클래스에서 자주 사용되는 상속의 개념에 대해 알아보자.
◆ 상속 (inheritance)
extension(확장)의 개념으로 다른 클래스의 속성을 사용할 수 있다.
- 수정, 추가해서 새로운 클래스를 설계하는 기법.
( 단, 접근제한자가 private인 속성의 경우 상속 관계라 할지라도 접근이 불가능 하다. ) - 상속받는 새로운 클래스 = 하위클래스, subclass, 자식클래스
- 원본이 되는 클래스 = 상위클래스, superclass, 부모클래스
◆ 상속 받는 방법
클래스 끝에 extends 키워드를 붙여서 상속받을 클래스명을 써준다.
하위 클래스 객체를 생성하게 되면 상위 클래스 객체 또한 자동으로 생성된다. 즉, 상위클래스의 생성자가 먼저 호출된 후 하위 클래스의 생성자가 호출 된다.
◆ extends 활용
- extends는 단 하나의 class를 대상으로만 설정할 수 있음. (다중 상속X)
- 상속되어 설계된 class는 다른 class들의 super 가 될 수 있음.
- 모든 class 들이 전부 extends의 대상은 아님. (final class)
- 하위 클래스에 부모클래스와 같은 이름으로 되어있는 변수나 메서드가 있다면 자식 클래스의 것이 우선시 됨.
- 부모클래스의 메서드를 자식클래스에서 변형시키는 오버라이드를 하는 상황이 빈번함 다형성 이라는 장점이 있기 때문에.
- 항상 되는 것은 아니고, 된다고 치더라도 시야는 최소한 유지해야 함.
- final메서드는 오버라이드 할 수 없음.
◆ Object클래스
모든 클래스들의 최상위 클래스.
모든 클래스들은 Object클래스를 상속받기 때문에 hashCode(), toString() 메서드를 사용 할 수 있다.
- toString()의 디폴트 설정 : 클래스명@해시코드메서드(16진수) 를 string형으로 반환
- hashCode()의 디폴트 설정 : 객체 생성 시 위치 값을 int형 반환
▶ 대부분의 객체는 println으로 객체를 출력 할 경우 toString()메서드를 자동 호출시킴
=> toString메서드를 오버라이드 해서 사용한다면, 객체를 출력할 경우 오버라이드된 toString 결과가 나온다. 단, 반환형 String으로 같아야 한다.
◆ 오버라이드(Override)
오버라이드는 상위 클래스의 메서드와 같은 메서드를 재정의 하는 것이다. 즉, 이미 있는 메서드를 다른 기능으로 바꿔서 정의하는 것.
◆ 오버라이드 주의점
재정의(오버라이드) 하는 쪽의 메서드는 원본메서드의 접근제한레벨보다 낮으면 안 된다.
원본메서드가protected라면 오버라이드 되는 메서드의 접근제한자는 protected~public만 가능
◆ 오버라이드된 메서드 체크
오버라이드된 메서드 위에 @Override라는 주석을 달면, 오버라이드된 메서드는 오류가 발생하지 않고, 오버라이드가 되지 않은 메서드라면 오류가 발생한다.
◆ 객체 값 캐스팅
객체 또한 형 변환(캐스팅)이 가능하다.
객체 값 캐스팅은 상속 또는 구현관계에서만 가능
- 다운 캐스팅: 상위객체 -> 하위객체
- 업 캐스팅: 하위객체 -> 상위객체
( 주의 : 같은 클래스를 상속받았더라도 상속관계가 아니라면 캐스팅불가 ! - 컴파일 실패 )
▶ 상위객체 -> 하위객체로 변환 시 불가능한 경우 런타임에러가 발생 할 수 도 있다.
▶ 여러 단계로 걸친 상속관계에서 캐스팅할 시 많은 단계를 걸치는 캐스팅의 경우 런타임 에러가 발생할 수 있다.
◆ 객체 확인
a객체 instanceof b객체
a객체가 b객체와 동일한 상속관계클래스이면 true, 그렇지 않으면 false를 반환 (boolean반환)
=> 업 캐스팅, 다운캐스팅 등을 확인하기 위해 사용 (즉, 캐스팅 불가능한 객체끼리는 비교불가)
◆ 업 캐스팅을 이용한 메서드 호출
기본적으로 업 캐스팅을 하면 하위클래스의 메서드를 사용할 수 없지만, 오버라이드된 메서드들은 사용이 가능하다.
( 단, 이때 호출되는 메서드는 오버라이드(재정의)된 메서드)
-
원래의 객체(new를 이용하여 생성한 객체)가 하위객체가 아닌 경우에는 하위객체의 오버라이드된 메서드 사용이 불가능하다.
-
업 캐스팅 하여 사용하지 못했던 하위 메서드의 경우 다시 다운 캐스팅하여 사용이 가능하다.
주의!
(Circle)s.method(); (x)
((Circle)s).method(); (o)
=> .의 우선순위가 높기 때문에 괄호가 더 필요하다.
다운 캐스팅하여 하위클래스의 메서드를 사용할 수 있지만 원래의 객체가 하위클래스객체가 아닌 상위클래스의 객체였다면 다운 캐스팅하더라도 사용이 불가능하다 (단, 문법상 오류는 아님, 런타임에러)