[혼공자] chapter07 - 상속

나봉·2025년 2월 13일
0

13기 혼공자

목록 보기
11/14

07-1 상속

  • 부모가 자식에게 물려주는 행위
    => 객체 지향 프로그래밍에서도 부모 클래스의 멤버를 자식 클래스에게 물려줄 수 있음
    => 부모 클래스 = 상위 클래스, 자식 클래스 = 하위 클래스, 파생 클래스

클래스 상속

  • 프로그램에서는 자식이 부모를 선택
    => 자식 클래스 선언 시 어떤 부모 클래스를 상속받을 것인지 결정

  • 다중 상속 허용하지 않고 단일 상속 가능

  • 부모 클래스에서 private 접근 제한을 갖는 필드와 메서드는 상속 대상에서 제외

클래스 상속 예시

	class SportCar extends Car{
    
    }

부모 생성자 호출

  • 자식 객체를 생성하면 부모 객체가 먼저 생성된 후 자식 객체가 생성

1. 기본 생성자 호출

  • 자식 클래스의 생성자 호출 시 자동으로 부모 클래스의 기본 생성자가 호출

기본 생성자 호출 예시

class Parent {
    Parent() {
        System.out.println("부모 클래스의 기본 생성자 호출");
    }
}

class Child extends Parent {
    Child() {
        // 부모 클래스의 기본 생성자가 자동 호출됨
        System.out.println("자식 클래스의 생성자 호출");
    }
}

public class Test {
    public static void main(String[] args) {
        Child child = new Child();  // 자식 클래스의 생성자 호출
    }
}

=> 출력 내용
부모 클래스의 기본 생성자 호출
자식 클래스의 생성자 호출

2. 명시적 생성자 호출

  • super() 키워드를 사용하여 부모 클래스의 생성자를 호출
    => 부모 클래스의 생성자가 제공하는 인자와 일치하는 값을 전달

  • super()의 위치자식 클래스 생성자의 첫 줄에 위치

명시적 생성자 호출 예시

class Parent {
    Parent(String message) {
        System.out.println("부모 클래스의 생성자 호출: " + message);
    }
}

class Child extends Parent {
    Child() {
        // 부모 클래스의 생성자 호출 (매개변수가 있는 생성자)
        super("부모 클래스의 메시지");
        System.out.println("자식 클래스의 생성자 호출");
    }
}

public class Test {
    public static void main(String[] args) {
        Child child = new Child();  // 자식 클래스의 생성자 호출
    }
}

=> 출력 내용
부모 클래스의 생성자 호출: 부모 클래스의 메시지
자식 클래스의 생성자 호출

메서드 재정의(오버라이딩: Overriding)

  • 부모 클래스로 부터 상속된 일부 메서드는 자식 클래스에서 재정의

  • 메서드 재정의 시 부모 객체의 메서드는 숨겨지고, 재정의된 자식 메서드가 호출

1. 메서드 재정의 방법

  • 부모 메서드와 동일한 시그니처(리턴 타입, 메서드 이름, 매개 변수 목록)

  • 접근 제한을 더 강하게 재정의 할 수 없다.

  • 새로운 예외를 throws 할 수 없다.

2. 부모 메서드 호출

  • 자식 클래스에서 부모 클래스의 메서드를 재정의 하면, 부모 클래스의 메서드는 숨겨지고 재정의된 자식 메서드가 호출
    => but 자식 클래스 내에서 재정의된 부모 클래스의 메서드를 호출해야 한다면, super 키워드를 사용
class Parent {
	void method1() {}
    void method2() {}
}

class Child extends Parent{
	void method2() {} // 재정의
    void method3() {
    	method2(); // 재정의된 호출
        super.method2(); // 부모 메서드 호출
    }
}

final 클래스와 final 메서드

  • 클래스와 메서드 선언 시 final 키워드가 지정되면 상속과 관련

1. 상속할 수 없는 final 클래스

  • 최종적인 클래스가 되어 상속할 수 없는 클래스가 된다.
    => 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없다.

final 클래스 예시

	public final class String{} // 상속할 수 없는 클래스

2. 재정의할 수 없는 final 메서드

  • 최종적인 메서드가 되어 메서드 재정의 불가

final 메서드 예시

	public final void String{} // 재정의 불가한 메서드

07-2 타입 변환과 다형성

  • 사용 방법은 동일 하지만 다른 객체를 이용하여 다양한 실행결과가 나온다.

자동 타입 변환

  • 프로그램 실행 도중 자동적으로 타입 변환
    => 자식 클래스의 객체는 부모 클래스 타입으로 자동 변환
    => 상속 계층에서 상위 타입이라면 자동 타입 변환 가능

자동 타입 변환 예시

	class Animal{}
    
    class Cat extends Anilmal {}
    
    Cat cat = new Cat();
    Animal animal = cat; // cat은 Animal로 자동 타입 변환 이루어짐

필드의 다형성

  • 컴파일 타임에 결정되고, 참조 변수 타입에 맞는 필드가 사용
    => 자식 클래스에서 숨기더라도 부모 클래스 필드가 사용됨

매개 변수의 다형성

  • 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체뿐만 아니라 자식 객체까지도 매개값으로 사용 가능
    => 매개값으로 어떤 자식 객체가 제공되느냐에 따라 메서드의 실행결과가 다양해 진다.

  • 매개값의 자동 타입변환과 메서드 재정의를 이용하여 매개 변수의 다형성을 구현

강제 타입 변환

  • 부모 타입을 자식 타입으로 변환하는 것
    => 자식 타입이 부모 타입으로 자동 타입 변환된 후 다시 자식 타입으로 강제 변환
	class Parent{
    	String field1;
        void method1() {}
        void method2() {}
    }
    
    class Child extends Parent{
    	Strinf field2;
        void method3() {}
    }
    
    class ChildExample{
    	public static void main(String[] args) {
        	Parent parent = new Child();
            parent.field1 = "xxx";
            parent.method1();
            parent.method2();
            //parent.field2 = "yyy"; // 불가능
            //parent.method3(); // 불가능
            
            // 강제 타입 변환 후 가능
            Child child = (Child) parent;
            child.field2 = "yyy"; // 가능
            child.method3(); // 가능
        }
    }

객체 타입 확인

  • instanceof 연산자 : 어떤 객체가 어떤 클래스의 인스턴스인지 확인
    객체 타입 확인 예시
public void method(Parent parent) {
	if(parent instanceod Child) {
    	Child child = (Child) parent;
    }
}

07-3 추상 클래스

  • 클래스들의 공통적인 특성을 추출해서 선언한 클래스

  • 추상 클래스(부모 클래스)와 실체 클래스(자식 클래스)는 상속의 관계를 가지고 구현되어 실체 클래스는 추상 클래스의 모든 특성을 물려받고 추가적인 특성을 가짐

추상 클래스의 용도

1. 공통된 필드와 메소드의 이름을 통일
=> 실체 클래스에 반드시 존재해야 할 필드와 메서드 선언

2. 실체 클래스를 작성할 때 시간 절약
=> 공통된 내용은 물려받고, 다른 점만 선언

추상 클래스 선언

  • abstract 키워드를 붙여야 한다.

  • new 연산자를 이용하여 객체 만들수 없다.
    => 상속을 통해서 자식 클래스 만들기 가능

추상 클래스 선언 예시

package sec03.exam01;

public abstract class Phone { //  추상 클래스
	
	// 필드
	public String owner;
	
	// 생성자
	public Phone(String owner) {
		this.owner = owner;
	}
	
	// 메서드
	public void turnOn() {
		System.out.println("폰 전원을 켭니다.");
	}
	
	public void turnOff() {
		System.out.println("폰 전원을 끕니다.");
	}
}

추상 메서드와 재정의

  • 메서드의 선언만 통일하고 실행 내용은 실체 클래스마다 다를 경우 사용

  • abstract 키워드와 함께 메서드의 선언부만 있고 메서드 실행 내용인 중괄호{}가 없는 메서드

  • 실체 클래스는 반드시 추상 메서드를 재정의 하여야 함

추상 메서드 선언 , 재정의 예시

public abstract class Animal { // 추상 클래스

	public String kind;
	
	public void breathe() {
		System.out.println("숨을 쉽니다.");
	}
	
	public abstract void sound(); // 추상 메서드
}

public class Cat extends Animal {
	public Cat() {
		this.kind = "포유류";
	}

	@Override
	public void sound() { // 추상 메서드 재정의
		System.out.println("냐옹");
	}
}

0개의 댓글

관련 채용 정보