같은 부모를 가지는 다른 인스턴스를 동일시하는 것이다. 상속에 의한 is-a관계가 성립하면 인스턴스를 부모 클래스 타입의 변수에 대입할 수 있다. 또한, 클래스를 인터페이스로 선언하면 인터페이스도 타입이 될 수 있다.
abstract interface class Drawable {
void draw();
}
void main() {
Drawable element = House();
List<Drawable> paintings = [];
paintings.add(Dog());
}
상속관계, 인터페이스 구현 관계에 있을 때만 다형성을 사용할 수 있다. 선언은 상위 개념으로, 인스턴스 생성은 하위 개념으로 한다.
void main() {
Student student1 = Freshman();
Freshman freshman = student1 as Student;
}
위 코드에서 student1의 타입은 Student지만, 실체는 Freshman 클래스의 인스턴스이다. 타입은 어떤 멤버를 접근할 수 있는지를 결정하고, 실체는 멤버가 어떻게 움직이는지를 결정한다. 즉, 타입 클래스에 원하는 멤버가 정의되어 있는지 확인하고 실체인 클래스에서 원하는 멤버를 불러오면 된다.
타입 캐스팅은 as
로 하면 되지만, 런타임에 하기 때문에 위험할 수 있다.
(character as Wizard).fireball(slime)
-> 그래서 is
로 타입 체크를 하는 것이 좋다!
if (character is Wizard) {
character.fireball(slime);
}
Dart에서는 메소드 오버로딩을 지원하지 않지만, 다형성을 활용해서 더 큰 개념을 메소드의 인자로 활용하면 문제를 해결할 수 있다.
다형성은 같은 부모를 가지는 다른 인스턴스를 동일시하여, 부모 클래스 타입에 자식 클래스의 인스턴스를 담는 것이다. 동일시 취급해도 각각의 인스턴스는 각 클래스의 정의를 따르고 다른 동작을 한다. 부모 클래스 타입의 인수나 리턴값을 이용하여 다른 클래스를 모아서 처리 가능하다.