상속 구조를 왜 사용해야 되는지 생각해 보자 (동작 측면에서)
설계자와 사용자가 다를 때 : (소스코드는 숨기고 중간에 인터페이스를 사용해서 코드를 사용할 수 있게) 상속을 사용해 설계를 해서 배포해야 한다.
(소스코드가 없고 실행코드(.class 파일)만 있으면 코드를 사용하기가 너무 어렵기 때문)
사람 - 리모콘 - TV 처럼 -> TV의 구조를 몰라도 리모콘으로 TV를 구동시킬 수 있다. (리모콘 : 부모, TV : 자식)
-> 자식의 동작 방식을 몰라도 부모를 이용해 자식을 구동할 수 있다.
상속에서는 부모 클래스를 어떻게 잘 활용하느냐가 중요하다. -> 하나를 통해 여러 자식을 컨트롤 할 수 있기 때문
Upcasting(업캐스팅) : 부모가 자식을 가리키는 객체생성 방법
// Upcasting
Animal x = new Dog();
x.eat();
Animal y = new Cat();
y.eat();
// 이대로라면 원하는 결과를 얻을 수는 없다.
상속 체이닝
super()
메서드의 재정의(Override)가 필요한 이유? 원하는 결과를 얻을 수 있다.
Override (재정의)
동적 바인딩
메서드가 재정의되면 부모의 메서드는 그림자로 취급된다. (무시됨)
Upcasting(업캐스팅, 자동형변환)
Downcasting(다운캐스팅, 강제형변환)
Animal은 Dog, Cat에게 동일한 메시지를 보낸다. (메서드를 호출한다.)
-> 반응이 다르다 (다형성)
먹어라. -> Dog은 개처럼 먹고 Cat은 고양이처럼 먹는다.
Downcasting(다운캐스팅)