[JAVA] 상속(extends) 개념, 상속 클래스 생성과 형 변환

GyeongEun Kim·2021년 6월 16일
0
post-custom-banner

상속이란

상속은 객체지향 프로그래밍의 특성 중 한 가지로 상위 클래스(부모 클래스)의 멤버변수와 메서드를 하위클래스(자식 클래스)가 물려받는 기술을 의미한다.

자바에서 상속을 구현할 때는 extends 예약어를 사용한다. 예를 들어 Animal이라는 클래스가 있고, Dog라는 클래스가 있다고 생각해 보자. Animal클래스가 Dog클래스보다 일반적이고 포괄적인 개념을 다루므로 상위 클래스가 되고 Dog클래스가 하위 클래스가 된다. 이것을 클래스 다이어그램으로 표현하면 이렇게 된다.

이처럼 상속을 받는 클래스에서부터 상속을 해주는 클래스로 화살표를 그린다. 일반적으로 생각하면 상속을 해주는 클래스로부터 상속을 받는 클래스한테 화살표가 갈 것 같은데 실제로는 반대방향이므로 주의해야한다!

이 관계를 코드로 나타내면 다음과 같다.

class Animal {
...
  	}
	
class Dog extends Animal {
...
  }

protected를 사용하여 상위 클래스 변수에 접근하기

만약 상위 클래스에서 선언한 변수가 private라면 외부 클래스에서는 모두 사용이 불가하므로 하위 클래스에서도 바로 사용할 수가 없게 된다. 하지만 외부클래스에서는 사용할 수 없지만 상속받은 하위 클래스에서는 사용할 수 있게 하는 접근제어자가 바로 protected이다.

protected로 선언한 변수나 메서드는 같은 패키지에 속해 있는 클래스나, 다른 패키지에 있더라도 해당 클래스를 상속받은 클래스의 접근을 허용한다.

상속에서의 클래스 생성과 super

상속이 이루어지는 과정에서 하위클래스가 생성될 때 상위 클래스의 생성자가 먼저 호출된다.

위에서 부모를 상속받는 자식 클래스는 부모의 멤버변수와 메서드를 사용할 수 있다고 했다. 그 이유가 바로 여기에 있다.
상위 클래스의 생성자가 먼저 호출되어 상위 클래스의 변수와 메서드가 메모리에 올라가야 하위 클래스들이 이를 메모리에서 가져와 사용할 수 있다.
그렇다면 어떻게 상위 클래스의 생성자가 먼저 호출될까?

이를 알기 위해서는 또 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클래스를 상속받은 클래스이다. 따라서 DogDog형이면서 동시에 Animal형이기도 하다. 그래서 Dog클래스로 인스턴스를 생성할 때 이 인스턴스의 자료형을 Animal형으로 클래스 형 변환하여 선언할 수 있다. (=upcasting)

Animal pup = new Dog();

Animal : 선언된 클래스형 (상위 클래스형)
Dog : 생성된 인스턴스의 클래스형 (하위 클래스형)

반대는 성립하지 않는다

그렇다면 형 변환된 pup이 가리키는 것은 무엇일까?

❕ 클래스가 형 변환이 되었을 때는 선언한 클래스형에 기반하여 멤버변수와 메서드에 접근할 수 있다.

따라서 pup이 가리킬 수 있는 변수와 메서드는 Animal클래스의 멤버들이다.

profile
내가 보려고 쓰는 글
post-custom-banner

0개의 댓글