티스토리 뷰

Mobile/Dart

[Dart] Extends, Implements, With

춘햄 2022. 6. 26. 10:23

Dart도 객체지향 언어이기 때문에 당연하게 상속이나 구현의 개념을 가지고 있다. 

 

이번 포스팅에서는 Dart에서 extends와 implements를 어떻게 사용하며, 추가로 상속과 같이 사용할 수 있는 mixin이 어떤 것인지 확인해보려고 한다.


1. extends

 

 상속은 아래와 같이  extends와 super를 사용하여 구현할 수 있다.

import 'package:untitled1/untitled1.dart' as untitled1;

void main(List<String> arguments) {
  Spacecraft sp = Spacecraft.origin();
  sp.describe();

  Orbiter ob = Orbiter("뭉치2", DateTime.now(), 100);
  ob.describe();

}

class Spacecraft {
  String? name;
  DateTime? launchDate;

  int? get launchYear => launchDate?.year;

  Spacecraft(this.name, this.launchDate);

  Spacecraft.unlaunched(String name) : this(name, null);

  Spacecraft.origin() {
    name = "뭉치";
    launchDate = DateTime.now();
  }

  // Method.
  void describe() {
    print('Spacecraft: $name');
    // Type promotion doesn't work on getters.
    var launchDate = this.launchDate;
    if (launchDate != null) {
      int years = DateTime.now().difference(launchDate).inDays ~/ 365;
      print('Launched: $launchYear ($years years ago)');
    } else {
      print('Unlaunched');
    }
  }
}

class Orbiter extends Spacecraft {
  num altitude;
  Orbiter(String name, DateTime launchDate, this.altitude): super(name, launchDate);
}

 

2. implements 

 

 Dart 에는 interface 키워드가 따로 존재하지 않는다. 대신, 일반 클래스도 implements를 사용하여 재정의 해줄 수 있는데, 이때는 반드시 구현할 클래스가 정의해놓은 모든 메서드나 인자도 같이 재정의 해야 한다. 

 

import 'package:untitled1/untitled1.dart' as untitled1;

void main(List<String> arguments) {
  Spacecraft sp = Spacecraft.origin();
  sp.describe();

  ImplOrbiter im = ImplOrbiter();
  im.describe();

}

class Spacecraft {
  String? name;
  DateTime? launchDate;

  int? get launchYear => launchDate?.year;

  Spacecraft(this.name, this.launchDate);

  Spacecraft.unlaunched(String name) : this(name, null);

  Spacecraft.origin() {
    name = "뭉치";
    launchDate = DateTime.now();
  }

  // Method.
  void describe() {
    print('Spacecraft: $name');
    // Type promotion doesn't work on getters.
    var launchDate = this.launchDate;
    if (launchDate != null) {
      int years = DateTime.now().difference(launchDate).inDays ~/ 365;
      print('Launched: $launchYear ($years years ago)');
    } else {
      print('Unlaunched');
    }
  }
}

class ImplOrbiter implements Spacecraft {
  @override
  DateTime? launchDate;

  @override
  String? name;

  @override
  void describe() {
    print("iplemented Orbiter");
  }

  @override
  // TODO: implement launchYear
  int? get launchYear => throw UnimplementedError();

}

 

3. Mixin 

 

 mixin은 dart 공식 레퍼런스에서 설명하기를 여러 클래스 계층에서 클래스의 코드를 재사용할 수 있는 방법이라고 나와있다.

Dart는 여러 객체지향언어와 마찬가지로 하나의 슈퍼 클래스만 상속이 가능하기 때문에 implements 없이 다른 슈퍼클래스나 형제 클래스의 코드를 재사용하기 위해 사용하는 개념이라고만 이해해두면 편할 거 같다.

 

 mixin은 아래와 같은 형태로, 일반 클래스 선언과 동일하게 정의할 수 있다.

class Walker {
  void walk() {
    print("I'm walking");
  }
}

정의 후 일반 상속과 동일하게 사용할 수 있으며, 여러 개를 사용할 수도 있다.

void main(List<String> arguments) {
  Cat cat = Cat();
  Dove dove = Dove();

  cat.walk();

  dove.walk();
  dove.fly();
}


class Walker {
  void walk() {
    print("I'm walking");
  }
}

class Flyer {
  void fly() {
    print("I'ma flying");
  }
}

class Mammal {}

class Bird {}

class Cat extends Mammal with Walker {}

class Dove extends Bird with Walker, Flyer {}

또한 on 키워드를 사용하여 mixin의 사용을 선언된 클래스를 확장하거나 구현하는 클래스로만 제한할 수 있다. 

class A {}

mixin X on A {}

class Y on A{}//에러

class p extends A with X {}

class Q extends X {} //에러

정리하면, 

 

Extends: 클래스의 멤버 변수, 함수, 생성자 등을 구현 없이 사용할 때 사용

 

Implements: 클래스의 멤버 변수, 함수, 생성자 등의 구현이 필수

 

With: 여러 클래스 계층에서 클래스의 코드를 재사용

'Mobile > Dart' 카테고리의 다른 글

[Dart] Null Safety  (0) 2022.06.27
[Dart] 비동기 프로그래밍: future, async, await  (0) 2022.06.27
[Dart] factory  (0) 2022.06.26
[Dart] Dart 기본  (0) 2022.06.26
Comments