Может ли абстрактный класс иметь конструктор? - PullRequest
557 голосов
/ 04 ноября 2008

Может ли абстрактный класс иметь конструктор?

Если да, то как его можно использовать и для каких целей?

Ответы [ 21 ]

599 голосов
/ 04 ноября 2008

Да, абстрактный класс может иметь конструктор. Учтите это:

abstract class Product { 
    int multiplyBy;
    public Product( int multiplyBy ) {
        this.multiplyBy = multiplyBy;
    }

    public int mutiply(int val) {
       return multiplyBy * val;
    }
}

class TimesTwo extends Product {
    public TimesTwo() {
        super(2);
    }
}

class TimesWhat extends Product {
    public TimesWhat(int what) {
        super(what);
    }
}

Суперкласс Product является абстрактным и имеет конструктор. Конкретный класс TimesTwo имеет конструктор, который просто жестко кодирует значение 2. Конкретный класс TimesWhat имеет конструктор, который позволяет вызывающей стороне указать значение.

Абстрактные конструкторы будут часто использоваться для обеспечения ограничений класса или инвариантов, таких как минимальные поля, необходимые для настройки класса.

ПРИМЕЧАНИЕ. Поскольку в родительском элементе нет конструктора по умолчанию (или без аргументов) абстрактный класс, конструктор, используемый в подклассе, должен явно вызывать родительский конструктор.

149 голосов
/ 04 ноября 2008

Вы бы определили конструктор в абстрактном классе, если находитесь в одной из следующих ситуаций:

  • вы хотите выполнить инициализация (для полей абстрактный класс) до создание подкласса на самом деле имеет место
  • вы определили последние поля в абстрактный класс, но вы не сделали инициализировать их в объявлении сам; в этом случае вы ДОЛЖНЫ иметь конструктор для инициализации этих поля

Обратите внимание, что:

  • вы можете определить более одного конструктор (с разными аргументы)
  • Вы можете (должны?) Определить все свои конструкторы защищены (делая их публика в любом случае бессмысленна)
  • ваш конструктор (ы) подкласса может вызвать один конструктор абстрактного учебный класс; может даже придется назвать это (если нет конструктора без аргументов в абстрактном классе)

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

55 голосов
/ 04 ноября 2008

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

34 голосов
/ 18 мая 2013

Да ! Абстрактные классы могут иметь конструкторы !

Да, когда мы определяем класс как абстрактный класс, он не может быть создан, но это не означает, что абстрактный класс не может иметь конструктор. Каждый абстрактный класс должен иметь конкретный подкласс, который будет реализовывать абстрактные методы этого абстрактного класса.

Когда мы создаем объект любого подкласса, все конструкторы в соответствующем дереве наследования вызываются в подходе сверху вниз. То же самое относится и к абстрактным классам. Хотя мы не можем создать объект абстрактного класса, когда мы создаем конкретный объект класса и подкласс абстрактного класса, конструктор абстрактного класса вызывается автоматически. Следовательно, у нас может быть конструктор в абстрактных классах.

Примечание: у неабстрактного класса не может быть абстрактных методов, но у абстрактного класса может быть неабстрактный метод. Причина аналогична конструкторам, с той разницей, что вместо автоматического вызова мы можем вызвать super (). Кроме того, нет ничего лучше абстрактного конструктора, поскольку он вообще не имеет смысла.

13 голосов
/ 12 сентября 2013

Мало того, что это может, это всегда так. Если вы не укажете один из них, то у него будет конструктор по умолчанию без аргументов, как и у любого другого класса. Фактически, ВСЕ классы, включая вложенные и анонимные классы, получат конструктор по умолчанию, если он не указан (в случае анонимных классов его невозможно указать, поэтому вы всегда получите конструктор по умолчанию).

Хорошим примером абстрактного класса, имеющего конструктор, является класс Calendar . Вы получаете объект Calendar, вызывая Calendar.getInstance (), но он также имеет конструкторы, которые защищены. Причина, по которой его конструкторы защищены, заключается в том, что их могут вызывать только его подклассы (или классы в одном и том же пакете, но, поскольку он абстрактный, это не применимо). GregorianCalendar является примером класса, расширяющего Calendar.

6 голосов
/ 21 июля 2013

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

6 голосов
/ 30 ноября 2015

Абстрактный класс может иметь конструктор, НО вы не можете создать объект абстрактного класса, так как вы используете этот конструктор?

Дело в том, что когда вы наследуете этот абстрактный класс в своем подклассе, вы можете передавать значения его (абстрактному) конструктору через метод super (value) в своем подклассе, и нет, вы не наследуете конструктор.

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

4 голосов
/ 06 сентября 2017

Хотя есть много хороших ответов, я хотел бы дать свои 2 цента.

Конструктор НЕ СОЗДАЕТ ОБЪЕКТ . Используется для инициализации объекта.

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

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

public abstract class Abs{
    int i;
    int j;
    public Abs(int i,int j){
        this.i = i;
        this.j = j;
        System.out.println(i+" "+j);
    }
}

Будьте осторожны при расширении выше абстрактного класса, вы должны явно вызывать super из каждого конструктора. Первая строка любого конструктора вызывает super (). если вы явно не вызовете super (), Java сделает это за вас. Ниже код не скомпилируется:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    System.out.println("2 arg");
}
}

Вы должны использовать его, как показано ниже:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    super(i,j);
    System.out.println("2 arg");
}
}
3 голосов
/ 20 мая 2016

Конечно, у абстрактного класса может быть конструктор. Обычно конструктор класса используется для инициализации полей. Так, конструктор абстрактного класса используется для инициализации полей абстрактного класса. Вы бы предоставили конструктор для абстрактного класса, если хотите инициализировать определенные поля абстрактного класса до того, как будет создан экземпляр дочернего класса. Абстрактный конструктор класса также может использоваться для выполнения кода, который важен для каждого дочернего класса. Это предотвращает дублирование кода.

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

Ссылка: Эта статья

2 голосов
/ 16 сентября 2017

да, это так. И конструктор абстрактного класса вызывается при создании экземпляра унаследованного класса. Например, следующее является допустимой программой Java.

// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
    }
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
    }

class Main {
public static void main(String args[]) { 
   Derived d = new Derived();
    }

}

Это вывод вышеуказанного кода,

Вызывается базовый конструктор Производный конструктор под названием

ссылка: введите описание ссылки здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...