본문 바로가기
Java/Java

[Java] 상속

by 전재경 2022. 11. 30.

상속

이미 잘 개발된 클래스를 재사용해서 중복되는 코드를 줄여준다.

상속을 하더라도 자식 클래스가 부모의 모든 것들을 물려받는 것은 아니다.

  • 부모 클래스의 private 접근 제한을 갖는 필드 및 메소드는 자식이 물려받을 수 없다.
  • 부모와 자식 클래스가 서로 다른 패키지에 있다면, 부모의 default 접근 제한을 갖는 필드 및 메소드도 자식이 물려받을 수 없다.
    (default 접근 제한은 ‘같은 패키지에 있는 클래스’만 접근이 가능하게끔 하는 접근 제한자이기 때문)
  • 그 이외의 경우는 모두 상속의 대상이 된다.

 

//상위클래스
public class A{
	int field1;
    void method1() { . . .}
}

 

//하위클래스
public class B extends A{	// extends A == A를 상속
	int field2;
    void method2() { . . .}
}

 

부모 생성자 호출

 

모든 객체는 클래스의 생성자를 호출해야만 생성된다.

부모 생성자는 자식 생성자의 맨 첫줄에서 호출 된다.

 

DmbCellPhone dmbCellPhone = new DmbCellPhone();

DmbCellPhone 객체만 생성하는 것처럼 보이지만, 사실은 내부적으로 부모인 CellPhone 객체가 먼저 생성되고

자식인 DmbCellPhone객체가 생성

public DmbCellPhone(){
	super();
}

super();는 부모의 기본 생성자를 호출, CellPhone클래스의 다음 생성자를 호출

CellPhone의 생성자가 선언되지 않았지만 컴파일러에 의해 기본 생성자가 만들어지므로 문제없이 실행

 

 

super

class Ex7_3 {
    public static void main(String args[]){
        Child2 c = new Child2();
        c.method();
    }
}

class Parent2 { int x= 10; }

    class Child2 extends Parent2{
        void method(){
            System.out.println("x=" + x);
            System.out.println("this.x = " +this.x);
            System.out.println("super.x = " +super.x);
        }
    }

모든 인스턴스 메서드에는 this와 super가 지역변수로 존재하는데,

이 들에는 자신이 속한 인스턴스의 주소가 자동으로 저장된다.

조상의 멤버와 자신의 멤버를 구현하는데 사용된다는 점을 제외하면 this와 super는 근본적으로 같다.

 

this()처럼 super()도 생성자이다. this()는 같은 클래스의 다른 생성자를 호출하는데 사용

super()는 조상의 생성자를 호출

 

method 재정의

부모 클래스의 모든 메소드가 자식 클래스에 맞게 설계되어 있다면 이상적인 상속

하지만 어떤 메소드에는 자식 클래스가 사용하기 적합하지 않기도 하다.

이 경우는 상송된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해야 한다.

이런 경우를 위해 메소드 재정의(오버라이딩 : Overriding)기능을 제공

 

예시

//상위클래스
public void boarding(int passenger){
        this.currentPassengerCount += passenger;
        this.maxPassengerCount -= passenger;
    }
@Override
    public void boarding(int passenger) {
        this.maxPassengerCount = 30;
        if (this.status == "운행중") {
            if (passenger > 30) {
                System.out.println("최대 승객 수 초과");
            } else {
                this.currentPassengerCount += passenger;
                this.maxPassengerCount -= passenger;
                this.price += 1000 * passenger; // 인당 1000원이니 기본요금 1000원에 * 인원수만큼
                System.out.println("탑승 승객 수 : " + this.currentPassengerCount);
                System.out.println("잔여 승객 수 : " + this.maxPassengerCount);
                System.out.println("요금 확인 : " + this.price);
            }
        }
    }

상위클래스의 boarding 하위클래스의 boarding에서 overridng해서 재정의 해서 사용

public void boarding(int passenger, String target, int targetDistance) { // 시나리오에 나온 승객수, 목적지, 목적지까지의 거리
    this.maxPassengerCount = 4;
    if (this.status == "일반") {
        if (passenger <= 4) {     //최대 4명까지 탑승
            this.currentPassengerCount += passenger;    // 현재 탑승객 수에 탑승객수를 더함
            this.maxPassengerCount -= passenger;   // 자리수 4에 탑승객 수만큼 뺌
            this.target = target;
            this.targetDistance = targetDistance;
            this.status = "운행중";
            this.price += 3000 + 1000 * (this.targetDistance - 1);  //기본요금 3000원 + 거리당 요금 1000 * 거리( -1은 기본 거리)

            System.out.println("탑승 승객 수 : " + this.currentPassengerCount);
            System.out.println("잔여 승객 수 : " + this.maxPassengerCount);
            System.out.println("기본 요금 확인 : " + 3000);
            System.out.println("목적지 : " + this.target);
            System.out.println("목적지까지 거리 : " + this.targetDistance + "km");
            System.out.println("지불할 요금 : " + this.price);
            System.out.println("상태 : " + this.status);
        } else {
            System.out.println("최대 승객 수 초과 입니다.");
        }
    } else {
        System.out.println("운행 불가입니다.");
    }
}

또 다른 하위클래스에서 같은 boarding이지만 overring할 필요 없이 오버로딩 되었기에 그냥 사용 가능

 

 

final 클래스와 메소드

 

해당 선언이 최송 상태, 결코 수정될 수 없음을 뜻함

필드를 선언할 때 final이 지정되면 초기값 설정 후 더이상 값을 변경할 수 없다.

제어자 대상 의미
final 클래스 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
메소드 변경될 수 없는 메소드, final로 지정된 메소드는 오버라이딩을 통해 재정의 될 수 없다.
멤버변수 변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 된다.
지역변수

final 클래스의 대표적인 예는 String과 Math이다.

final class FinalTest{         	  //조상이 될 수 없는 클래스
    final int Max_Size = 10;  	  //값을 변경할 수 없는 멤버변수(상수)
    
    final void getMaxSize(){   	  //오버라이딩할 수 없는 메소드(변경불가)
        final int LV = Max_Size;  //값을 변경할 수 없는 지역변수(상수)
        return Max_Size;
    }
}

 

protected

public과 default 접근 제한의 중간쯤 해당한다.

접근제어자가 protected로 설정되었다면 protected가 붙은 변수, 메소드는 동일 패키지의 클래스 또는 해당 클래스를 상속받은 다른 패키지의 클래스에서만 접근이 가능하다.

 

package house;  // 패키지가 서로 다르다.

public class HousePark {
    protected String lastname = "park";
}

 

 

package house.person;  // 패키지가 서로 다르다.

import house.HousePark;

public class EungYongPark extends HousePark {  // HousePark을 상속했다.
    public static void main(String[] args) {
        EungYongPark eyp = new EungYongPark();
        System.out.println(eyp.lastname);  // 상속한 클래스의 protected 변수는 접근이 가능하다.
    }
}

HousePark 클래스를 상속한 EungYongPark 클래스의 패키지는 house.person으로

HousePark의 패키지인 house와 다르지만 HousePark의 lastname 변수가 protected이기 때문에 

eyp.lastname과 같은 접근이 가능하다.

만약 lastname의 접근제어자가 protected 가 아닌 default 접근제어자였다면

eyp.lastname 문장은 컴파일 오류가 발생할 것이다.

'Java > Java' 카테고리의 다른 글

[Java] 추상 클래스, 메소드  (0) 2022.12.02
[Java]타입 변환과 다형성  (0) 2022.11.30
[Java]public static void  (0) 2022.11.27
[Java]오버라이딩 (Override)  (0) 2022.11.27
[Java] 클래스의 구성  (0) 2022.11.22

댓글