다형성(polymorphism): 객체 사용 방법 또는 코드는 동일하나 실행 결과가 다양하게 나오는 성질. 하나의 객체가 여러개의 자료형 타입을 가질 수 있는 것.
메소드 재정의와 클래스 타입 변환으로 구현한다.
장점: 유사한 클래스가 추가되는 경우 유지보수에 용이하고 각 자료형마다 다른 메소드를 호출하지 않으므로 코드가 절약된다.
클래스 타입 변환에는 자동 타입 변환, 강제 타입 변환이 있다
먼저 다시 한번 정리하면 상속을 받은 클래스는 부모 객체를 먼저 호출한다. 따라서 밑에 기술한 클래스 타입 변환이 일어날 때, 객체 변수들이 참조하는 주소는 변하지 않는다.
1. 자동 타입 변환(Promotion, Up Casting, 묵시적) - 자식 인스턴스가 부모 클래스 타입의 변수에 담기는 것이다.
여기서 새로운 부모 타입 변수는 본래 자식 객체의 주소를 갖게 된다.
예를 들어 Animal이라는 클래스를 상속 받은 Cat 이라는 클래스가 있을 때, 다음과 같은 방법으로 자동 타입 변환할 수 있다.
부모 타입 변수 = 자식 타입 변수; 또는 부모 타입 변수 = new 자식타입();
Cat cat = new Cat();
Animal animal = cat; // animal은 부모 타입 변수이지만, 자식 객체의 주소를 참조함
또는
Animal animal = new Cat();
자동 타입 변환은 바로 위 부모가 아니더라도, 상위 계층의 관계를 갖는 클래스라면 자동 타입 변환이 가능하다.
부모 타입으로 자동 타입 변환 후에는 부모 클래스의 멤버만 접근이 가능하지만, 예외적으로 자식 클래스에서 부모 클래스의 메소드를 재정의 한 것이 있다면 재정의된 자식 클래스의 메소드가 호출 된다.(메소드 재정의를 통한 다형성) -> 자바는 인스턴스의 메소드가 호출된다.
- 자바의 모든 메소드는 가상 메소드이다. 그리고 메소드의 이름과 메소드의 주소가 매핑된 가상 메소드 테이블이 있다.
- 메소드의 이름은 컴파일 되면, 그 자체가 주소가 된다. 오버로딩, 오버라이딩 되면 메소드의 이름이 같아도 컴파일 되면 다른 주소를 갖는다.
- 상속 관계에서 하위 클래스가 재정의한 메소드는 내용이 달라 당연히 다른 주소를 갖는다. 이 때, 업캐스팅된 객체의 메소드를 호출한다면 클래스 타입을 따라가지 않고 생성된 인스턴스 타입에 기반에 메소드를 호출한다. 따라서 하위 클래스에서 메소드를 호출한다.
- 재정의 되지 않은 메소드는 상위 클래스와 같은 주소를 참조한다.
클래스의 필드 부분을 부모 관계를 갖는 클래스들로 선언할 때 필드의 다형성을 갖게 되고
매개 변수를 부모 관계를 갖는 클래스들로 선언할 때 매개 변수의 다형성을 갖는다.
추가적으로 자동 타입 변환을 통해 그룹화할 수 있다.
Animal c = new Cat();
Animal d = new Dog();
Animal h = new Horse();
// 동물 배열 - 고양이, 개, 말
Animal[] animals = { c, d, h };
//또는 명시적으로 업캐스팅 하지 않아도 됨.
dog = new Dog();
cat = new Cat();
horse = new Horse();
Animal[] ani = {dog, cat, horse};
2. 강제 타입 변환(Casting, 명시적) - 부모 타입의 객체가 자식 타입의 객체로 타입을 바꾸는 것이다. 단, 여기서의 부모 타입 객체는 본래 자식 객체이나 자동 타입 변환으로 부모 타입으로 바뀐 객체만 가능하다. 따라서 본래 부모 객체였던 것은 자식 타입으로 강제 타입 변환될 수 없다.
Parent pa = new Child();
Child ch = (Child)parent;
//가능
Parent pa = new Parent();
child ch = (Child)pa;
//불가능, 에러 발생
당연히 원래대로 자식 타입으로 돌아가면, 자식 필드와 메소드를 사용한다. 또한 상속 받은 자식 클래스니까 부모 메소드도 사용 가능하다.
컴파일 에러가 발생하지 않지만, 강제 타입 변환이 안되면 ClassCastException이 발생한다. 그래서 instanceof 연산자로 어느 클래스의 객체인지 확인해야 한다.
instanceof 연산자는 형변환된 타입이 아닌 생성된 인스턴스의 원래 클래스 타입과 비교한다.
클래스 타입의 객체가 맞다면 true, 그렇지 않으면 false를 반환한다. if문과 함께 사용하여 안전하게 Casting할 수 있다.
boolean result = 객체 instanceof 클래스 타입
'study > java' 카테고리의 다른 글
자바/JAVA 인터페이스 - 타입 변환 다형성 (0) | 2021.01.05 |
---|---|
자바/JAVA 인터페이스 정리 (0) | 2021.01.05 |
자바/JAVA 추상 클래스, 추상 메소드, 템플릿 메소드 (0) | 2021.01.04 |
자바/JAVA 객체지향 관련 정리 (0) | 2020.12.28 |
자바/JAVA 공부 정리 (0) | 2020.12.28 |