Может ли абстрактный класс иметь конструктор?
Может ли абстрактный класс иметь конструктор?
Если да, то как это можно использовать и для каких целей?
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
имеет конструктор, который позволяет вызывающей стороне указывать значение.
Абстрактные конструкторы будут часто использоваться для обеспечения ограничений класса или инвариантов, таких как минимальные поля, необходимые для настройки класса.
ПРИМЕЧАНИЕ. Поскольку в родительском абстрактном классе нет конструктора по умолчанию (или без аргументов), конструктор, используемый в подклассе, должен явно вызывать родительский конструктор.
Вы бы определили конструктор в абстрактном классе, если находитесь в одной из следующих ситуаций:
- вы хотите выполнить некоторую инициализацию (для полей абстрактного класса) до того, как фактически произойдет создание экземпляра подкласса
- вы определили конечные поля в абстрактном классе, но не инициализировали их в самом объявлении; в этом случае вы ДОЛЖНЫ иметь конструктор для инициализации этих полей
Обратите внимание, что:
- вы можете определить более одного конструктора (с разными аргументами)
- Вы можете (должны?) определить все ваши защищенные конструкторы (в любом случае делать их публичными бессмысленно)
- ваш конструктор (ы) подкласса может вызывать один конструктор абстрактного класса; он может даже вызывать его (если в абстрактном классе нет конструктора без аргументов)
В любом случае, не забывайте, что если вы не определили конструктор, компилятор автоматически сгенерирует его для вас (этот является открытым, не имеет аргументов и ничего не делает).
Да, он может иметь конструктор, и он определен и ведет себя так же, как конструктор любого другого класса. За исключением того, что абстрактные классы не могут быть непосредственно созданы, только расширены, поэтому использование всегда происходит из конструктора подкласса.
Да! Абстрактные классы могут иметь конструкторы!
Да, когда мы определяем класс как абстрактный класс, он не может быть создан, но это не означает, что абстрактный класс не может иметь конструктор. Каждый абстрактный класс должен иметь конкретный подкласс, который будет реализовывать абстрактные методы этого абстрактного класса.
Когда мы создаем объект любого подкласса, все конструкторы в соответствующем дереве наследования вызываются в подходе сверху вниз. То же самое относится и к абстрактным классам. Хотя мы не можем создать объект абстрактного класса, когда мы создаем конкретный объект класса и подкласс абстрактного класса, конструктор абстрактного класса вызывается автоматически. Следовательно, мы можем иметь конструктор в абстрактных классах.
Примечание: неабстрактный класс не может иметь абстрактных методов, но абстрактный класс может иметь неабстрактный метод. Причина аналогична конструкторам, с той разницей, что вместо автоматического вызова мы можем вызвать super(). Кроме того, нет ничего лучше абстрактного конструктора, поскольку он не имеет никакого смысла.
Это не только так, но и всегда. Если вы не укажете один из них, то у него будет конструктор по умолчанию без аргументов, как и у любого другого класса. Фактически, ВСЕ классы, включая вложенные и анонимные классы, получат конструктор по умолчанию, если он не указан (в случае анонимных классов его невозможно указать, поэтому вы всегда получите конструктор по умолчанию).
Хорошим примером абстрактного класса, имеющего конструктор, является класс Calendar. Вы получаете объект Calendar, вызывая Calendar.getInstance(), но он также имеет конструкторы, которые защищены. Причина, по которой его конструкторы защищены, заключается в том, что их могут вызывать только его подклассы (или классы в одном и том же пакете, но, поскольку он абстрактный, это не применимо). GregorianCalendar - это пример класса, расширяющего Calendar.
Хотя есть много хороших ответов, я хотел бы дать свои 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");
}
}
Абстрактный класс может иметь конструктор, НО вы не можете создать объект абстрактного класса, так как вы используете этот конструктор?
Дело в том, что когда вы наследуете этот абстрактный класс в своем подклассе, вы можете передавать значения в его (абстрактный) конструктор через метод super(value) в своем подклассе, и нет, вы не наследуете конструктор.
поэтому, используя super, вы можете передавать значения в конструктор абстрактного класса, и, насколько я помню, это должен быть первый оператор в вашем методе или конструкторе.
Конечно, абстрактный класс может иметь конструктор. Обычно конструктор класса используется для инициализации полей. Итак, конструктор абстрактного класса используется для инициализации полей абстрактного класса. Вы бы предоставили конструктор для абстрактного класса, если хотите инициализировать определенные поля абстрактного класса до того, как будет создан экземпляр дочернего класса. Абстрактный конструктор класса также можно использовать для выполнения кода, который важен для каждого дочернего класса. Это предотвращает дублирование кода.
Мы не можем создать экземпляр абстрактного класса, но мы можем создать экземпляры классов, которые являются производными от абстрактного класса. Таким образом, когда создается экземпляр производного класса, автоматически вызывается родительский конструктор абстрактного класса.
Ссылка: эта статья
Да, может, конструкторы абстрактных классов обычно используются для супер-вызовов для событий инициализации, общих для всех подклассов.
Да, у абстрактных классов могут быть конструкторы!
Вот пример использования конструктора в абстрактном классе:
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());
}
}
Так что я думаю, что вы получили ответ.
В конкретном классе объявление конструктора для конкретного типа 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
}
}
Абстрактный класс может иметь конструктор, хотя он не может быть создан. Но конструктор, определенный в абстрактном классе, можно использовать для создания экземпляров конкретного класса этого абстрактного класса. Проверьте JLS:
Это ошибка времени компиляции, если предпринята попытка создать экземпляр абстрактного класса с помощью выражения создания экземпляра класса.
Может быть создан экземпляр подкласса абстрактного класса, который сам не является абстрактным, что приводит к выполнению конструктора для абстрактного класса и, следовательно, к выполнению инициализаторов поля для переменных экземпляра этого класса.
Да, это. И конструктор абстрактного класса вызывается при создании экземпляра унаследованного класса. Например, следующее является допустимой программой 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();
}
}
Это вывод приведенного выше кода,
Основной конструктор называется Производный конструктор называется
ссылки: введите описание ссылки здесь
Учти это:
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;
}
}
Суперкласс является абстрактным и имеет конструктор.
Да, абстрактный класс может иметь конструктор. Вы можете перегружать столько конструкторов, сколько хотите в абстрактном классе. Эти подрядчики могут использоваться для инициализации начального состояния объектов, расширяющих абстрактный класс. Как мы знаем, мы не можем сделать объект абстрактного класса, потому что объекты создаются "новыми" ключевыми словами, а не конструкторами... они существуют только для инициализации состояния объектов подкласса.
Да, конечно, вы можете добавить один, как уже упоминалось для инициализации переменных класса Abstract. НО, если вы явно не объявляете его, в любом случае у него есть неявный конструктор для работы "Цепочки конструктора".
Для достижения цепочки конструктора абстрактный класс будет иметь конструктор. Компилятор хранит оператор 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;
}
}
Пакет 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;
}
}
Да.. Это как любой другой класс. Он может иметь конструктор и вызывается после создания объекта для базового класса.