1. 상속
상속은 부모가 가진 상태와 행위를 자식이 물려받는 것과 동시에 다형성이 성립해야 한다.
상속을 위해 extends 키워드를 사용한다.
1.1 다형성
class Burger { Burger() { print("버거"); } } class CheeseBurger extends Burger { CheeseBurger() { print("치즈버거"); } } void main() { CheeseBurger cb1 = CheeseBurger(); Burger cb2 = CheeseBurger(); //다형성 }
다형성이란 여러 가지 형태를 가질 수 있는 능력을 의미한다.
치즈 버거는 버거인가? yes
1.2 추상 클래스
추상 클래스는 말 그대로 추상적인 클래스이다. 추상적이기 때문에 객체를 만들 수 없다.
추상 클래스를 사용하는 이유는 수많은 객체를 추상화하는 공통 부모를 만들 수 있기 때문이다.
class Dog { void sound() { print("배고파"); } } class Cat { void sound() { print("배고파"); } } class Fish { void hungry() { print("배고파"); } } void main() { Dog d = Dog(); Cat c = Cat(); Fish f = Fish(); d.sound(); c.sound(); f.hungry(); }
추상화를 하지 않으면 코드가 위의 코드처럼 코드가 일관성이 깨지게 된다. 따라서 부모 클래스를 상속해 부모 클래스가 가진 메서드를 사용하도록 해야 한다.
abstract class Animal{ void sound(); } class Dog implements Animal{ void sound() { print("멍멍 배고파"); } } class Cat implements Animal{ void sound() { print("야옹 배고파"); } } class Fish implements Animal{ void hungry() { print("뻐끔뻐금 배고파"); } } void main() { Dog d = Dog(); Cat c = Cat(); Fish f = Fish(); d.sound(); c.sound(); // f.sound(); }
각 클래스의 추상 클래스인 Animal 클래스를 만들고 hungry 함수를 추가했다.
자식 클래스는 implements 를 통해 부모 클래스를 상속받게 되면 부모가 가진함수를 반드시 구현해야 한다.
이렇게 되면 추상 클래스의 함수를 호출하게 되면 자식 클래스의 함수가 동적으로 실행된다. 이를 오버라이딩이라고 한다.
부모 클래스가 가진 sound() 함수가 아니라 다른 함수를 구현하면 오류가 발생한다.
2. 슈퍼(super) 키워드
class Burger { String? name; Burger(){} } class CheeseBurger extends Burger { CheeseBurger(String name) { // 생성자 super.name = name; } } void main() { CheeseBurger cb = CheeseBurger("치즈햄버거"); print(cb.name); // 자식 클래스를 호출했을 때 부모의 name 변수를 사용함. }
super 키워드는 자식이 부모의 객체를 참조할 수 있는 키워드이다. 자식이 부모의 변수를 사용할 수 있다.
3. final 키워드
final 키워드는 변수를 단 한번만 초기화 하겠다고 선언하는 키워드이다. 한 번만 초기화되기 때문에 변수가 아닌 상수라고 부른다.
class Burger { final String name; Burger(this.name); } class CheeseBurger extends Burger { CheeseBurger(String name) : super(name) {} // : 은 이니셜라이져 키워드 } void main() { CheeseBurger cb = CheeseBurger("치즈햄버거"); print(cb.name); }
이니셜 라이져 키워드 (:) 을 사용하면 자식 생성자의 내부 스택이 실행되기 전에 부모 생성자에게 값을 전달한다.
4. Mixin
Mixin 은 여러 클래스 계층에서 클래스의 코드를 재사용하는 방법이다. 다중 상속의 문제를 해결할 수 있고, 컴퍼지션을 사용하지 않고 다른 클래스 코드를 재사용할 수 있다.
with 키워드를 사용한다.
mixin Engine { int power = 5000; } mixin Wheel { String wheelName = "4륜 구동 바퀴"; } class BMW with Engine, Wheel {} void main() { BMW b = BMW(); print(b.power); print(b.wheelName); }
하지만 Mixin은 인스턴스화가 불가능하다. 따라서 인스턴스로 사용하고 싶다면 mixin class 를 사용해야 한다.
mixin class Engine { int power = 5000; } mixin Wheel { String wheelName = "4륜 구동 바퀴"; } class BMW with Engine, Wheel {} void main() { BMW b = BMW(); Engine engine = Engine(); // 인스턴스 가 Wheel wheel = Wheel(); // 인스턴스 불가 print(b.power); print(b.wheelName); }
Share article