이전에 만든 클래스에서 추가 기능을 덧붙일때 사용된다. 부모 클래스의 멤버는 자동적으로 자식 클래스에 상속되므로, 자식 클래스에는 추가 된 부분만 기술 하면 된다. 그렇기에 같은 기능을 복사 붙여넣기하지 않아도 되는 것이다. 자식 클래스는 더 구체적이고, 부모 클래스는 더 추상적 / 일반적인 개념을 갖는다.자식 클래스에서 extends
키워드를 사용해서 구현된다.
부모 클래스의 메소드를 사용하려면 override해야 한다. 이때 @override 애노테이션을 붙여야 한다.
void run() {
print("Ahh");
}
부모 클래스의 객체를 참조하려면 super
키워드를 사용해야 한다.
ex) SuperHero({required super.name, required super.hp});
부모 클래스가 생성자가 있다면 자식 클래스에서 부모 클래스의 생성자를 상속받아야 한다. 부모 생성자가 먼저 실행되고, 다음 자식 생성자가 실행된다.
다트에서 다중상속은 불가능하지만 Mixin으로 다중상속의 느낌을 낼 수 있다.
상속은 is-a 원칙으로 사용하면 된다.
a(자식클래스)는 b(부모클래스)이다
라는 말이 성립하면 옳은 관계이다.
현실 세계의 등장인물 사이에 개념적으로 is-a 관계가 성립하지 않는데 상속을 사용하면 잘못된 것이다. 이러면 클래스를 확장할 때 현실세계와 모순이 생기고, 다형성을 이용할 수 없게 된다.
상속의 재료로 사용되며, 상세 부분이 정의되지 않아 자식 클래스에서 무조건 구현해야 한다. 즉, 자식 클래스에서 override가 강제된다.
abstract
키워드를 붙이면 추상클래스 / 메소드가 된다. 추상 클래스는 인스턴스화될 수 없고, 추상 메소드는 method body를 가질 수 없다.
추상클래스는 뜻하지 않은 인스턴스화나 오버라이드를 구현하지 않는 문제를 예방할 수 있다.
Dart3에 추가된 기능으로, 추상 클래스 중 추상 메소드만 가지고 있는 것이라고 생각해도 된다. 인터페이스의 모든 메소드는 추상 메소드이고, 필드를 갖지 않는다. 또한, 여러 인터페이스를 implement할 수 있기 때문에 다중상속의 효과를 볼 수 있다. extends와 implements를 동시에 사용할 수 있다.
같은 인터페이스를 구현한 클래스들은 공통 메소드를 구현하고 있음을 보장하며, 어떤 클래스가 인터페이스를 구현하고 있다면 적어도 그 인터페이스에 정의된 메소드를 가지고 있다는 것이 보증된다.
abstract interface class 클래스이름 {
void 메소드();
}
상속은 부모 클래스의 모든 것을 자식 클래스에서 복붙한다음 내용을 추가하는 것이다.
추상클래스와 인터페이스는 템플릿이다. 템플릿을 만들어 놓으면 이걸 가져와서 각자 다르게 내용을 채우는 것이다. 틀을 만들어 놓기 때문에 개발을 효율적으로 할 수 있게 하고, 구현을 강제하기 때문에 코드의 안전성을 확보할 수 있다.