본문 바로가기

자바/자바 개념

[Java] 상속, 상속과 protected 접근 지정자, 상속과 생성자, super () / 2021.08.02

* 참고자료 : 명품 자바 프로그래밍


1. 상속이란?
상속은 부모 클래스에 만들어진 필드와 메소드를 자식 클래스가 물려받는 것이다. 상속을 선언하면, 자식 클래스는 부모 클래스에 만들어진 필드와 메소드를 만들지 않고 만든 것과 같은 효과를 얻는다.
단, 상속은 클래스 사이의 상속이지 객체 사이의 상속은 아니다. 다시 말해, 자식 객체는 자식 클래스와 부모 클래스에 만들어진 모든 멤버를 가지고 생성된다.

2. 상속의 장점
예를 들어, 4개의 클래스가 있다. 이 4개의 클래스는 같은 코드를 포함하는데, 이 코드에 오류가 있어 코드를 수정하려면 클래스 4개를 각각 모두 수정해 주어야 한다. 이처럼 코드가 중복되면 클래스의 유지 보수가 번거롭다.
그러나 상속을 이용하면 간단히 해결된다. 공통된 코드를 하나의 클래스(부모 클래스)에 작성하고 이 코드를 포함하는 4개의 클래스는 코드를 중복 작성 할 필요 없이 상속을 받으면 된다. 만약 코드에 오류가 있어 코드를 수정해야 한다면 부모 클래스의 코드만 수정해 주면 된다. 이처럼 상속은 코드 중복을 제거하여 클래스를 간결하게 구현할 수 있도록 해준다.
장점을 간략히 정리하면 다음과 같다.
(1) 클래스의 간결화 - 멤버의 중복 작성 불필요
(2) 클래스 관리 용이 - 클래스들의 계층적 분류
(3) 소프트웨어의 생산성 향상 - 클래스 재사용과 확장 용이

3. 상속의 특징
(1) 자바에서는 클래스의 다중 상속을 지원하지 않는다. (C++에서는 지원한다.)
자바는 클래스를 여러 개 상속받는 다중 상속을 지원하지 않는다. 그러므로 extends 다음에는 클래스 이름을 하나만 지정할 수 있다.
(2) 자바에서는 상속의 횟수에 제한을 두지 않는다.
(3) 자바에서 계층 구조의 최상위에 java.lang.Object 클래스가 있다.

4. 상속과 protected 접근 지정자
슈퍼 클래스의 protected 멤버는 다음 주 가지 경우에 접근을 허용한다.
(1) 같은 패키지에 속한 모든 클래스들
(2) 같은 패키지든 다른 패키지든 상속받는 서브 클래스

(예제) 클래스 Person을 아래와 같은 필드를 갖도록 선언하고, 클래스 student는 Person을 상속받아 각 멤버 필드에 값을 저장하라.
- private int weight;
- int age;
- protected int height;
- public String name;

이 예제에서 Person클래스의 private필드인 weight는 Student 클래스에서는 접근이 불가능 하여 슈퍼 클래스인 Person의 get, set메소드를 통해서만 조작이 가능하다.

package Chapter5;
class Person{
    private int weight;
    int age;
    protected int height;  // protected는 서브클래스에서 접근 가능
    public String name;
    // private 멤버인 weight를 접근하기 위한 get/set 메소드
    public int getWeight() {
        return weight;
    }
    public void setWeight(int weight) {
        this.weight = weight;
    }    
}

class Student extends Person{
    public void set() {
        age = 30;
        name = "홍길동";
        height = 175;
        // weight = 99; 오류 : 슈퍼클래스의 private 멤버 접근 불가
        setWeight(99);
    }
}
public class InheritanceEx {
    public static void main(String[] args) {
        Student s = new Student();
        s.set();
    }
}​

 


5. 상속과 생성자
서브 클래스와 슈퍼 클래스는 각각 생성자를 가지고 있다.
(1) 서브 클래스 객체가 생성될 때 서브 클래스의 생성자와 슈퍼 클래스의 생성자가 모두 실행되는가? 아니면 서브 클래스의 생성자만 실행되는가?
둘 다 실행된다. 서브 클래스의 객체가 생성되면 이 객체 속에 서브 클래스와 맴버와 슈퍼 클래스의 멤버가 모두 들어 있다.
(2) 서브 클래스의 생성자와 슈퍼 클래스의 생성자 중 누가 먼저 실행되는가?
슈퍼 클래스의 생성자가 먼저 실행된 후 서브 클래스의 생성자가 실행된다.
이 말을 코드로 나타 내면,

이와 같다.

6. 서브 클래스에서 슈퍼 클래스 생성자 선택
(1) 슈퍼 클래스의 기본 생성자가 자동 선택되는 경우
개발자의 명시적 지시가 없으면, 서브 클래스의 생성자가 기본 생성자이든 매개변수를 가진 생성자이든, 슈퍼 클래스에 만들어진 기본 생성자가 선택된다. 이 선택은 자바 컴파일러에 의해 강제로 이루어진다.

- 클래스 B는 A를 상속받는다. 클래스 A에는 2개의 생성자가 작성되어 있지만, 클래스 B의 기본 생성자가 호출되면, 슈퍼 클래스의 기본 생성자 A( )가 자동으로 호출된다.
만약 A에 기본 생성자 없이 A(int x)만 작성되어 있다면 오류가 발생한다.
서브 클래스 B의 매개변수를 가진 생성자도 슈퍼 클래스 A의 기본 생성자와 짝을 이룬다.

(2) super( )를 이용하여 명시적으로 슈퍼 클래스의 생성자 선택
서브 클래스의 생성자에서 super( )를 이용하면, 슈퍼 클래스 생성자를 명시적으로 선택할 수 있다. super( )는 슈퍼 클래스 생성자를 호출하는 코드이다. 괄호 안에 인자를 전달하여 슈퍼 클래스의 생성자를 호출할 수도 있다.
* super() 는 반드시 생성자의 첫 라인에 사용되어야 한다.


(예제) super()를 이용하여 ColorPoint 클래스의 생성자에서 슈퍼 클래스 Point의 생성자를 호출하는 예를 보인다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package Chapter5;
 
class Point{
    private int x, y;
    public Point() {
        this.x = this.y = 0;
    }
    // 호출
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public void showPoint() {
        System.out.println("("+x+","+y+")");
    }
}
 
class ColorPoint extends Point{
    private String color;
    public ColorPoint(int x, int y, String color) {
        super(x, y); // Point의 생성자 Point(x, y) 호출
        this.color = color;
    }
    public void showColorPoint() {
        System.out.print(color);
        showPoint();
    }
}
public class SuperEx {
    public static void main(String[] args) {
        ColorPoint cp = new ColorPoint(56"blue"); // x =5, y=6, color="blue" 전달
        cp.showColorPoint();
    }
}
cs

 

실행 결과 :