1. 다형성 (Polymorphism)
하나의 객체(Object) 혹은 메서드가 여러가지 타입을 가질 수 있는 것을 말한다.
자바에서 다형성은 한 타입의 참조 변수를 통해 여러 타입 객체를 참조할 수 있도록 하는 것이다.
class Phone{
void sendMessage() {}
void sendCall() {}
}
class IPhone extends Phone {
void siri() {}
void useAppleStore() {}
}
- Phone 클래스와 IPhone는 상속관계를 맺고 있다.
- Phone 클래스 : 메시지/전화 송신
- IPhone 클래스 : 시리 실행, 애플스토어 실행 메소드
Phone ph = new Phone();
IPhone iPh = new IPhone();
다형성을 공부하기 전까지 동일한 클래스 타입의 클래스로 객체를 생성해 사용했다.
// 부모 타입의 참조변수로 자식 객체 생성
Phone ph = new IPhone();
그렇지만 만약 부모 자식 상속 관계에 있으면 다음과 같이 부모타입으로 자식 클래스 타입을 받아 초기화 할 수 있다.
이때 ph는 일반 휴대폰이라 아이폰에 있는 시리나 애플스토어 기능은 조작하지 못한다.
그러나 기본적인 기능은 아이폰에서도 사용이 가능하다.
→ 부모의 참조 변수로 자식 클래스를 다루면 부모 클래스에 있는 멤버와 메서드만 사용이 가능하다.
→ 반대의 경우로 자식의 참조 변수로 부모의 객체를 생성하면 컴파일 에러가 발생한다.
IPhone iph = (IPhone) ph;
만약 자식 객체인 아이폰의 시리, 애플스토어 기능을 사용하고 싶다면 다시 자식 타입으로 강제 타입변환을 하면 된다.
But, 무조건 강제 타입변환을 할 수 있는 것은 아니다.
자식 타입 객체가 부모 타입으로 자동 타입 변환된 후 다시 자식 타입으로 변환될 때에만 강제 타입 변환이 가능하다.
사용할 멤버도 줄어드는데 왜 다형성이 이득인가 ?
다형성은 부모-자식 관계일 때, 부모를 상속받은 클래스가 많을 때 그 빛을 볼 수 있다.
과일 클래스들을 배열에 담아 자주 조회하거나 꺼내야 하는 일이 생긴다면 어떻게 해야 할까요?
if 각 과일 클래스들이 상속을 받지 않았다고 가정한다면
Apple[] apple = new Apple[3];
Banana[] banana = new Banana[3];
Orange[] orange = new Orange[3];
apple[0] = new Apple();
banana[0] = new Banana();
orange[0] = new Orange();
각 과일 별로 배열을 생성하고, 각 배열마다 과일의 객체를 담아 주어야한다.
사과, 바나나, 오렌지는 공통분모가 있다. 바로 과일이라는 특징을 가지고 있다.
각 과일 클래스들이 Fruit 클래스를 모두 상속받는다면 코드를 훨씬 유연하게 개선할 수 있다.
Fruit[] fruitArr = new Fruit[10];
fruitArr[0] = new Apple();
fruitArr[1] = new Banana();
fruitArr[2] = new Orange();
(1) Instanceof
- 객체 타입을 확인하는 연산자로 {대상객체} instanceof {클래스 이름}과 같은 형태로 사용
- 형변환 가능 여부를 확인하며 boolean으로 결과를 반환한다.
- 주로 상속관계에서 부모 객체인지 자식 객체인지 확인하는데 사용된다.
// 다형성
class Parent { }
class Child extends Parent { }
class Brother extends Parent { }
public class Main {
public static void main(String[] args) {
Parent pc = new Child(); // 다형성 허용 (자식 -> 부모)
Parent p = new Parent();
System.out.println(p instanceof Object); // true 출력
System.out.println(p instanceof Parent); // true 출력
System.out.println(p instanceof Child); // false 출력
Parent c = new Child();
System.out.println(c instanceof Object); // true 출력
System.out.println(c instanceof Parent); // true 출력
System.out.println(c instanceof Child); // true 출력
}
}
+ 내 언어로 표현한 다형성 .. 다음에 헷갈리면 보자 !
내가 이해한 바는 다형성은 공통의 것을 뽑아 사용할 수 있기 위함
그런데 자식 클래스의 정의가 이루어지지 않은 시점에서 여러 클래스들의 공통적인 것들만 뽑아 하나의 클래스로 먼저 사용하기 위해 다형성을 이용함으로 이해하였다.
하지만 다형성을 이용한 업캐스팅은 부모클래스의 멤버만 사용가능 하다. 만약 자식 클래스의 멤버를 사용하고 싶다면 다운 캐스팅을 통해 사용할 수 있다.
+ 출처
2. 추상 클래스
public abstract class 추상클래스명 {
}
- 추상 클래스는 자식 클래스에 상속되어 자식 클래스에 의해서만 완성될 수 있다.
- 추상 클래스는 여러개의 자식 클래스들에서 공통적인 필드나 메서드를 추출해서 만들 수 있다.
(1) 추상 메서드
- 추상 메서드는 아직 구현되지 않은 미완성된 메서드이다.
- abstract 키워드를 사용하여 추상 메서드를 선언할 수 있다.
public abstract class 추상클래스명 {
abstract 리턴타입 메서드이름(매개변수, ...);
}
- 추상 메서드는 일반적인 메서드와 다르게 블록{}이 없다. → 정의만 할 뿐, 실행내용은 가지고 있지 않다.
(2) 추상 클래스 상속
추상 메서드는 extends 키워드를 사용하여 클래스에서 상속된다.
public class 클래스명 extends 추상클래스명 {
@Override
public 리턴타입 메서드이름(매개변수, ...) {
// 실행문
}
}
- 상속받은 클래스에서 추상 클래스의 추상 메서드는 반드시 오버라이딩 되어야 한다.
'TIL' 카테고리의 다른 글
240429 TIL (0) | 2024.04.30 |
---|---|
240426 TIL : 계산기 (0) | 2024.04.26 |
240424 TIL 3일차 (0) | 2024.04.24 |
240423 TIL 2일차 (0) | 2024.04.24 |
TIL 1일차 : CPU와 메모리 (0) | 2024.04.19 |