Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

자바에서 추상 클래스에는 생성자가 있지만 인터페이스에는 생성자가 없는 이유

생성자(Constructor)는 특정 객체를 기준으로 해당 클래스의 비정적(non-static) 멤버들을 초기화하는 역할을 합니다. 그렇다면 왜 자바에서는 추상 클래스에는 생성자가 존재하지만, 인터페이스에는 생성자가 없을까요? 각각의 이유를 예제 코드와 함께 살펴보겠습니다.

인터페이스에 생성자가 없는 이유

  • 자바의 인터페이스(Interface)에는 생성자가 없습니다. 그 이유는 인터페이스의 모든 데이터 멤버가 기본적으로 public static final로 선언되는 상수(constant)이기 때문입니다. 상수는 선언 시점에 값을 할당해야 하므로 생성자를 통한 초기화 과정이 필요하지 않습니다.
  • 인터페이스에는 생성자로 초기화할 수 있는 일반적인 인스턴스 변수 자체가 존재하지 않습니다.
  • 메서드를 호출하려면 객체가 필요한데, 인터페이스의 메서드는 구현부(메서드 바디)가 없으므로 직접 호출할 대상이 없습니다.
  • 결국 인터페이스의 메서드를 직접 호출할 수 없기 때문에 인터페이스의 객체를 생성할 필요가 없고, 따라서 생성자도 필요하지 않습니다.

예제 1

interface Addition {
    int add(int i, int j);
}
public class Test implements Addition {
    public int add(int i, int j) {
        int k = i+j;
        return k;
    }
    public static void main(String args[]) {
        Test t = new Test();
        System.out.println("k value is:" + t.add(10,20));
    }
}

출력 결과

k value is:30

위 예제처럼 인터페이스는 구현 클래스(Test)를 통해 객체를 생성하고 메서드를 사용합니다. 인터페이스 자체를 객체화하는 것은 불가능합니다.

클래스(추상 클래스)의 생성자

  • 클래스에서 생성자의 목적은 필드를 초기화하는 것이지, 객체를 생성(빌드)하는 것이 아닙니다.
  • 추상 슈퍼클래스의 새 인스턴스를 직접 생성하려고 하면 컴파일러가 오류를 발생시킵니다.
  • 그러나 추상 클래스를 상속한 서브클래스에서는 super() 키워드를 통해 부모 클래스의 생성자를 호출하여 변수를 설정할 수 있습니다.

예제 2

abstract class Employee {
    public String empName;
    abstract double calcSalary();
    Employee(String name) {
        this.empName = name; // 추상 클래스의 생성자
    }
}
class Manager extends Employee {
    Manager(String name) {
        super(name); // 서브클래스의 생성자에서 이름 설정
    }
    double calcSalary() {
        return 50000;
    }
}
public class Test {
    public static void main(String args[]) {
        Employee e = new Manager("Adithya");
        System.out.println("Manager Name is:" + e.empName);
        System.out.println("Salary is:" + e.calcSalary());
    }
}

출력 결과

Manager Name is:Adithya
Salary is:50000.0

정리

요약하자면, 인터페이스는 오직 상수와 추상 메서드만 가지며 객체화될 수 없기 때문에 생성자가 필요 없습니다. 반면 추상 클래스는 인스턴스 변수를 가질 수 있고, 서브클래스가 super()를 통해 이를 초기화할 수 있어야 하므로 생성자를 가질 수 있습니다. 즉, 추상 클래스의 생성자는 직접적인 객체 생성이 아니라 상속 구조에서 공통 필드를 초기화하기 위한 용도로 사용됩니다.