CH_07 상속

한지혜·2025년 3월 25일

상속

  • 부모 클래스의 필드와 메소드를 자식 클래스에게 물려주는 것
  • 부모 클래스를 수정하면 모든 자식 클래스에 수정 효과를 가져온다.

클래스 상속

  • 자식이 부모를 선택하여 extends키워드로 선언한다.
  • 자바는 다중 상속을 허용하지 않는다. 여러 개의 부모 클래스를 상속할 수 없다.
public class 자식클래스 extends 부모클래스 {
}

// 부모 클래스
public class Phone {
	public String model;
    public String color;
    
    public void bell() {
    	System.out.println("벨이 울립니다.");
    }
}

// 자식 클래스
public class SmartPhone extends Phone {
	public boolean wifi;
   	
    // 부모로부터 상속받은 필드 사용
    public SmartPhone(String model, String color) {
    	this.model = model;
        this.color = color;
    }
    
    public void setWifi(boolean wifi) {
    	this.wifi = wifi;
    }
}

// 메인 클래스
public class PhoneEx {
	public static void main(String[] args) {
    	SmartPhone myPhone = new SmartPhone("apple", "silver");
        
        // Phone으로부터 상속받은 메소드 사용
        myPhone.bell();
        
        // SmartPhone의 메소드 사용
        myPhone.setWifi(true);
    }
}

부모 생성자 호출

  • 자식 객체를 생성하면 부모 객체가 먼저 생성된 다음에 자식 객체가 생성된다.
  • 다음 코드는 Phone객체가 먼저 생성된 후, SmartPhone객체가 생성된 것이다.
SmartPhone myPhone = new SmartPhone("apple", "silver");

  • 부모 생성자는 자식 생성자의 맨 첫 줄에 숨겨져 있는 super()에 의해 호출된다.
    • 컴파일 과정에서 자동으로 추가된다. 따라서 생략 가능하다.
    • 만약 부모 클래스에 기본 생성자가 없다면 자식 생성자 선언에서 컴파일 에러가 발생한다.
  • 부모 클래스에 기본 생성자가 없고 매개변수를 갖는 생성자만 있다면,
    다음과 같이 super(매개값...)코드를 직접 넣어야 한다.
public SmartPhone() {
	super("apple", "black");
}

메소드 오버라이딩(Overriding)

  • 상속된 메소드를 자식 클래스에서 재정의하는 것
  • 메소드가 오버라이딩됐다면 해당 부모 메소드는 숨겨지고, 자식 메소드가 우선적으로 사용된다.
  • @Override어노테이션을 붙이면 컴파일 단계에서 정확히 오버라이딩 됐는지 체크하고, 문제가 있다면 컴파일 에러를 출력한다.
// 부모 클래스
public class Calculator {
	public double calculate(double r) {
    	return 3.14 * r * r;
    }
}

// 자식 클래스
public class Computer extends Calculator {
    // 메소드 오버라이딩
    @Override
    public double calculate(double r) {
    	return Math.PI * r * r;
    }
}

메소드 오버라이딩 규칙

  • 부모 메소드의 선언부(리턴 타입, 메소드 이름, 매개변수)와 동일해야 한다.
  • 접근 제한을 더 강하게 오버라이딩할 수 없다.(public -> private 변경 불가)
  • 새로운 예외를 throws할 수 없다.

부모 메소드 호출

  • 메소드를 재정의할 때, 부모 메소드의 일부만 변경된다 하더라도 중복된 내용을 자식 메소드도 가지고 있어야 한다.
  • super.method();로 자식 메소드 내에서 부모 메소드를 호출하면 된다.
    • super.method();작업 처리 2 전후 어디든지 올 수 있다.
class parent {
	public void method() {
    	// 작업 처리1
    }
}

class child {
	@Override
    public void method() {
    	super.method();
        // 작업 처리 2
    }
}

final 클래스와 final 메소드

(복습)필드 선언 시 final을 붙이면 초기값 설정 후 값을 변경할 수 없다.
final 클래스와 final 메소드는 상속과 관련있다.

final 클래스

  • final 클래스는 최종적인 클래스이므로 더 이상 상속할 수 없는 클래스가 된다.
  • 즉, final 클래스는 부모 클래스가 될 수 없으며, 자식 클래스를 만들 수 없다.
  • 대표적인 예: String 클래스는 다음과 같이 선언되어 있다.
public final class String { ... }

// 다음은 불가능한 예이다.
// public class NewString extends String { ... }

final 메소드

  • final 메소드는 최종적인 메소드이므로 오버라이딩할 수 없는 메소드가 된다.
  • 부모 클래스에서 선언된 final 메소드는 자식 클래스에서 재정의할 수 없다.

protected 접근 제한자

protected는 상속과 관련이 있고, publicdefault의 중간에 해당하는 접근 제한을 한다.

접근제한자제한대상제한범위
protected필드,생성자,메소드같은 패키지 or 자식 객체만 사용 가능
  • 자식 객체에서, new연산자를 사용해서 부모의 생성자를 직접 호출할 수는 없고, 자식 생성자에서 super()로 부모 생성자를 호출할 수 있다.
public class Parents {
	protected Parents() {
    }
    
    protected String field;
    
	protected void method() {
    }
}


public class Child extends Parents {
	public Child() {
    	// Parents() 생성자 호출
        super()
    }
    
    // 상속을 통해서만 사용 가능하다.
    public void method1() {
    	this.field = "Hello";
        this.method();
    }
    
    // 직접 객체를 생성해서 사용하는 것은 안됨
    public void method2() {
    	Parents a = new Parents(); // X
    	a.field = "World"; // X
        a.method(); // X
    }
}

profile
공부

0개의 댓글