views:

1192

answers:

6

Why do we need constructors and private members in the abstract class? It is not like we are ever going to create an instance of that class.

+9  A: 

You will create instances, just instances of a derived class. Those derived classes will still need to call constructors, and can still call members of the abstract class - which may in turn use private members.

Here's an example (not a terribly useful one, but just to show the basic idea...)

public abstract class NamedObject
{
    private final String name = name;

    protected NamedObject(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }
}

public class Computer extends NamedObject
{
    private final int processorSpeed;

    public Computer(String name, int processorSpeed)
    {
        super(name); // See, the constructor is useful
        this.processorSpeed = processorSpeed;
    }

    public String toString()
    {
        return getName() + " (" + processorSpeed + ")";
    }
}

I can't say I write abstract classes that often, generally preferring composition to inheritance, but when I do create them I certainly use constructors and private members.

Jon Skeet
+3  A: 

Abstract classes provide a partial implementation of some interface. It's perfectly reasonable to consider that you might want to provide part of that implementation and disallow client code (concrete subclasses) from accessing the specifics - i.e. an extension of the principle of encapsulation.

Marking some members as private forces the inheriting class to call protected methods to access that partial implementation; providing a constructor allows for subclasses to initialise the parent's encapsulated state during their own construction.

Rob
+1  A: 

Unlike an interface, an abstract class that defines data fields is in fact instantiated in the sense that these data fields are allocated. It is just that they are never instantiated on their own, they are instantiated as part of something bigger - the subclass. So when the subclass is built, the supertype is built as well, which is why you would need a constructor.

Depending on your hierarchy, your abstract class may have a meaning and state. For example, if your application is a school you may have the notion of a person (that has a name and an SSN), but you would have different subtypes for students and for faculty. Because both types of people share certain state structure (name and SSN) you would have both classes extend the Person class. But you would never simply instantiate a person directly.

Uri
A: 

In addition to Jon's answer, I'd like to mention that abstract classes still go well with composition, if you keep the subclass tree shallow. I.e. it is great for providing a common base class for a few closely related objects, but not for creating a gigantic tree of subclasses.

Thorbjørn Ravn Andersen
A: 

Why do you need private class? I think that you are confusing abstract classes with interfaces. Unlike interfaces, abstract classes can hold functionality. For example:

public class AbstractBase{
    private int num;

    public AbstractBase(int number){
       this->num = number;
    }

    public int method(){
       return ( this->num * this->templateMethod());
    }

    public abstract int templateMethod();
 }

public class ConcreteDerived extends AbstractBase{

public ConcreteDerived(){
  super(4);
}

public int templateMethod(){
   return number; //number is the result of some calculation
}

}

In this example, you´ll never explicitly instantiate AbstractBase, but by declaring members and constructors, you can customize the functionality of your classes (this is called template method).

Tom
A: 

Assuming you're doing ad hoc code or prototyping, you do instantiate abstract classes (or maybe even interfaces) from time to time. They're called anonymous inner classes (one, two) and look like this:

// you have this...
public abstract class SomeClass {
    public abstract String returnAString();
}

// ...and this...
public class OtherClass {
    public void operate(SomeClass c) {
     System.out.println(c.returnAString());
    }
}

// ...so you do this:    
OtherClass oc = new OtherClass();
// this is one of the reasons why you need to specify a constructor
oc.operate(new SomeClass() {
    @Override
    public String returnAString() {
     return "I'm an anonymous inner class!";
    }
});

This example is of course quite redundant but should expose the point. Some existing frameworks even rely on the heavy usage of this behaviour, namely Apache Wicket at least.

Esko