본문 바로가기

플밍 is 뭔들/JAVA

[자바] 상속

※ 상속이란
기존 클래스를 재사용하여 새로운 클래스를 작성하는 것


※ 상속방법
class Child extends Parent{
    ...
}


※ 상속의 특징
생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
자손 클래스의 개수는 조상 클래스보다 항상 같거나 많다.
자손 클래스는 부모클래스의 기능 및 변수 + 자손 클래스의 기능 및 변수 이므로 부모클래스를 포함하는 범위에 속한다.



※ 상속 예시
public class Animal {
      int age;
      
      public Animal(){
            this(7);
      }
      
      public Animal(int age){
            this.age = age;
      }
      public void eat(){
            System.out.println("[Animal 클래스] 먹는다. 냠냠");
      }

}


public class Cat extends Animal{}


public class main {
      public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            Cat cat = new Cat();
            System.out.println(cat.age);
            
            cat.eat();
            
      }
}

----------------------------------------------------------------------------------------------
결과 

7
[Animal 클래스] 먹는다. 냠냠


위에 보다시피 Cat 클래스에는 아무것도 구현이 되어 있지 않다. 
하지만 Animal을 상속 받았기 때문에 Cat클래스의 인스턴스인 cat에서 Animal 클래스의 eat()함수와 age 변수를 그대로 사용 할 수 있다.
그리고 Cat 클래스에 따로 변수와 메서드를 정의하면 그 메서드와 변수는 cat인스턴스에서만 사용 할 수 있다.
그렇기 때문에 Animal클래스를 상속받은 Cat클래스의 인스턴스들은 Animal클래스의 기능 및 변수를 포함하며 Cat만의 기능과 변수가 있다. 즉 Animal클래스에서 더 확장되었다.


※ super
super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조한다. 하지만 상속받은 조상의 멤버도 자손 클래스 자신의 멤버이므로 super대신 this를 써도 같다. 하지만 자손의 멤버와 조상으로부터 상속받은 멤버를 구분하기위해 사용한다. 
그리고 상속받은 메서드를 확장시킬때도 사용할 수 있다.
this와 마찬가지로 super는 인스턴스와 상관없는 static 메서드에서는 사용할 수 없다.


※ super 사용 예시
public class Animal {
      int age;
      
      public Animal(){
            this.age=7;
      }
      public void eat(){
            System.out.println("[Animal 클래스] 먹는다. 냠냠");
      }
      
}


public class Cat extends Animal{

      int age;
      
      public Cat(){
            //자손의 age = 조상의 age + 2
            this.age = super.age + 2;
      }
      
      @Override
      public void eat(){
            
            super.eat();
            //조상 클래스의 eat()메서드를 확장
            System.out.println("[Cat 클래스] 먹는다. 냠냠");
      }
}

----------------------------------------------------------------------------------------------
결과 

9
[Animal 클래스] 먹는다. 냠냠
[Cat 클래스] 먹는다. 냠냠


여기서 잘 봐야 할점은 메서드 오버라이드를 할 때 super.eat()을 하는 것이다. 만약 super.eat()을 지우고

      @Override
      public void eat(){
            System.out.println("[Cat 클래스] 먹는다. 냠냠");
      }

위처럼 eat() 메서드를 정의하면  결과에서는 '[Animal 클래스] 먹는다. 냠냠' 을 출력하지 않는다.
조상의 메서드와 이름은 같지만 기능이 완전 다른 메서드를 만드는 것과 같다.
그렇기 때문에 조상메서드의 기능에서 확장하여 사용하고 싶다면 오버라이드할 부분에 super.메서드();를 정의해 줘야한다.


※ 상속과 생성자
상속을 받았어도 자손의 생성자는 부모의 생성자와는 다르다. 그렇기 때문에 자손클래스의 생성자는 상황에 맞게 생성자를 정의해 줘야한다.
그리고 조상의 생성자를 확장하여 사용하고 싶다면 자손의 생성자 안에 super();를 선언해주면 된다.


※ 상속은 언제 사용해야 할까?
사람과 고양이 모두 보고 듣고 먹고 중복되는 기능들이 있다.
하지만 사람 클래스에는 동물클래스를 상속하면 안된다 하지만 고양이 클래스에는 동물클래스를 상속할 수 있다.
상속은 개념적으로 IS-A(~은 ~이다) 관계일때 사용해야 한다.

만약 언제 상속해야 될지 잘 모르겠다면 아래 예시처럼 단어를 넣어보면 된다.
사람은 동물이다. 라는 명제는 거짓이지만 고양이는 동물이다.라는 명제는 참이다.
그렇기 때문에 동물클래스는 사람클래스보단 고양이클래스에 상속을 해야한다.

그리고 또 다른 예로는 DMB와 핸드폰을 생각할 수 있다.
핸드폰에는 DMB기능을 모두 포함하고 있다. 간단히 생각해서 DMB클래스를 핸드폰 클래스에 상속을 해버리면 핸드폰 객체에서 DMB의 기능을 모두 사용할 수 있다고 생각 할 수 있지만 핸드폰은 DMB다 라는 명제는 거짓이다. 
그렇기 때문에 핸드폰 클래스 안에서 DMB의 모든 기능을 넣고싶을때는 핸드폰 클래스 안에 DMB클래스의 객체를 만들어 사용하는건 괜찮지만 DMB를 상속받는것은 안된다.

그러니 우리는 상속을 사용하기전에 핸드폰과 DMB의 관계처럼 단순 포함관계(HAS-A)인지 상속관계(IS-A)인지 잘 확인해보고 사용해야 할 것이다.







'플밍 is 뭔들 > JAVA' 카테고리의 다른 글

[자바] 다형성 (Polymorphism)  (0) 2017.09.18
[자바] 제어자(Modifier)  (0) 2017.09.18
[자바] 오버로딩 / 오버라이딩  (0) 2017.09.11
[자바] 클래스  (0) 2017.09.11
JVM(자바가상메모리)의 메모리구조  (0) 2017.09.11