본문 바로가기
기타개발/Flutter

Dart #6 : Abstract, Implicit interface, Extends

by 궝테스트 2020. 8. 28.

Dart : https://dart.dev/guides/language/language-tour

 

1. Abstract classes

  • abstract 한정자를 사용하여 인스턴스화 할 수없는 추상 클래스를 정의한다
  • 추상 클래스가 인스턴스화 가능한 것처럼 보이게하려면 팩토리 생성자를 정의한다
// 이 클래스는 abstract 클래스이므로 인스턴스화 할 수 없다
abstract class AbstractContainer {
  // 생성자, 필드, 메소드를 정의한다

  // 추상 메소드
  void updateChildren();
}

 

2. Abstract methods

  • 인스턴스, getter/setter 메서드는 추상적 일 수 있으며 인터페이스를 정의하지만 구현은 다른 클래스에서 한다
  • 추상 메서드는 추상 클래스에만 존재할 수 있다
abstract class Doer {
  // 인스턴스 변수 또는 인스턴스 메소드를 정의한다
  
  // 추상 메소드
  void doSomething();
}

class EffectiveDoer extends Doer {
  void doSomething() {
    // 실제 구현은 이곳에서 한다
  }
}

 

3. Implicit interfaces

  • 모든 클래스는 클래스의 모든 인스턴스 멤버와 구현하는 인터페이스를 포함하는 인터페이스를 암시적으로 정의한다
  • 예를 들어 클래스 B 의 구현을 상속하지 않고 B 의 API를 지원하는 클래스 A 를 만들려면 클래스 A 는 B 인터페이스를 구현해야한다
  • 클래스는 하나 이상의 인터페이스를 implements 절에서 선언 후 인터페이스에 필요한 API 를 제공받아 구현한다
    • ex) class Point implements Comparable, Location {...}
// Person 클래스는 암시적 인터페이스인 greet() 를 갖고있다
class Person {
  // library-private 한 인터페이스
  final _name;

  // 인터페이스가 아닌 생성자
  Person(this._name);

  // 인터페이스
  String greet(String who) => 'Hello, $who. I am $_name.';
}

// Persion 인터페이스를 구현한다
class Impostor implements Person {
  // library-private 한 name 변수의 getter
  get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}

// result
Hello, Bob. I am Kathy.
Hi Bob. Do you know who I am?

 

4. Extending  a class

  • extends 를 사용하여 하위 클래스를 만들고 super 를 사용하여 수퍼 클래스를 참조한다
  • 하위 클래스는 인스턴스 메서드, getter/setter 를 재정의 할 수 있다
  • @override 어노테이션을 사용하여 의도적으로 멤버를 대체하고 있음을 나타낼 수 있다
  • 메소드 뿐만 아니라 operator 도 override 할 수 있다
class Television {
  void turnOn() {
    _illuminateDisplay();
    _activateIrSensor();
  }
  // ···
}

// Telelvision 을 상속받은 SmartTelevision 클래스
class SmartTelevision extends Television {
  @override
  void turnOn() {
    super.turnOn();
    _bootNetworkInterface();
    _initializeMemory();
    _upgradeApps();
  }
  // ···
}

 

여기서 잠깐, convariant keyword

  • 일부 (드물게 사용되는) 코딩 패턴은 매개 변수 타입을 유효하지 않은 하위 타입으로 재정의하여 타입을 강화하는데 의존한다
  • 이 경우 공변 키워드를 사용하여 의도적으로 수행하고 있음을 알릴 수 있다
  • 이렇게하면 정적 오류가 제거되고 대신 런타임에 잘못된 인수 타입이 있는지 확인한다
  • 아래 예제는 하위 타입에서 공변을 사용하는 것을 보여준다
  • 공변 키워드는 수퍼 클래스 또는 하위 클래스 메소드에 배치 할 수 있다
  • 일반적으로 수퍼 클래스 메서드가 가장 적합하며 공변 키워드는 단일 매개 변수에 적용되고 setter 및 필드에도 지원된다
class Animal {
  void chase(Animal x) { ... }
}

class Mouse extends Animal { ... }

class Cat extends Animal {
  void chase(covariant Mouse x) { ... }
}


또 여기서 잠깐, noSuchMethod()

  • 코드가 존재하지 않는 메서드 또는 인스턴스 변수를 사용하려고 할 때마다 감지할 때 사용한다
  • noSuchMethod 를 재정의하지 않을 경우, 존재하지 않는 멤버 사용 시 NoSuchMethodError 가 발생한다
class A {
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: ' +
        '${invocation.memberName}');
  }
}

 

'기타개발 > Flutter' 카테고리의 다른 글

Dart #8 : Generics  (0) 2020.08.28
Dart #7 : Extension method, Enum, Mixin  (0) 2020.08.28
Dart #5 : Classes, Constructor  (0) 2020.08.28
Dart #4 : if-else, for/while/do-while, switch, exceptions  (0) 2020.08.27
Dart #3 : Operators  (0) 2020.08.27

댓글