[Java] 상속의 기본

이준영·2023년 8월 15일
0

🟫 Java

목록 보기
1/21
post-thumbnail

자바의 상속은 익숙하고 자주 쓰는 문법이지만 그 본질은 잘 이해하지 못하고 있다고 느껴 다시 한번 정리해 보려고 합니다.

상속의 치명적인 오해

  • 상속은 코드의 재활용을 위한 문법입니다. ❌
  • 연관된 일련의 클래스들에 대해 공통적인 규약을 정의할 수 있습니다. ⭕️

💡 상속은 재활용을 위한 문법이 아니고, A, B, C 클래스의 공통적인 규약을 적용시켜주는 것입니다.



상속의 기본 문법

class Man {
    String name;
    public void tellYourName() { 
        System.out.println("My name is " + name); 
    }
}

class BusinessMan extends Man {
    String company;
    String position;
    
    public void tellYourInfo() {
        System.out.println("My company is " + company);
        System.out.println("My position is " + position);
        tellYourName();
    }
}

위와같이 특정 클래스이름 뒤에 extends [상속받을 클래스] 를 추가해 상속을 받을 수 있습니다.
위의 예시에서는 BusinessMan이 Man 클래스를 상속받고 있습니다. 클래스를 상속받으면 해당 클래스의 필드 변수와 메소드를 가져와서 사용할 수 있습니다. (BusinessMan이 Man의 tellYourName() 호출)

⛔️ 상속된 메소드와 필드변수가 Private으로 선언되었을 경우 접근이 불가능하고,
Public으로 선언 되었을 경우만 가능합니다.



상속 관련 용어

상속의 대상이 되는 클래스 : 상위 클래스, 부모 클래스
상속을 하는 클래스 : 하위 클래스, 자식 클래스

상속의 관계는 위,아래 또는 부모와 자식으로 표현합니다.

  • Man -> 부모클래스
  • BusinessMan -> 자식 클래스


다중상속 불가

class AAA {
    public AAA () {
        System.out.println("I'm AAA");
    }
}
class BBB {
    public BBB () {
        System.out.println("I'm BBB");
    }
}

CCC는 AAA,BBB 두 개의 클래스 모두를 상속 받을 수 없고 오직 하나의 클래스만 상속 가능합니다.

❌ 다중 상속 불가능

class CCC extends AAA,BBB { 
    public CCC () {
        System.out.println("I'm CCC");
    }
}


⭕️ 단일 상속 가능

class CCC extends AAA { 
    public CCC () {
        System.out.println("I'm CCC");
    }
}


상속과 생성자 호출

기본적으로 클래스는 생성시에 생성자를 호출합니다.
상속을 받고 있는 경우라면 부모 클래스의 생성자도 호출해야 합니다.

class SuperCLS {
	String name;
    public SuperCLS () {
        this.name = "superClass"
    }
    public SuperCLS (String name) {
        this.name = name;
    }
}

class SubCLS extends SuperCLS {
    public SubCLS (String name) {
    	super(name); // 부모 클래스의 생성자 호출
        System.out.println("I'm Sub Class");
    }
}

super()

super()는 부모의 생성자를 의미합니다. super(name) 과 같이 부모의 다른 생성자들도 호출 가능합니다.
super()을 명시하지 않는다면, 컴파일러가 자동으로 셍성자의 맨 윗줄에 super()를 삽입하여 실행합니다.



클래스 변수, 메소드도 상속이 될까?

클래스(스태틱) 변수, 메소드는 전체가 공유하는 데이터 인데 상속이 될까? 의문이 듭니다. 아래 count 변수와 같이 클래스 내부에 선언된 클래스 변수는 과연 상속이 될까?

class SuperCLS {
    protected static int count = 0; // 클래스 변수

    public SuperCLS() {
        count++; // 클래스 내에서는 직접 접근 가능
    }
}

class SubCLS extends SuperCLS {
    public void showCount() {
        System.out.println(count);
    }
}

정답부터 이야기 하자면 상속이 되지 않습니다.
당연한 이야기로 비유를 들자면 부모의 건물에 다른 사람이 월세로 살고 있다고 가정했을 때, 부모가 자식에게 건물을 물려줄 수는 있습니다. 그러나 건물 안 월세로 살고 있는 다른 사람의 가구까지는 물려줄 수 없습니다. 당연한 이야기이지만, 부모도 다른사람의 가구는 자신의 것이 아니기 때문에 자식에게 물려줄 수 없는 것입니다.
이와 같은 논리로 static 으로 선언된 count 는 전역변수이기 때문에 부모 클래스인 SuperCLS에 선언 되어있더라도 자식 클래스에게 물려줄 수는 없는 것입니다.


집 공간을 내어준 특권 - 직접 호출
그러나 집 공간을 내어준 부모는 하나의 특권을 가집니다.
보통은 클래스 변수를 호출할 경우

	SuperCLS.count

와 같이 클래스 이름.변수이름 의 형태로 호출해야 하지만, 해당 클래스 변수를 선언한 클래스 내부에서는

class SuperCLS {
    protected static int count = 0; // 클래스 변수

    public SuperCLS() {
        count++; // 클래스 내에서는 직접 접근 가능
    }
}

count 만으로 호출이 가능합니다.

하위 클래스에서도 이름만으로 접근이 가능합니다.
단, 클래스 변수의 접근 수준 지시자가 public 이나 protect로 허용될 경우에만 가능합니다. (private는 접근 불가)

class SubCLS extends SuperCLS {
    public void showCount() {
        System.out.println(count);
    }
}
profile
작은 걸음이라도 꾸준히

0개의 댓글