Зачем нам нужны конструкторы и закрытые члены в абстрактном классе? - PullRequest
2 голосов
/ 04 мая 2009

Зачем нам нужны конструкторы и закрытые члены в абстрактном классе? Мы не собираемся создавать экземпляр этого класса.

Ответы [ 6 ]

14 голосов
/ 04 мая 2009

Вы создадите экземпляры, просто экземпляры производного класса. Эти производные классы по-прежнему должны вызывать конструкторы и могут вызывать члены абстрактного класса, которые, в свою очередь, могут использовать закрытые члены.

Вот пример (не очень полезный, но просто чтобы показать основную идею ...)

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 + ")";
    }
}

Не могу сказать, что я пишу абстрактные классы , которые часто, обычно предпочитая композиции наследованию, но когда я делаю , я, конечно, использую конструкторы и закрытые члены.

3 голосов
/ 04 мая 2009

Абстрактные классы обеспечивают частичную реализацию некоторого интерфейса. Вполне разумно предположить, что вы можете захотеть предоставить часть этой реализации и запретить клиентскому коду (конкретным подклассам) доступ к специфике, т. Е. Расширению принципа инкапсуляции.

Пометка некоторых членов как приватных заставляет наследующий класс вызывать защищенные методы для доступа к этой частичной реализации; Предоставление конструктора позволяет подклассам инициализировать инкапсулированное состояние родителя во время их собственной конструкции.

1 голос
/ 04 мая 2009

В отличие от интерфейса, абстрактный класс, который определяет поля данных, фактически создается в том смысле, что эти поля данных выделяются. Просто они никогда не создаются сами по себе, они создаются как часть чего-то большего - подкласса. Поэтому, когда создается подкласс, также создается супертип, поэтому вам понадобится конструктор.

В зависимости от вашей иерархии, ваш абстрактный класс может иметь значение и состояние. Например, если ваше заявление является школой, вы можете иметь представление о человеке (у которого есть имя и SSN), но у вас будут разные подтипы для студентов и преподавателей. Поскольку оба типа людей имеют определенную государственную структуру (имя и SSN), оба класса будут расширять класс Person. Но вы бы никогда не просто создали экземпляр человека напрямую.

0 голосов
/ 04 мая 2009

Предполагая, что вы делаете специальный код или создаете прототипы, вы время от времени создаете экземпляры абстрактных классов (или, возможно, даже интерфейсов). Они называются анонимными внутренними классами ( один , два ) и выглядят так:

// 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!";
    }
});

Этот пример, конечно, довольно избыточен, но должен раскрыть суть. Некоторые существующие фреймворки даже полагаются на интенсивное использование этого поведения, а именно Apache Wicket * по крайней мере 1009 *.

0 голосов
/ 04 мая 2009

Зачем вам нужен частный класс? Я думаю, что вы путаете абстрактные классы с интерфейсами. В отличие от интерфейсов, абстрактные классы могут содержать функциональность. Например:

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();
 }

открытый класс ConcreteDerived extends AbstractBase {

public ConcreteDerived(){
  super(4);
}

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

}

В этом примере вы никогда не будете явно создавать экземпляр AbstractBase, но, объявляя члены и конструкторы, вы можете настроить функциональность ваших классов (это называется шаблонным методом).

0 голосов
/ 04 мая 2009

В дополнение к ответу Джона я хотел бы упомянуть, что абстрактные классы по-прежнему хорошо сочетаются с композицией, если дерево подклассов остается мелким. То есть он отлично подходит для предоставления общего базового класса для нескольких тесно связанных объектов, но не для создания гигантского дерева подклассов.

...