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

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
657
0
644 950
22
Перейти к ответу Данный вопрос помечен как решенный

Ответы 22

Учти это:

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

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

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

MikeL 11.05.2013 15:37

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

V. Sambor 05.06.2016 16:19

Этот код не будет компилироваться, поскольку у вас нет конструктора по умолчанию в классе Product, а ваш TimesTwo имеет конструктор по умолчанию. Конструктор по умолчанию для TimesTwo вызовет конструктор по умолчанию класса Product с помощью super (), что приведет к ошибке компиляции.

Harshil 06.09.2017 15:12

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

Ответ принят как подходящий

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

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

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

NOTE: As there is no default (or no-arg) constructor in the parent abstract class, the constructor used in subclass must explicitly call the parent constructor.

@Jonathon: Никакой реальной пользы от добавления сложности для ответа на заданный вопрос не получится. Если бы вопрос был о масштабах, тогда, да, было бы разумно сопоставить три полезные возможности.

Michael Rutherfurd 21.06.2010 04:50

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

Hobo Spider 18.04.2014 01:10

Конструктор в TimesTwo не является конструктором по умолчанию.

Lew Bloch 03.09.2014 04:09

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

Vic Seedoubleyew 11.08.2016 17:24

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

Andy Royal 01.11.2017 18:13

Здесь новичок в Java. Если подкласс находится в другом пакете, чем абстрактный класс, тогда имеет смысл иметь общедоступный конструктор, не так ли? так что подкласс может вызывать super () ..

Uncaught Exception 09.01.2019 13:45

@UncaughtException, в этом случае защищенный конструктор будет иметь больше смысла, чем открытый конструктор.

Silwing 07.08.2019 16:04

@HoboSpider По моему опыту, конструкторы абстрактных классов имеют смысл для десериализации объектов, например, с использованием Джексона. Поскольку Джексону требуется пустой конструктор, код вне вашего контроля (или код, который вы не хотите изменять), у которого его нет, можно изменить с помощью абстрактного класса. Например, добавьте к любому классу пустой конструктор по умолчанию, используя «миксин», чтобы сделать ObjectMapper счастливым ObjectMapper.addMixIn(Concrete.class, MixinAbstract.class).

Jonathan Komar 19.11.2019 10:08

@MichaelRutherfurd Если мы не можем создать конструктор абстрактного класса, тогда в cusntructor подкласса, как его можно вызвать?

chirag soni 25.08.2020 15:54

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

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

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

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

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

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

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

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

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

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

antiplex 14.08.2013 16:10

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

Lew Bloch 03.09.2014 04:11

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

Вырезано и вставлено из geekinterview.com/question_details/77988. Плагиат - это не круто.

Cameron Skinner 28.08.2013 07:19

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

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

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

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

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

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

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

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

он не похож ни на один другой класс. Его нельзя создать, как любой другой класс.

Aslam Jiffry 06.07.2015 09:38

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

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

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

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:

It is a compile-time error if an attempt is made to create an instance of an abstract class using a class instance creation expression.

A subclass of an abstract class that is not itself abstract may be instantiated, resulting in the execution of a constructor for the abstract class and, therefore, the execution of the field initializers for instance variables of that class.

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

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

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

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

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

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

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

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

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

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

Да, у абстрактного класса всегда есть конструктор. Если вы не определите свой собственный конструктор, компилятор предоставит конструктор по умолчанию классу 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");
}
}

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

Optimus 07.12.2018 14:22

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

}

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

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

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

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

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

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

пакет 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;
    }

}

Другие вопросы по теме