다형성(polymorphism)
객체지향에서 다형성이란 "여러가지 형태를 가질 수 있는"이란 뜻이다.
자바에서는 상위 클래스 타입의 참조변수로 하위 클래스의 인스턴스를 참조할 수 있도록 하는 것이다.
class Animal{
void run(){System.out.println("달리자");}
}
class Cat extends Animal{
void eat(){System.out.println("츄르먹자");}
}
class Polymorphism{
public static void main(String[] args) {
Animal cat = new Cat();
cat.run();
// cat.eat(); error
}
}
실제 생성된 인스턴스는 Cat 타입이지만 Animal 타입으로 참조되었다.
이렇게 생성된 인스턴스는 Cat 타입의 멤버를 모두 사용하지 못하고 Animal 타입의 멤버만 사용가능하다.
반대로 하위 클래스 타입의 참조변수로 상위 클래스의 인스턴스를 참조할 수 없다.
하위 클래스 타입이 요구하는 정보를 상위 클래스에서 모두 제공하지 못하기 때문이다.
Cat cat = new Animal(); //error
이처럼 여러 타입을 가질 수 있는 다형성을 사용하여 유연하고 확장성이 있으며 유지보수가 편리한 프로그램을 만들 수 있다.
기본 변수와 같이 참조형 변수도 상속관계에 있는 클래스 사이에서 형변환이 가능하다.
Upcasting(업캐스팅)
upcasting : 하위클래스 ➡️ 상위클래스
업캐스팅은 하위 클래스의 객체를 상위 클래스로 형변환 하여 사용하는 것으로 형변환 생략이 가능하다.
Downcasting(다운캐스팅)
downcasting : 상위클래스 ➡️ 하위클래스
다운캐스팅은 상위 클래스에서 하위클래스로 형변환하는 것으로 명시적 형변환을 해주어야한다.
Cat cat = (Cat) new Animal();
다운캐스팅 시에 컴파일 타임에는 에러가 발생하지 않지만 런타임에서는 에러가 발생한다.
컴파일 시에는 참조변수간의 타입만 체크를 하지만 런타임 시에 생성 된 인스턴스의 타입이 일치하지 않기 때문이다.
Instanceof 연산자
instanceof 연산자를 사용해서 참조변수가 형변환이 가능지 확인할 수 있다.
조건문에 주로 사용되며 instanceof의 왼쪽에는 참조변수명을 오른쪽에는 타입을 넣으면 boolean 타입으로 변환 가능 여부를 리턴한다.
void checkCasting(Car car){
if (car instanceof SportsCar){
SportsCar sportscar = (SportsCar)car;
} else if (car instanceof MiniCar){
MiniCar minicar = (MiniCar)car;
}
}
Abstract Class (추상 클래스)
추상 클래스는 미완성 설계도처럼 완성되지 않은 메서드(추상 메서드)를 포함하고 있는 클래스이다.
추상 메서드는 구현부가 없는 메서드로 abstract 키워드를 사용해 선언한다.
마찬가지로 추상 메서드를 포함하고 있는 추상 클래스도 abstract 키워드를 사용하여 구분한다.
abstract class ClassName{
abstract void methodName();
}
추상 메소드는 하위클래스에서 반드시 오버라이드 해야할 책임이 있다.
이러한 특징으로 추상클래스를 상속 받는 모든 클래스는 추상메서드를 오버라이딩하여 사용하도록 강제하는 기능이 있다.
추상클래스는 추상메서드를 제외하고 일반 클래스와 동일하기 때문에 다른 멤버들은 자유롭게 필요에 따라 사용할 수 있다.
예제에서 SuperCar는 추상클래스인 Car를 상속 받았다.
abstract class Car{
abstract void drive();
void stop(){
System.out.println("Stop the Car");
}
}
class SuperCar extends Car{
@Override
void drive() {
System.out.println("driving a SuperCar");
}
}
class TestMain{
public static void main(String[] args) {
SuperCar superCar = new SuperCar();
superCar.drive();
superCar.stop();
}
}
추상 메서드인 drive를 오버라이드 하여 로직을 작성하였고 일반 메서드인 stop은 선택적으로 사용이 가능한 것을 알 수 있다.
'Language & Framework > Java' 카테고리의 다른 글
[JAVA] :: 자바 기초 6 :: 인터페이스 (Interface) (0) | 2021.07.25 |
---|---|
[JAVA] :: 자바 기초 4 :: 상속 / 오버라이딩(overriding) / IS-A vs HAS-A / 가상함수 (0) | 2021.07.19 |
[JAVA] :: 자바 기초 3 :: Static / Singleton Patton / Array / ArrayList (0) | 2021.07.10 |
[JAVA] :: 자바 기초 2 :: 생성자 / 오버로딩 / 접근제어자 / 정보은닉 (0) | 2021.07.06 |
[JAVA] :: 자바 기초 1 :: 객체 / 클래스 / 인스턴스 / 속성 / 함수 / 메소드 (2) | 2021.07.04 |