상속
은 객체지향 프로그래밍의 특성 중 한 가지로 상위 클래스(부모 클래스)의 멤버변수와 메서드를 하위클래스(자식 클래스)가 물려받는 기술을 의미한다.
자바에서 상속을 구현할 때는 extends
예약어를 사용한다. 예를 들어 Animal
이라는 클래스가 있고, Dog
라는 클래스가 있다고 생각해 보자. Animal
클래스가 Dog
클래스보다 일반적이고 포괄적인 개념을 다루므로 상위 클래스가 되고 Dog
클래스가 하위 클래스가 된다. 이것을 클래스 다이어그램으로 표현하면 이렇게 된다.
이처럼 상속을 받는 클래스에서부터 상속을 해주는 클래스로 화살표를 그린다. 일반적으로 생각하면 상속을 해주는 클래스로부터 상속을 받는 클래스한테 화살표가 갈 것 같은데 실제로는 반대방향이므로 주의해야한다!
이 관계를 코드로 나타내면 다음과 같다.
class Animal {
...
}
class Dog extends Animal {
...
}
protected
를 사용하여 상위 클래스 변수에 접근하기만약 상위 클래스에서 선언한 변수가 private
라면 외부 클래스에서는 모두 사용이 불가하므로 하위 클래스에서도 바로 사용할 수가 없게 된다. 하지만 외부클래스에서는 사용할 수 없지만 상속받은 하위 클래스에서는 사용할 수 있게 하는 접근제어자가 바로 protected
이다.
protected
로 선언한 변수나 메서드는 같은 패키지에 속해 있는 클래스나, 다른 패키지에 있더라도 해당 클래스를 상속받은 클래스의 접근을 허용한다.
상속이 이루어지는 과정에서 하위클래스가 생성될 때 상위 클래스의 생성자가 먼저 호출된다.
위에서 부모를 상속받는 자식 클래스는 부모의 멤버변수와 메서드를 사용할 수 있다고 했다. 그 이유가 바로 여기에 있다.
상위 클래스의 생성자가 먼저 호출되어 상위 클래스의 변수와 메서드가 메모리에 올라가야 하위 클래스들이 이를 메모리에서 가져와 사용할 수 있다.
그렇다면 어떻게 상위 클래스의 생성자가 먼저 호출될까?
이를 알기 위해서는 또 super()
라는 예약어를 알아야 한다.
super()
는 상위 클래스의 주소값을 가지고 있다.
Dog dog = new Dog();
로 Dog객체의 생성자를 부르면 컴파일러가 자동으로 super()
를 호출하여 상위 클래스의 디폴트 생성자가 호출된다.
class Dog extends Animal {
public Dog () {
super(); //컴파일러가 자동으로 추가한 코드
System.out.println("I'm dog"); //원래 생성자에 있던 코드
}
class Animal {
protected String name = "animal";
public Animal () { //디폴트 생성자
System.out.println("I'm animal);
}
}
public static void main(String[] args) {
Dog dog = new Dog();
}
그런데 위와 같은 디폴트 생성자가 아닌 매개변수를 받는 생성자는 자동으로 자동으로 호출되지 않는다. 따라서 명시적으로 호출을 해줘야한다.
super
는 상위 클래스의 멤버 변수나 메서드에 접근할 때도 사용한다. 예를들어 Dog
클래스에서 Animal
클래스의 name
이라는 변수를 바꾸는 changeName
함수를 작성한다고 하면 이렇게 작성할 수 있다.
class Dog extends Animal {
public Dog () {
super(); //컴파일러가 자동으로 추가한 코드
System.out.println("I'm dog"); //원래 생성자에 있던 코드
}
public void changeName() {
super.name = "dog";
}
}
Dog
클래스는 Animal
클래스를 상속받은 클래스이다. 따라서 Dog
은 Dog
형이면서 동시에 Animal
형이기도 하다. 그래서 Dog
클래스로 인스턴스를 생성할 때 이 인스턴스의 자료형을 Animal
형으로 클래스 형 변환하여 선언할 수 있다. (=upcasting)
Animal pup = new Dog();
Animal : 선언된 클래스형 (상위 클래스형)
Dog : 생성된 인스턴스의 클래스형 (하위 클래스형)
반대는 성립하지 않는다
그렇다면 형 변환된 pup이 가리키는 것은 무엇일까?
❕ 클래스가 형 변환이 되었을 때는 선언한 클래스형에 기반하여 멤버변수와 메서드에 접근할 수 있다.
따라서 pup이 가리킬 수 있는 변수와 메서드는 Animal클래스의 멤버들이다.