programing

추상 클래스가 생성자를 가질 수 있습니까?

nasanasas 2020. 10. 3. 10:54
반응형

추상 클래스가 생성자를 가질 수 있습니까?


추상 클래스가 생성자를 가질 수 있습니까?

그렇다면 어떻게 사용할 수 있으며 어떤 용도로 사용할 수 있습니까?


예, 추상 클래스는 생성자를 가질 수 있습니다. 이걸 고려하세요:

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 ()를 호출 할 수 있다는 차이점이 있습니다. 또한 전혀 의미가 없으므로 추상 생성자와 같은 것은 없습니다.


할 수있을뿐만 아니라 항상 그렇습니다. 하나를 지정하지 않으면 다른 클래스와 마찬가지로 기본 no arg 생성자가 있습니다. 실제로 중첩 및 익명 클래스를 포함한 모든 클래스는 지정되지 않은 경우 기본 생성자를 가져옵니다 (익명 클래스의 경우 하나를 지정할 수 없으므로 항상 기본 생성자를 얻습니다).

생성자가있는 추상 클래스의 좋은 예는 Calendar 클래스입니다. Calendar.getInstance ()를 호출하여 Calendar 객체를 얻지 만 보호되는 생성자도 있습니다. 생성자가 보호되는 이유는 하위 클래스 만 호출 할 수 있도록하기 때문입니다 (또는 동일한 패키지의 클래스이지만 추상이기 때문에 적용되지 않음). GregorianCalendar 는 Calendar를 확장하는 클래스의 예입니다.


예, 가능합니다. 추상 클래스 생성자는 일반적으로 모든 하위 클래스에 공통적 인 초기화 이벤트에 대한 슈퍼 호출에 사용됩니다.


추상 클래스는 생성자를 가질 수 있지만 추상 클래스의 객체를 만들 수는 없으므로 해당 생성자를 어떻게 사용합니까?

문제는 하위 클래스에서 해당 추상 클래스를 상속하면 하위 클래스의 super (value) 메서드를 통해 해당 (추상) 생성자에 값을 전달할 수 있으며 생성자를 상속하지 않습니다.

따라서 super를 사용하면 추상 클래스의 생성자에 값을 전달할 수 있으며 내가 기억하는 한 메서드 또는 생성자의 첫 번째 문이어야합니다.


좋은 답변이 많지만 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");
}
}

물론 추상 클래스는 생성자를 가질 수 있으며, 일반적으로 클래스 생성자는 필드를 초기화하는 데 사용되므로 추상 클래스 생성자는 추상 클래스의 필드를 초기화하는 데 사용됩니다. 자식 클래스의 인스턴스화가 발생하기 전에 추상 클래스의 특정 필드를 초기화하려는 경우 추상 클래스에 대한 생성자를 제공합니다. 추상 클래스 생성자를 사용하여 모든 자식 클래스와 관련된 코드를 실행할 수도 있습니다. 이것은 코드 중복을 방지합니다.

추상 클래스의 인스턴스를 만들 수는 없지만 추상 클래스에서 파생 된 클래스의 인스턴스를 만들 수 있습니다. 따라서 파생 클래스의 인스턴스가 생성되면 부모 추상 클래스 생성자가 자동으로 호출됩니다.

참고 : 이 기사


이걸 고려하세요:

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

수퍼 클래스는 추상적이며 생성자를 가지고 있습니다.


As described by javafuns here, this is an example:

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

In a concrete class, declaration of a constructor for a concrete type Fnord effectively exposes two things:

  • A means by which code can request the creation of an instance of Fnord

  • A means by which an instance of a type derived from Fnord which is under construction can request that all base-class features be initialized.

While there should perhaps be a means by which these two abilities could be controlled separately, for every concrete type one definition will enable both. Although the first ability is not meaningful for an abstract class, the second ability is just as meaningful for an abstract class as it would be for any other, and thus its declaration is just as necessary and useful.


Yes, Abstract Classes can have constructors !

Here is an example using constructor in abstract class:

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

So I think you got the answer.


yes it is. And a constructor of abstract class is called when an instance of a inherited class is created. For example, the following is a valid Java program.

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

}

This is the output of the above code,

Base Constructor Called Derived Constructor Called

references: enter link description here


Abstract class can have a constructor though it cannot be instantiated. But the constructor defined in an abstract class can be used for instantiation of concrete class of this abstract class. Check 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.


Since an abstract class can have variables of all access modifiers, they have to be initialized to default values, so constructor is necessary. As you instantiate the child class, a constructor of an abstract class is invoked and variables are initialized.

On the contrary, an interface does contain only constant variables means they are already initialized. So interface doesn't need a constructor.


In order to achieve constructor chaining, the abstract class will have a constructor. The compiler keeps Super() statement inside the subclass constructor, which will call the superclass constructor. If there were no constructors for abstract classes then java rules are violated and we can't achieve constructor chaining.


Yes, an Abstract Class can have a Constructor. You Can Overload as many Constructor as you want in an Abstract Class. These Contractors Can be used to Initialized the initial state of the Objects Extending the Abstract Class. As we know we can't make an object of an Abstract Class because Objects are Created by the "new" keywords and not by the constructors...they are there for only initializing the state of the subclass Objects.


Yes surely you can add one, as already mentioned for initialization of Abstract class variables. BUT if you dont explicitly declare one, it anyways has an implicit constructor for "Constructor Chaining" to work.


The purpose of the constructor in a class is used to initialize fields but not to "build objects". When you try to create a new instance of an abstract SuperClass, the compiler will give you an error. However, we can inherit an abstract class Employee and make use of its constructor by setting its variables See example below

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

package Test1;

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

}

Yes..It is like any other class. It can have a constructor and it is called after creating object for the base class.

참고URL : https://stackoverflow.com/questions/260666/can-an-abstract-class-have-a-constructor

반응형