본문 바로가기

Java

[Java] 이것이 자바다 - 상속

상속이란?

현실에서 상속이란 부모가 자식에게 물려주는 행위를 말한다. 객체 지향 프로그래밍에서도 상속이 존재하는데 자식 클래스가 부모클래스를 상속받음으로써 부모클래스가 갖고 있는 필드나 메서드를 사용할 수 있다. 이러한 특성 덕분에 상속을 사용하면 코드의 중복을 줄여 개발 시간을 단축시키므로 매우 효율적이다.

 

부모클래스를 상속받는다고 해서 모든 필드와 메서드를 사용할 수 있는 것은 아니다. 부모클래스에서 접근제어자가 private인 필드나 메서드는 상속 대상에서 제외되며 부모클래스와 자식클래스가 다른 패키지에 존재하는 경우 default 접근제어자도 상속대상에서 제외된다.

클래스 상속

상속을 사용하는 방법은 아래와 같이 자식클래스의 extends 뒤에 부모클래스를 적으면 된다. 자바에서는 다중 상속을 허용하지 않는다. 그렇기 때문에 extends 뒤에 여러 부모클래스를 선언할 수 없다.

 

class 자식클래스 extends 부모클래스 {
    // 필드
    // 생성자
    // 메소드
}

부모클래스 필드와 메서드 사용

public class 부모클래스 {
    // 필드
    String parents
    
    // 생성자
    
    // 메서드
    void parentsMethod() {
    	...
    };
}

 

위와 같은 부모클래스를 상속받아 사용한다고 했을 때 부모클래스의 필드와 메서드를 사용하려면 아래와 같이 자식 객체를 생성한 후 필드나 메서드를 호출하면 된다.

 

public static void main(String[] args) {
    자식클래스 child = new 자식클래스();
    
    System.out.println(child.parents);
    child.parentsMethod();
}

부모 생성자 호출

부모클래스를 호출하기 위해서는 super()를 사용하면 된다. 자바에서는 자식 객체를 생성하기 위해서는 항상 부모 객체를 먼저 생성해야 한다. 만약 자식클래스의 기본 생성자가 선언되어 있지 않다면 컴파일 과정에서 컴파일러가 자식클래스에 아래와 같은 기본생성자를 선언한다.

 

public 자식클래스() {
    super();
}

 

아래와 같은 부모클래스와 자식클래스가 있다고 가정해보자.

 

public class 부모클래스 {
    String parents1;
    String parents2;
    
    public 부모클래스(String parents1, String parents2) {
    	this.parents1 = parents1;
        this.parents2 = parents2;
    }
}
public class 자식클래스 {
    String child;
    
    public 자식클래스(String parents1, String parents2, String child) {
    	super(parents1, parents2);
        this.child = child;
    }
}

만약 자식클래스 생성자 부분에 super(parents1, parents2)가 없다면 컴파일러는 컴파일 단계여서 부모클래스의 기본생성자를 생성하는 super()를 추가한다. 하지만 부모클래스에는 기본생성자가 없기 때문에 컴파일 단계에서 에러가 발생한다. 부모클래스에 기본생성자가 없고 매개변수가 있는 생성자만 있다면 자식클래스 생성자에서 매개변수가 있는 부모클래스 생성자를 호출해주어야 한다.

부모 메서드 재정의

상속 받은 부모클래스의 메서드를 재정의 할 수 있다. 이를 오버라이드(Override)라고 한다.

// 부모클래스
public class Calculator {
    double areaCircle(double r) {
    	System.out.println("Calculator 객체의 areaCircle() 실행");
        return 3.141592 * r * r;
    }
}
// 자식클래스
public class Computer extends Calculator {
    
    @Override
    double areaCircle(double r) {
    	System.out.println("Computer 객체의 areaCircle() 실행");
        return Math.PI * r * r;
    }
}

자식클래스은 Computer 클래스가 Calculator 클래스를 상속받아 areaCircle() 메서드를 재정의(Override)했다. 이제 Computer 클래스 객체를 생성한 후 areaCircle() 메서드를 호출하면 자식 클래스에서 재정의한 메서드가 실행된다.

 

참고로 @Override 어노테이션은 재정의하려는 부모클래스의 메서드와 자식클래스의 메서드의 메서드명, 리턴 타입, 매개 변수 등을 컴파일 단계에서 체크하여 개발자의 실수를 줄여준다. 다를 경우 컴파일 에러가 발생한다.