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

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

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

21 ответов


да, абстрактный класс может иметь конструктор. Рассматривайте это:

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 имеет конструктор, который позволяет звонящему указать значение.

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

Примечание: поскольку в Родительском конструкторе нет конструктора по умолчанию (или no-arg абстрактный класс, конструктор, используемый в подклассе, должен явно вызывать родительский конструктор.


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

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

Примечание. что:

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

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


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


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

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

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

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


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

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


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


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

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

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


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

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

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

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

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

рассмотрим следующий пример:

abstract class Product { 
    int value;
    public Product( int val ) {
        value= val;
    }
    abstract public int multiply();
}

class TimesTwo extends Product {
    public int mutiply() {
       return value * 2;
    }
}

суперкласс является абстрактным и имеет конструктор.


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

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

ссылки :В Этой Статье


в конкретном классе объявление конструктора для конкретного типа Fnord эффективно предоставляет две вещи:

  • средство, с помощью которого код может запросить создание экземпляра Fnord

  • средство, с помощью которого экземпляр типа, производного от Fnord который находится в стадии разработки, может запросить инициализацию всех функций базового класса.

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


как описано javafuns здесь, например:

public abstract class TestEngine
{
   private String engineId;
   private String engineName;

   public TestEngine(String engineId , String engineName)
   {
     this.engineId = engineId;
     this.engineName = engineName;
   }
   //public gettors and settors
   public abstract void scheduleTest();
}


public class JavaTestEngine extends TestEngine
{

   private String typeName;

   public JavaTestEngine(String engineId , String engineName , String typeName)
   {
      super(engineId , engineName);
      this.typeName = typeName;
   }

   public void scheduleTest()
   {
     //do Stuff
   }
}

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

вот пример использования конструктора в абстрактном классе:

abstract class Figure { 

    double dim1;        
    double dim2; 

    Figure(double a, double b) {         
        dim1 = a;         
        dim2 = b;         
    }

    // area is now an abstract method 

   abstract double area(); 

}


class Rectangle extends Figure { 
    Rectangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for rectangle 
    double area() { 
        System.out.println("Inside Area for Rectangle."); 
        return dim1 * dim2; 
    } 
}

class Triangle extends Figure { 
    Triangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for right triangle 
    double area() { 
        System.out.println("Inside Area for Triangle."); 
        return dim1 * dim2 / 2; 
    } 
}

class AbstractAreas { 
    public static void main(String args[]) { 
        // Figure f = new Figure(10, 10); // illegal now 
        Rectangle r = new Rectangle(9, 5); 
        Triangle t = new Triangle(10, 8); 
        Figure figref; // this is OK, no object is created 
        figref = r; 
        System.out.println("Area is " + figref.area()); 
        figref = t; 
        System.out.println("Area is " + figref.area()); 
    } 
}

Итак, я думаю, вы получили ответ.


абстрактный класс может иметь конструктор, хотя он не может быть инстанцирован. Но конструктор, определенный в абстрактном классе, может использоваться для создания экземпляра конкретного класса этого абстрактного класса. Проверка JLS:

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

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


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

напротив, an интерфейс содержит только постоянные переменные, что означает, что они уже инициализированы. Поэтому интерфейс не нуждается в конструкторе.


для достижения цепочки конструкторов абстрактный класс будет иметь конструктор. Компилятор сохраняет оператор Super () внутри конструктора подкласса, который будет вызывать конструктор суперкласса. Если для абстрактных классов не было конструкторов, то правила java нарушаются, и мы не можем достичь цепочки конструкторов.


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


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


назначение конструктора в классе используется для инициализировать поля но не "создавать объекты". При попытке создать новый экземпляр абстрактного суперкласса, компилятор даст вам ошибку. Однако мы можем наследовать абстрактный класс Employee и использовать его конструктор, установив его переменные см. пример ниже

public abstract class Employee {
  private String EmpName;
  abstract double calcSalary();

  Employee(String name) {
    this.EmpName = name;// constructor of abstract class super class
  }
}

class Manager extends Employee{
 Manager(String name) {
    super(name);// setting the name in the constructor of sub class
 }
double calcSalary() {
    return 0;
 }
}

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