[Flutter] Dart 문법 3 - 상속, super, final, Mixin

류재성's avatar
Apr 12, 2024
[Flutter] Dart 문법 3 - 상속, super, final, Mixin
 

1. 상속

 
💡
상속은 부모가 가진 상태와 행위를 자식이 물려받는 것과 동시에 다형성이 성립해야 한다. 상속을 위해 extends 키워드를 사용한다.
 

1.1 다형성

 
 
class Burger { Burger() { print("버거"); } } class CheeseBurger extends Burger { CheeseBurger() { print("치즈버거"); } } void main() { CheeseBurger cb1 = CheeseBurger(); Burger cb2 = CheeseBurger(); //다형성 }
 
notion image
 
💡
다형성이란 여러 가지 형태를 가질 수 있는 능력을 의미한다. 치즈 버거는 버거인가? 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 를 통해 부모 클래스를 상속받게 되면 부모가 가진함수를 반드시 구현해야 한다. 이렇게 되면 추상 클래스의 함수를 호출하게 되면 자식 클래스의 함수가 동적으로 실행된다. 이를 오버라이딩이라고 한다.
 
notion image
 
💡
부모 클래스가 가진 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); }
 
notion image
 
💡
이니셜 라이져 키워드 (:) 을 사용하면 자식 생성자의 내부 스택이 실행되기 전에 부모 생성자에게 값을 전달한다.

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 를 사용해야 한다.
 
notion image
 
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); }
 
notion image
Share article

{CODE-RYU};