- 상속 관계를 결정하는 클래스란 뭘까?
- 생성자도 상속되는 걸까?
- 아래 사진에서 A와 B 중 어떤 것이 부모클래스일까?
객체지향프로그래밍에는 4가지 중요한 특징이 있다. 추상화, 상속, 다형성, 캡슐화인데 지금은 그 중 '상속'에 대해 얘기해보려고 한다.
상속은 기존 클래스에 기능을 추가하거나 재정의하여 새로운 클래스를 정의하는 것을 의미한다.
예를 들면,
'아이폰'과 '갤럭시'라는 휴대폰을 클래스로 구현한다고 생각해보자.
이 둘을 각각 구현하려고 하면 생각보다 겹치는 기능이 존재한다는 것을 알 수 있다.
그 이유는 두 클래스 모두 '스마트폰'이라는 공통 분모를 갖고 있기 때문이다.
그렇다면, '스마트폰' 클래스를 먼저 만들어놓고 이를 이용해서 '아이폰'과 '갤럭시' 클래스에서 다른 부분만 각각 구현하면 되지 않을까?
이런 생각을 객체 지향에 적용한 개념이 바로 '상속'이다.
그리고 이 예제에서 부모 클래스는 '스마트폰', 자식 클래스는 '아이폰'과 '갤럭시'가 된다.
결론부터 말하자면, 자바에서 상속은 자식 클래스가 결정한다.
사실 부모 클래스는 자신의 클래스를 누가 상속받았는지의 여부도 알 방법이 없다.
부모 클래스는 그냥 평범한 클래스인데, 자식 클래스가 'extends'라는 키워드를 통해 부모를 선택한다.
// Phone 클래스(부모)
package phone;
public abstract class Phone {
private boolean power;
public abstract void printLogo();
public void turnOn(){
printLogo();
power = true;
System.out.println("휴대폰이 켜졌습니다.");
}
public void turnOff(){
power = false;
System.out.println("띠로리로");
}
}
// Galaxy 클래스(자식)
package phone;
public class Galaxy extends Phone{
@Override
public void printLogo() {
System.out.println("*** Samsung ***");
}
}
// Iphone 클래스(자식)
package phone;
public class Iphone extends Phone{
@Override
public void printLogo() {
System.out.println("@@@ Apple @@@");
}
}
위 코드에서 자식 클래스에서 'extends' 키워드를 통해 부모를 상속받는 것을 알 수 있다.
그리고 두 자식 클래스 모두 부모로부터 printLogo, turnOn, turnOff라는 메서드를 상속 받는다.
자식 클래스는 부모 클래스의 메서드를 상속받는다. 물론 위의 printLogo처럼 상속받고 재정의 할 수도 있지만, 그렇지 않으면 부모 클래스의 메서드를 그대로 사용할 수 있다.
그렇다면, 생성자는?
이것도 결론부터 얘기하자면, 생성자는 상속이 불가능하다. 물론 자식 클래스에서 인스턴스를 생성할 때, 부모 클래스의 기본 생성자를 자동으로 호출하긴 한다. 하지만, 매개변수를 갖는 부모 클래스의 생성자는 자동으로 호출되지 않는다. 따라서 호출하고 싶다면, 자식 생성자의 첫 줄에 super() 키워드를 추가해서 명시적으로 부모 생성자를 호출해야 한다.
이렇게 호출을 명시적으로 해야 한다는 것은, 상속받지 못한다는 것을 의미한다.
위에서 언급한 대로, 자식 클래스는 부모 클래스를 확장해서 구현한다.
이 얘기는 즉, 더 넓은 것이 자식 클래스라는 것이고 위 사진에서는 더 넓은 B가 자식 클래스가 된다.
어쩌면 Phone보다 Iphone이 더 구체화 된 것이니까 A가 자식 아니냐고 생각할 수도 있지만, 적어도 나는 컴퓨터 언어로 접근했을 때 B인 것이 명확해서 B라고 생각한다.