💡
class Animal에 bark( )메서드가 있다.
이 메서드는 "..."을 출력한다.
Animal -> bark( ) : "..."
💡
class Cat은 Animal의 서브클래스다.
bark( )를 오버라이딩 하여 "야옹"을 출력한다.
또한 고유 메서드인 play( )는 "혼자놀기"를 출력한다.
Cat -> bark( ) : "야옹" (오버라이딩)
Cat -> play( ) : "혼자놀기"
💡
class Dog은 Animal의 서브클래스다.
bark( )를 오버라이딩 하여 "멍멍"을 출력한다.
또한 고유 메서드인 tailing( )는 "꼬리흔들기"를 출력한다.
Dog -> bark( ) : "멍멍" (오버라이딩)
Dog -> tailing( ) : "꼬리흔들기"
Cat ob1 = new Cat( "해피" ) --> Cat자료형의 ob1객체 생성
Dog ob2 = new Dog( "뽀삐" ) --> Dog자료형의 ob2객체 생성
Animal a1 = ob1 --> Animal자료형의 a1 객체 생성
Animal a2 = ob2 --> Animal자료형의 a2 객체 생성
ob1.bark( ); --> "야옹"
ob1.play( ); --> "혼자놀기"
ob2.bark( ); --> "멍멍"
ob2.tailing( ) --> "꼬리흔들기"
a1.bark( ); --> "야옹"
a1.play( ); --> 에러
a2.bark( ); --> "멍멍"
a2.tailing( ) --> 에러
play( )와 tailing( )은 자료형이 각각 Cat, Dog일 때에만 사용이 가능한 메서드다. 따라서 각 고유의 메서드를 호출할 시 Animal자료형인 a1과 a2는 에러가 뜨게 된다.
이때 주목해야할 점은
Animal의 bark( )는 "..."인데 이렇게 출력되지 않고
각각 오버라이딩한 대로 잘 출력이 됨을 볼 수 있다.
서브클래스 객체를 슈퍼클래스로 참조하는 형태
Animal[ ] arr = { ob1, ob2 };
위 배열 arr는 Animal자료형을 담을 수 있는 배열이지만
Cat, Dog 자료형인 ob1과 ob2가 에러없이 잘 담긴다.
이것은 자료형이 슈퍼클래스로 자연스럽게 업캐스팅 되었기 때문이다.
arr [ 0 ].play ( x )
arr [ 1 ].play ( x )
arr [ 0 ].tailing ( x )
arr [ 1 ].tailing ( x )
자료형이 Animal로 바뀌어 서브클래스의 고유메서드 실행불가
arr [ 0 ].bark( ) = "야옹"
arr [ 1 ].bark( ) = "멍멍"
하지만 bark는 오버라이딩한 내용으로 실행
만약에 서브클래스의 고유 메서드를 사용하고 싶다면 강제형변환을 해줘야 한다.
Cat tmp1 = ( Cat ) arr[ 0 ]
tmp1.play( ) --> "혼자놀기"
이렇게 강제형변환을 통해 사용할 수 있다
만약에 배열에 담아둔 객체의 원래 자료형을 알 수 없어서 형변환이 어려운 경우 확인할 수 있는 2가지 방법이 있다.
클래스의 이름을 문자열로 반환하는 코드
( arr [ 0 ]의 클래스 이름을 받을 수 있다. )
앞쪽 객체의 자료형과 뒤쪽에 적은 클래스의 이름이 일치하는지 확인 후 boolean값 반환하는 코드
( arr [ 0 ]의 자료형이 Cat인지 확인후 같다면 true, 다르다면 false를 반환한다.)