1/Путь к первому мобильному приложению. Часть 1.12 - Изучаем язык Dart: ООП. Generics, перечисления и другое

Generics это обобщения позволяющие добавить Вашему коду гибкости и не привязываться жёстко к типам данным.

// Вместо двух классов под разные типы данных...
class PersonInt{
    int id;
    String name;
    Person(this.id, this.name);
}
class PersonSring{
    string id;
    String name;
    Person(this.id, this.name);
}
... можно сделать один обобщённый
class Person<T>{
    T id;   // идентификатор пользователя
    String name; // имя пользователя
    Person(this.id, this.name);
}
// Программа
void main (){
    Person bob = Person("324", "Bob");
    print(bob.id.runtimeType);  // String
    Person sam = Person(123, "Sam");
    print(sam.id.runtimeType);  // int
}

В языке программирования Dart имеется возможность переопределять в классах стандартные операции, которые по сути над ними недоступны, но есть возможность задать правила их реализации.

// Переопределение операторов
class Vector {
  final int x, y;
  Vector(this.x, this.y);
  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
}
// Программа
void main ( ) {
  var v = Vector(2, 3);
  var w = Vector(2, 2);
  print('${(v+w).x} , ${(v+w).y}'); // 4 , 5
  print('${(v-w).x} , ${(v-w).y}'); // 0 , 1
}

Также у нас есть возможность отловить ошибку неизвестного метода:

// Отловить ошибку неизвестного метода
class A {
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: ' +
        '${invocation.memberName}');
  }
  void hello ( );
}
// Программа
void main ( ) {
  var a2 = A ( );
  a2.hello ( ); // You tried to use a non-existent member: Symbol("hello")
}

Есть возможность расширять функционал уже существующих классов:

// Расширение существующих классов
extension NumberParsing on String {
  int parseInt ( ) {
    return int.parse ( this );
  }
  double parseDouble ( ) {
    return double.parse ( this );
  }
}
// Программа
void main ( ) {
  print ( '0777'.parseInt ( ) ); // 777
}

Enum или перечисления в Dart это особый тип класса, который содержит в себе набор константных значений.

// Перечисления
enum Color { red, green, blue }
// Программа
void main ( ) {
  print(Color.red.index); // 0
  print(Color.green.index); // 1
  print(Color.blue.index); // 2
  List<Color> colors = Color.values;
  print(colors); // [Color.red, Color.green, Color.blue]
  var aColor = Color.blue;
  switch (aColor) {
    case Color.red:
      print('Red as roses!');
      break;
    case Color.green:
      print('Green as grass!');
      break;
    default:
      print(aColor); // Color.blue
  }
}

Определение типов - Typedefs

// Определяем свой собственный тип
typedef MyType<T> int Function (T a, T b);
// Создаём функцию
int sort (int a, int b) => a-b;
// Программа
void main ( ) {
  print ( sort is MyType<int>); // true
}

Call-классы

// Создаем такой класс
class CallFunction {
  String call ( String a , String b ) => '$a $b';
}
// Программа
void main ( ) {
  var callVar = CallFunction ();
  print ( callVar ( 'Hello,' , 'world!' ) ); // Hello, world!
}