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

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

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

+577
источник поделиться
22 ответа

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

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

+613
источник

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

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

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

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

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

+151
источник
другие ответы

Связанные вопросы


Похожие вопросы

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

+57
источник

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

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

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

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

+38
источник

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

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

+13
источник

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

+6
источник

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

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

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

+6
источник

Хотя есть много хороших ответов, я хотел бы дать свои 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");
}
}
+5
источник

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

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

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

+3
источник

Рассмотрим это:

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

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

+2
источник

Как описано 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
   }
}
+2
источник

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

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

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

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

+2
источник

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

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

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

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

+2
источник

да, это так. И конструктор абстрактного класса вызывается, когда создается экземпляр унаследованного класса. Например, следующая действительная 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();
    }

}

Это результат приведенного выше кода,

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

ссылки: введите ссылку здесь

+2
источник

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

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

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

+1
источник

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

+1
источник

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

+1
источник

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

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

+1
источник

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

0
источник

Назначение конструктора в классе используется для инициализации полей, но не для "создания объектов". Когда вы пытаетесь создать новый экземпляр абстрактного суперкласса, компилятор выдаст вам ошибку. Однако мы можем наследовать абстрактный класс 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;
 }
}
0
источник

пакет Test1;

открытый класс AbstractClassConstructor {

public AbstractClassConstructor() {

}

    public static void main(String args[]) {
       Demo obj = new Test("Test of code has started");
       obj.test1();
    }

}

abstract class Demo{
    protected final String demoValue;

    public Demo(String testName){
        this.demoValue = testName;
    }

    public abstract boolean test1();
}

class Test extends Demo{

    public Test(String name){
        super(name);
    }

    @Override
    public boolean test1() {
       System.out.println( this.demoValue + " Demo test started");
       return true;
    }

}
0
источник

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

-5
источник

Посмотрите другие вопросы по меткам или Задайте вопрос