자바의 상속

mDev_97·2022년 1월 5일
0

Java

목록 보기
8/28

상속 (Inheritance)

• 부모 클래스의 필드와 메소드를 자식 클래스가 물려받는 것

• 동일한 특성을 재정의하는 것을 상속을 통해서 간결하게 만들 수 있다.

• 멤버를 중복 작성할 필요가 없다.

• 클래스들을 계층적으로 분류할 수 있다.

• 클래스의 재사용과 확장이 용이하다.

• 상속을 통해서 새로운 클래스 작성이 빨라질 수 있다.

부모 클래스 : 슈퍼 클래스(Super Class)

자식 클래스 : 서브 클래스(Sub Class)

extends 키워드를 사용하여 상속

• 클래스 상속 예

class Point {
    private int x, y; // x, y 좌표
    public void setPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public void showPoint() {
        System.out.println("(" + x + ", " + y + ")");
    }
}

// Point 클래스를 상속받는 ColorPoint 선언
class ColorPoint extends Point {
    private String color; // 색상
    public void setColor(String color) {
        this.color = color;
    }
    
    public void showColorPoint() {
        System.out.print(color);
        showPoint(); // 슈퍼 클래스의 showPoint() 함수를 호출
    }
}

public class PointEx {
    public static void main(String[] args) {
        Point p = new Point(); // Point 객체 생성
        p.setPoint(4, 5);  // Point 클래스의 setPoint() 호출
        p.showPoint();
        
        ColorPoint cp = new ColorPoint();
        cp.setPoint(5, 6); // Point 클래스의 setPoint()
        cp.setColor("blue"); // ColorPoint 클래스의 setColor()
        cp.showColorPoint(); // ColorPoint 클래스의 showColorPoint()
    }
}

• 실행 결과

(4, 5)
blue(5, 6)

자바 상속의 특징

• 자바에서의 클래스 상속에서는 다중 상속을 지원하지는 않는다.

• 상속 횟수는 무제한이다.
-> 한 클래스를 여러 클래스가 상속할 수 있다.

• 컴파일러에 의해 모든 클래스는 java.lang.Object를 상속받는다.

상속과 접근 지정자

슈퍼 클래스의 public 멤버

• 슈퍼 클래스의 public 멤버는 다른 모든 클래스가 접근 가능

슈퍼 클래스의 protected 멤버

• 같은 패키지 내에 있는 모든 클래스는 접근 가능
• 서브 클래스가 다른 패키지에 있더라도 서브 클래스는 슈퍼 클래스의 protected 멤버 접근 가능하다.

슈퍼 클래스의 private 멤버

• private 멤버는 모든 다른 클래스는 접근 불가능하다.
• 클래스 내에서만 접근 가능하다.

슈퍼 클래스의 디폴트(default) 멤버

• 패키지 내에 있는 모든 클래스는 접근 가능하다.

상속 관계에서의 생성자 호출 및 실행

new키워드에 의해 서브 클래스의 객체가 생성되는 경우
• 슈퍼 클래스와 서브 클래스의 생성자가 모두 실행된다.
• 서브 클래스의 생성자가 먼저 호출된다.
• 서브 클래스의 생성자를 실행하기 전 슈퍼 클래스의 생성자를 호출한다.
• 슈퍼 클래스의 생성자 실행 후 서브 클래스의 생성자 실행

상속 관계 생성자 호출 및 실행 예제

class NumberOne {
    public NumberOne() {
        System.out.println("NumberOne 생성자");
    }
}

class NumberTwo extends NumberOne {
    public NumberTwo() {
        System.out.println("NumberTwo 생성자");
    }
}

class NumberThree extends NumberTwo {
    public NumberThree() {
        System.out.println("NumberThree 생성자");
    }
}

public class ConstructorExample {
    public static void main(String[] args) {
        NumberThree numberThree = new NumberThree();
    }
}

• 실행 결과

NumberOne 생성자
NumberTwo 생성자
NumberThree 생성자

상속 관계에서의 생성자 선택

• 슈퍼 클래스와 서브 클래스 모두 각각 여러 개의 생성자를 작성할 수 있다.

서브 클래스의 생성자 작성 원칙

• 서브 클래스의 생성자가 슈퍼 클래스의 생성자 하나를 선택

• 선택하지 않는 경우 컴파일러가 자동으로 슈퍼 클래스의 기본 생성자를 선택한다.
-> 컴파일러는 서브 클래스이 기본 생성자를 슈퍼 클래스의 기본 생성자와 자동으로 짝을 맺는다.

슈퍼 클래스의 생성자를 선택하는 방법

super() 메소드 사용

class NumberOne {
    public NumberOne(int x) {
        System.out.println("NumberOne 생성자");
    }
}

class NumberTwo extends NumberOne {
    public NumberTwo() { // 오류 발생
        System.out.println("NumberTwo 생성자");
    }
}

public class ConstructorExample {
    public static void main(String[] args) {
        NumberThree numberTwo = new NumberTwo();
    }
}

• 서브 클래스의 생성자와 슈퍼 클래스의 생성자의 짝을 찾을 수 없기 때문에 오류가 발생한다.

서브 클래스의 생성자가 슈퍼 클래스의 생성자를 선택하지 않는 경우

class NumberOne {
    public NumberOne() {
        System.out.println("NumberOne 기본 생성자");
    }
    
    public NumberOne(int x) {
        System.out.println("NumberOne 매개변수 생성자");
    }
}

class NumberTwo extends NumberOne {
    public NumberTwo() {
        System.out.println("NumberTwo 기본 생성자");
    }
    
    public NumberTwo(int x) {
        System.out.println("NumberTwo 매개변수 생성자");
    }
}

public class ConstructorExample {
    public static void main(String[] args) {
        NumberThree numberTwo = new NumberTwo(10);
    }
}

• 실행결과

NumberOne 기본 생성자
NumberTwo 매개변수 생성자

super()을 이용하여 슈퍼 클래스의 생성자를 선택

반드시 서브 클래스 생성자의 첫 라인에 작성
• 파라미터(parameter)를 이용하여 슈퍼 클래스의 생성자를 호출

class NumberOne {
    public NumberOne() {
        System.out.println("NumberOne 기본 생성자");
    }
    
    public NumberOne(int x) {
        System.out.println("NumberOne 매개변수 생성자");
    }
}

class NumberTwo extends NumberOne {
    public NumberTwo() {
        System.out.println("NumberTwo 기본 생성자");
    }
    
    public NumberTwo(int x) {
        super(x); // 반드시 첫 라인에 작성
        // NumberOne 클래스의 매개변수 생성자를 호출
        System.out.println("NumberTwo 매개변수 생성자");
    }
}

public class ConstructorExample {
    public static void main(String[] args) {
        NumberThree numberTwo = new NumberTwo(10);
    }
}

• 실행 결과

NumberOne 매개변수 생성자
NumberTwo 매개변수 생성자

profile
안녕하세요. 백엔드, 클라우드, 인프라에 관심과 열정이 있는 김문성입니다. 😊

0개의 댓글