클래스에서 자주 사용되는 상속의 개념에 대해 알아보자.


◆ 상속 (inheritance)

extension(확장)의 개념으로 다른 클래스의 속성을 사용할 수 있다.

  • 수정, 추가해서 새로운 클래스를 설계하는 기법.
    ( 단, 접근제한자가 private인 속성의 경우 상속 관계라 할지라도 접근이 불가능 하다. )
  • 상속받는 새로운 클래스 = 하위클래스, subclass, 자식클래스
  • 원본이 되는 클래스 = 상위클래스, superclass, 부모클래스



◆ 상속 받는 방법

클래스 끝에 extends 키워드를 붙여서 상속받을 클래스명을 써준다.

class Magic extends model.Unit{}

하위 클래스 객체를 생성하게 되면 상위 클래스 객체 또한 자동으로 생성된다. 즉, 상위클래스의 생성자가 먼저 호출된 후 하위 클래스의 생성자가 호출 된다.


◆ extends 활용

  1. extends는 단 하나의 class를 대상으로만 설정할 수 있음. (다중 상속X)
  2. 상속되어 설계된 class는 다른 class들의 super 가 될 수 있음.
  3. 모든 class 들이 전부 extends의 대상은 아님. (final class)
  4. 하위 클래스에 부모클래스와 같은 이름으로 되어있는 변수나 메서드가 있다면 자식 클래스의 것이 우선시 됨.
  5. 부모클래스의 메서드를 자식클래스에서 변형시키는 오버라이드를 하는 상황이 빈번함 다형성 이라는 장점이 있기 때문에.
    • 항상 되는 것은 아니고, 된다고 치더라도 시야는 최소한 유지해야 함.
    • final메서드는 오버라이드 할 수 없음.



◆ Object클래스

모든 클래스들의 최상위 클래스.
모든 클래스들은 Object클래스를 상속받기 때문에 hashCode(), toString() 메서드를 사용 할 수 있다.

  • toString()의 디폴트 설정 : 클래스명@해시코드메서드(16진수) 를 string형으로 반환
  • hashCode()의 디폴트 설정 : 객체 생성 시 위치 값을 int형 반환
    ▶ 대부분의 객체는 println으로 객체를 출력 할 경우 toString()메서드를 자동 호출시킴
    => toString메서드를 오버라이드 해서 사용한다면, 객체를 출력할 경우 오버라이드된 toString 결과가 나온다. 단, 반환형 String으로 같아야 한다.



◆ 오버라이드(Override)

오버라이드는 상위 클래스의 메서드와 같은 메서드를 재정의 하는 것이다. 즉, 이미 있는 메서드를 다른 기능으로 바꿔서 정의하는 것.



◆ 오버라이드 주의점

재정의(오버라이드) 하는 쪽의 메서드는 원본메서드의 접근제한레벨보다 낮으면 안 된다.

원본메서드가protected라면 오버라이드 되는 메서드의 접근제한자는 protected~public만 가능



◆ 오버라이드된 메서드 체크

오버라이드된 메서드 위에 @Override라는 주석을 달면, 오버라이드된 메서드는 오류가 발생하지 않고, 오버라이드가 되지 않은 메서드라면 오류가 발생한다.

@Override
public void toString(){
    System.out.println("오버라이드");
}


◆ 객체 값 캐스팅

객체 또한 형 변환(캐스팅)이 가능하다.
객체 값 캐스팅은 상속 또는 구현관계에서만 가능

  • 다운 캐스팅: 상위객체 -> 하위객체
  • 업 캐스팅: 하위객체 -> 상위객체
// Car Avante 상위 클래스  
Car c = new Car();
Avante a = new Avante();
(Car)a // 업캐스팅
(Avante)c // 다운캐스팅


( 주의 : 같은 클래스를 상속받았더라도 상속관계가 아니라면 캐스팅불가 ! - 컴파일 실패 )
▶ 상위객체 -> 하위객체로 변환 시 불가능한 경우 런타임에러가 발생 할 수 도 있다.
▶ 여러 단계로 걸친 상속관계에서 캐스팅할 시 많은 단계를 걸치는 캐스팅의 경우 런타임 에러가 발생할 수 있다.



◆ 객체 확인

a객체 instanceof b객체


a객체가 b객체와 동일한 상속관계클래스이면 true, 그렇지 않으면 false를 반환 (boolean반환)
=> 업 캐스팅, 다운캐스팅 등을 확인하기 위해 사용 (즉, 캐스팅 불가능한 객체끼리는 비교불가)



◆ 업 캐스팅을 이용한 메서드 호출

기본적으로 업 캐스팅을 하면 하위클래스의 메서드를 사용할 수 없지만, 오버라이드된 메서드들은 사용이 가능하다.
( 단, 이때 호출되는 메서드는 오버라이드(재정의)된 메서드)

  • 원래의 객체(new를 이용하여 생성한 객체)가 하위객체가 아닌 경우에는 하위객체의 오버라이드된 메서드 사용이 불가능하다.

  • 업 캐스팅 하여 사용하지 못했던 하위 메서드의 경우 다시 다운 캐스팅하여 사용이 가능하다.

    주의!
    (Circle)s.method(); (x)
    ((Circle)s).method(); (o)
    => .의 우선순위가 높기 때문에 괄호가 더 필요하다.

다운 캐스팅하여 하위클래스의 메서드를 사용할 수 있지만 원래의 객체가 하위클래스객체가 아닌 상위클래스의 객체였다면 다운 캐스팅하더라도 사용이 불가능하다 (단, 문법상 오류는 아님, 런타임에러)

상위클래스 s = new 하위클래스();  
((하위클래스)s).하위메서드();  // (o)가능

상위클래스 s2 = new 상위클래스();
((하위클래스)s2).하위메서드; // (x)불가능