11 Replies - 2656 Views - Last Post: 14 April 2010 - 05:50 PM Rate Topic: -----

#1 Codebug  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 244
  • Joined: 11-October 09

abstract method question

Posted 14 April 2010 - 03:03 PM

I've recently been introduced to inheritance, polymorphism, abstract, etc and I have a question. Why is the abstract method needed at all in an implementation? I understand having a base class that more specialized subclasses can inherit from. I just don't see the point of having an abstract method in the base class. Since the abstract method is just referring to individual methods in each subclass, why can't you just call those individual methods own their from the subclasses instead?

Thanks

Is This A Good Question/Topic? 0
  • +

Replies To: abstract method question

#2 erik.price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 485
  • View blog
  • Posts: 2,690
  • Joined: 18-December 08

Re: abstract method question

Posted 14 April 2010 - 03:15 PM

It's like using an interface, in that it guarantees that all all derived classes will need to implement the methods, except it allows you to fill in some methods which will be the same for all of the child classes. (saving you some work)

Say you have an abstract class, Mammal:
public abstract class Mammal {
   public void live(){
     //do stuff to not die
   }
   public void move();
   public void eat();
}


All Mammals live, and they all do the same things in the live method (well, maybe not, but pretend!), however, each Mammal will move around and eat differently (but they all do it), therefore, you make sure that each Mammal implements the abstract methods, and you don't need to duplicate the live method in every subclass
Was This Post Helpful? 2
  • +
  • -

#3 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10438
  • View blog
  • Posts: 38,651
  • Joined: 27-December 08

Re: abstract method question

Posted 14 April 2010 - 03:33 PM

The two key things with abstract methods are dynamic binding and interfacing. Dynamic binding comes into play more with abstract classes than interfaces, though you see it with both. Basically, it means that if you have a pointer of the Abstract class or interface type, the abstract method used will be determined at runtime based on the type of the object in memory. So for example, given that you have a GeometricObject abstract super class with the abstract method getArea(), and subclasses Circle, Rectangle, and Triangle. If you have an array of GeometricObjects, length 3, with an instance of each of these subclasses, when you iterate through and invoke the getArea() method, at runtime, the JVM will determine which getArea() method is appropriate based on Object type in memory. So maybe a little long-winded explanation for a simple concept- it forces the subclasses to implement the abstract method, allowing you to invoke the functionality (method) safely, as it must be implemented.

This brings us into interfacing. For this concept, I'll use the List interface as my example. If you look in the API, you will see that List has a ton of methods like add(), remove(), get(), and set(). Since List is an interface, all of the methods are abstract. However, note that List is also a datatype of the implementing class. So ArrayList is also a List. This comes into play with dynamic binding, as implementing classes must either implement the methods or be declared abstract. So by implementing an interface, we are forcing this functionality upon a class. This is useful for instances like when we invoke Collections.sort(List<E>). It doesn't matter if the List is an ArrayList, Vector, Stack, LinkedList, RoleList, etc., they will all be treated the same way as they all implement the same methods from List, so sort() will invoke those methods as they are designed to be implemented for the purpose of sorting the List param.
Was This Post Helpful? 1
  • +
  • -

#4 Codebug  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 244
  • Joined: 11-October 09

Re: abstract method question

Posted 14 April 2010 - 03:44 PM

I'm still having some difficulty understanding why the abstract method is needed. If I understand erik.price correctly, all the abstract method does is save work. But this still doesn't make sense. It seems like you have two methods that do the same thing(abstract method and subclass method). Why not just go directly to the subclass and call the same method that the abstract method is referencing?
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5795
  • View blog
  • Posts: 12,628
  • Joined: 16-October 07

Re: abstract method question

Posted 14 April 2010 - 04:07 PM

View PostCodebug, on 14 April 2010 - 04:44 PM, said:

Why not just go directly to the subclass and call the same method that the abstract method is referencing?


I'm blanking on a brilliant example, but I'll take a stab.

abstract class WidgetBase {
	// some abstract methods
	public abstract string getName();
	public abstract boolean process(Object [] args);
	
	// a default method call, implemented
	public boolean process() { return process(null); }
	
	public String toString() { return getName(); }
}



Notice that there are abstract methods, but also concrete methods. The concrete methods, in a sense, are the reason for an abstract class. You can write code that leverages methods that don't exist yet, but will be. If you didn't have any code you wanted to implement, you'd just make an interface.

interface IWidgetBase {
	string getName();
	boolean process(Object [] args);
	boolean process();
	String toString();
}



With an interface I have to write everything.

Indeed, abstract classes are often uses to partially implement an interface, providing the code that can be implemented in an generalized way. Much of the JDK implements this kind of pattern. e.g http://java.sun.com/...stractList.html
Was This Post Helpful? 2
  • +
  • -

#6 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10438
  • View blog
  • Posts: 38,651
  • Joined: 27-December 08

Re: abstract method question

Posted 14 April 2010 - 04:10 PM

Not exactly. The abstract method says "here is a method that returns blank." It is then the responsibility of the implementing class to define how the method functions. So if you have getArea() abstract method in abstract GeometricObject class, you are saying that all subclasses of GeometricObject will define how to get area for their instances. So some subclasses of GeometricObject would be Circle, Rectangle, and Triangle. Each of these shapes has a different area formula, so therefore defines getArea() differently.

Then if you have a collection of GeometricObjects, like an array or a List, and you invoke getArea() from the GeometricObject pointer, the appropriate getArea() method will be invoked based on the Object in memory. So for example:
GemoetricObject circle = new Circle();
GeometricObject rect = new Rectangle();
GeometricObject triangle = new Triangle();



Now for each of these three objects, when I invoke getArea(), the result will be different based on the instance of the subclass the pointer is referencing. However, if I did not abstractly define getArea() in GeometricObject, then I couldn't invoke getArea() from the pointers, even though each of the subclasses may define getArea().

@baavgai: I think you mistyped string for the getName() methods. :)

This post has been edited by macosxnerd101: 14 April 2010 - 04:12 PM

Was This Post Helpful? 1
  • +
  • -

#7 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,025
  • Joined: 15-July 08

Re: abstract method question

Posted 14 April 2010 - 04:39 PM

Well, you can also look at it with objects that maybe explain a little bit better. Let's say that there is a generic BankAccount type and 2 subclasses, say CheckingAccount and SavingsAccount. Now, you cannot just have a BankAccount because it does not have limits on how much you can withdraw, deposit, and that sort of thing, but we implement as much as we can, and why, I'll explain in a minute.

public abstract class BankAccount {

    // Make these for the subclass's purpose only.
    protected double balance;
    protected int bankNum;

    // Constructor
    public BankAccount(double money, int num) {
        balance = money;
        bankNum = num;
    }
    
    // No limit on deposit, so we'll implement it here
    public void deposit(int double) {
        balance += amount;
    }
 
    // However, there are different ways to withdraw:
    // fees and such...why we do this - I'll explain in a minute.
    public double withdraw(double amount);

    // Other methods can be put here.
    public int getBalance() {
        return balance;
    }

    public void getBankNumber() {
        return bankNum;
    }
}



Now, for each of the concrete (non-abstract) subclasses, you must implement that missing method. Additionally, you may add methods, variables...that sort of thing.

public class SavingsAccount extends BankAccount {
    
    // Use our constructor.
    public SavingsAccount(double money, int number) {
        super(money, number);
    }

    // Since this is just a basic Bank Account, the only thing we will add  
    // is the unimplemented method.
    public double withdraw(double amount) {
        if (amount < 200 && amount > 0) {
            balance -= amount;
            return amount;
        }
        else {
            // Invalid number
            return -1;
        }
    }
}



Very simple right? Well, CheckingAccount has different restrictions on the withdraw.
public class CheckingAccount extends BankAccount {

    double taxFee;
    
    // Use our constructor.
    public CheckingAccount(double money, int number, double fee) {
        super(money, number);
        taxFee = fee;
    }

    // Subtract a fee for every check too.
    public double withdraw(double amount) {
        if (amount < 10000 && amount > 0) {
            balance -= amount;
            balance -= (amount*calcFee());
            return amount;
        }
        else {
            // Invalid number
            return -1;
        }
    }

    public double calcFee() {
        return taxFee/100;
    }
}



In that one, I added the method and another variable and method. Now, you are still asking, what is the purpose of that? Well, what if you wanted to make a SINGLE array of all the bank accounts. Without the abstract class BankAccount, there'd be no way to group them together. However, one may only call methods that exist in BankAccount (so one couldn't call calcFee). Now that you have this in you mind, let me show you an example:

public static void main(String[] args) {
    // Make our array of bank accounts
    BankAccount[] accts = new BankAccount[4];
    
    // Now, whatever type they are...add them
    accts[0] = new SavingsAccount(100, 8923901);
    accts[1] = new SavingsAccount(20000, 2389112);
    accts[2] = new CheckingAccount(3000, 1234232, 89.9);
    accts[3] = new CheckingAccount(100000, 2896723, 1000.0);

    // Now, we can only call deposit(), withdraw(), getBalance(),
    // or getBankNumber() on any of those...
    for (BankAccount ba : accts) {
        System.out.println("You withdrew $" + ba.withdrawl(30));
    }
  
    // Note, you cant call calcFee of CheckingAccount unless you 
    // explicitly cast it.
    for (BankAccount ba : accts) {
        System.out.println("You withdrew $" + ba.withdrawl(30));
        if (ba instanceof CheckingAccount) {
            System.out.println("Fee is $" + ((CheckingAccount)ba).calcFee());    
        }
    }
}



See? That's the idea of Collections that you see throughout the Java language.

Hope I cleared that up

:D
Was This Post Helpful? 1
  • +
  • -

#8 zim1985  Icon User is offline

  • Grand Inquisitor
  • member icon

Reputation: 74
  • View blog
  • Posts: 568
  • Joined: 19-February 10

Re: abstract method question

Posted 14 April 2010 - 04:44 PM

The way I learned it was that an Interface is purely so you make sure that all classes the implement the interface will be forced to implement the methods in some way, shape, or form. For example:
public interface Shape
{
    public double perimeter();
    public double area();
    public String toString();
}


You see now that any class that implements Shape will have to implement these methods in some way.
So...
public class Square implements Shape
{
    double sideLength;

    public Square(double side)
    {
        sideLength = side;
    }

    public double perimeter()
    {
        return 4* sideLength;
    }

    public double area()
    {
        return sideLength* sideLength;
    }

    public String toString()
    {
        return "\nPerimeter: " + perimeter() + "\nArea: " + area();
    }
}


public class Rectangle implements Shape
{
    double length;
    double width;

    public Rectangle(double len, double wid)
    {
        length = len;
        width = wid;
    }

    public double perimeter()
    {
        return 2*(length + width);
    }

    public double area()
    {
        return length*width;
    }

    public String toString()
    {
        return "\nPerimeter: " + perimeter() + "\nArea: " + area();
    }
}



Now notice how both of these classes implement toString() exactly the same. This could be remedied with an Abstract Class. An Abstract Class works much the same as an Interface. It can declare methods just like an Interface, forcing any class that extends it to implement those methods, but it also works like a regular class in that you can implement a method in the Abstract Class to be inherited by a subclass, thus eliminating repetitive code such as the toString() methods we saw.

Now for the same problem using an Abstract Class:

public abstract class ShapeAC
{
    public abstract double perimeter();
    public abstract double area();
    public String toString()
    {
        return "\nPerimeter: " + perimeter() + "\nArea: " + area();
    }
}


You see now that any class that extends Shape will have to implement these methods in some way, but will inherit the toString() method. One change it the "abstract" modifier that you need to place before all unimplemented methods.
So...
public class SquareAC extends ShapeAC
{
    double sideLength;

    public SquareAC(double side)
    {
        sideLength = side;
    }

    public double perimeter()
    {
        return 4*sideLength;
    }

    public double area()
    {
        return sideLength*sideLength;
    }
}


public class RectangleAC extends ShapeAC
{
    double length;
    double width;

    public RectangleAC(double len, double wid)
    {
        length = len;
        width = wid;
    }

    public double perimeter()
    {
        return 2*(length + width);
    }

    public double area()
    {
        return length*width;
    }
}



I think I got this example right. I ran the code and it all runs fine.

Granted this isn't the most complicated example, but I think it get's the points of Interfaces and Abstract Classes across...hope this is helpful. I also attached my work...

Attached File(s)


This post has been edited by zim1985: 14 April 2010 - 04:52 PM

Was This Post Helpful? 2
  • +
  • -

#9 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,025
  • Joined: 15-July 08

Re: abstract method question

Posted 14 April 2010 - 04:54 PM

Nice example zim! I think he wants to know why to use them, not what they do, but I'll give you a check for that. Wow, you were smart and typed it in a project...I just typed it right into the browser window.
Was This Post Helpful? 1
  • +
  • -

#10 zim1985  Icon User is offline

  • Grand Inquisitor
  • member icon

Reputation: 74
  • View blog
  • Posts: 568
  • Joined: 19-February 10

Re: abstract method question

Posted 14 April 2010 - 05:00 PM

View PostDogstopper, on 14 April 2010 - 02:54 PM, said:

Nice example zim! I think he wants to know why to use them, not what they do, but I'll give you a check for that. Wow, you were smart and typed it in a project...I just typed it right into the browser window.

I actually typed into the Browser, and then moved it to a project so I could test it.
Was This Post Helpful? 0
  • +
  • -

#11 zim1985  Icon User is offline

  • Grand Inquisitor
  • member icon

Reputation: 74
  • View blog
  • Posts: 568
  • Joined: 19-February 10

Re: abstract method question

Posted 14 April 2010 - 05:35 PM

On that note, this site was helpful in my understanding of when to use them: http://codeofdoom.co...d-an-interface/

What it boils down to is that because Interfaces can only define functions, they only say what something can do. For instance, say you have a class Car which implements Vehicle. Sure, this seems logical, the car are vehicles, so they function as vehicles, but because you can implement multiple interfaces, you could also implement Recyclable or some other obscure, unrelated Interface which defines functions that are unrelated to your Car.

Now because an Abstract Class can fully qualify methods and then provide methods that define functions they act as more of a definition for your class. Now take this example: you have an Abstract Class Dog. Your class German_Shepard extends Dog, enforcing that it is a Dog, not just something that can act like a dog as an interface would imply. You have to keep in mind that this is also because, like any other class, you can only extend one class per class.

For example:
// Doesn't work
public class German_Shepard extends Dog, Mammal

//Works
public class German_Shepard extends Dog implements Mammal, Pet



But there are also other things to keep in mind when choosing to use an Interface or Abstract Class and when choosing between the two. This site is also useful: http://mindprod.com/...vsabstract.html

In terms of choosing between the two, when you want to set up a "contract" with classes on what they absolutely must have in them, you would use an interface. Likewise, when you want to provide some ground work for the subclasses to start off with, while still forcing some kind of abstract implementation of other methods, you would use an Abstract class. (Like with shapes, you want your toString() to be the same, but you need each shape to implement perimeter and area differently).

Why should you use an interface? It helps to group classes together. The List interface is a good example of this...so here we go. The List interface defines a whole bunch of methods for implementing classes to use. Classes such as ArrayList, LinkedList, and many others. Now look at this:
ArrayList<Object> aL = new ArrayList<Object>();
// same as
List<Object> list = new ArrayList<Object>();


Why? Because ArrayList implements List, you can actually declare the List and define is as an ArrayList. Going back to my previous example we could do this:
Square sq = new Square(4);
// same as
Shape sh = new Square(4);



Now for a more practical example. Let say you have this:
public class Person extends Human implements Alive

Person instanceof Human // return true
Person instanceof Alive // return true



Because Person extends Human, it is a subclass and therefore is directly related and an instance of the Human class. Because Person implement Alive, it falls under the "functional umbrella" that is defined by Alive, and it therefore an instance of Alive. Basically, by implementing and extending Interfaces and Classes respectively, you group things together and put them all in one "family" if you will so that you can manipulate them, mainly because they are all innately similar.

I think I got most of that right, though don't refrain from correcting me if I didn't.

This post has been edited by zim1985: 14 April 2010 - 05:37 PM

Was This Post Helpful? 1
  • +
  • -

#12 Dogstopper  Icon User is offline

  • The Ninjaducky
  • member icon



Reputation: 2870
  • View blog
  • Posts: 11,025
  • Joined: 15-July 08

Re: abstract method question

Posted 14 April 2010 - 05:50 PM

Also, when you have a HUGE amount of methods (like the List interface) that MUST be implemented, obviously, one would not want to implement those methods for EVERY class that implements that array, there's just way too many to be practical. That's where an abstract class helps. An abstract class will attempt to implement as many of those methods as it can and still have all the subclasses be correct. However, quite obviously, there are still SOME methods that cannot be implemented on that abstract a level, so those must be implemented by the concrete class that extends it.

So instead of implementing literally dozens of methods in EACH class that implements List, you make a single entity that takes care of most, and then the code that you have have to write is minimized. The code you have to implement boils down to the methods that just couldn't be defined at the abstract level and those that are overwritten.

This concept is extremely useful and saves LOADS of time (and handache) both when making your own List object and when considering making your own interface. So basically, with abstract classes, you have the capability of abstraction (as Zim and I have shown) and the convenience of having a lot of the work done for you.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1