Dart基础(六)-面向对象和类

2022-01-10  本文已影响0人  苍眸之宝宝

1.简介:

  Dart是面向对象的语言,具有面向对象的三个基本特征,即封装、继承和多态。

2.Dart面向对象独有的特征:

3.类的创建和使用:

  类中包含实例成员(对象成员)和静态成员,实例成员包含实例变量和实例方法,静态成员包含静态变量可静态方法。对象(也叫实例)是由函数functions(也叫做方法methods)和数据data(也叫做实例变量instance variables、成员变量members variables、属性properties、字段fields)组成的;类的对象访问成员变量或者方法需要.语法,可选用?.语法。
  类中静态成员可以通过类名加Type.语法进行访问。

3.1实例变量(instance variables):

  实例变量需要注意的点:

关键字 例子 意义
Type int a 表明实例变量的类型,有构造函数,必须在构造函数中初始化,没有构造函数必须提供默认值;初始化赋值后,后续可以继续改变其值
? int? a 表明实例变量可以为null值,初始化时不是必传参数 ;初始化赋值后,后续可以继续改变其值
final final int a 表明实例变量只能初始化赋值一次;有构造函数,必须在构造函数中初始化,没有构造函数必须提供默认值;初始化赋值后,后续无法修改其值
late late int a 表明实例变量可以延时初始化,及可以在构造函数外进行初始化赋值

注意:有构造函数表示的是自定义的构造函数,不包括默认构造函数。

3.2构造函数(Constructors):

构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载

构造函数需要注意的点:

3.3构造函数调用顺序:

  默认情况下,子类中的默认构造函数调用超类的默认构造函数。
  父类的构造函数在子类构造函数体的开头被调用;如果初始化列表Initializer list也被使用,它会在调用超类之前执行。综上所述,执行顺序如下::

  1. 初始化列表;
  2. 父类的无参数构造函数的;
  3. 子类的无参数构造函数.
      如果父类有自定义构造函数(后续都成为构造函数),子类构造函数则必须手动调用父类中的一个构造函数;在冒号:之后指定父类构造函数;其含义是在调用子类的该构造函数之前,先执行父类的构造函数。
class Duck extends Bird {
  // 子类构造函数重定向父类构造函数
  Duck(String name, String wing) : super(name, wing);
}

class Point {
  double x;
  late final double y;
  late double? z;
  final double a;

  Point(this.x, this.y, this.z, this.a);
  // 命名构造函数,重定向构造函数
  Point.zero() : this(0, 0, 0, 0);

  static Point zero2() {
    final zero = Point(0, 0, 0, 0);
    return zero;
  }
}
3.4初始化列表Initializer list

  子类构造函数除了调用超类构造函数外,还可以在构造函数体运行之前初始化实例变量;用逗号分隔初始化式。

// 在调用构造函数前初始化实例变量
Point.fromJson(Map<String, double> json)
    : x = json['x']!,
      y = json['y']! {
  print('In Point.fromJson(): ($x, $y)');
}
}
3.5常量构造函数Constant constructors

  如果类生成的对象永远不会改变,那么可以将这些对象设置为编译时常量。为此,定义一个const构造函数,并确保所有实例变量都是final变量。

class ImmutablePoint {
  static const ImmutablePoint origin = ImmutablePoint(0, 0);

  final double x, y;

  const ImmutablePoint(this.x, this.y);
}
3.6工厂构造函数Factory constructors

  当实现不总是创建类的新实例的构造函数时,请使用factory关键字。例如,工厂构造函数可以从缓存返回一个实例,也可以返回一个子类型的实例。工厂构造函数的另一个用例是使用无法在初始化列表中处理的final修饰的变量;另一种解决方法是late final修饰变量。工厂方法中无法使用this关键字代表当前创建实例
  在下面的例子中,Logger工厂构造函数从缓存中返回对象,Logger. fromjson工厂构造函数从JSON对象中初始化final变量。

// 
class Logger {
  final String name;
  bool mute = false;

  // _cache is library-private, thanks to
  // the _ in front of its name.
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    return _cache.putIfAbsent(
        name, () => Logger._internal(name));
  }

  factory Logger.fromJson(Map<String, Object> json) {
    return Logger(json['name'].toString());
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

// 外部访问
var logger = Logger('UI');
logger.log('Button clicked');

var logMap = {'name': 'UI'};
var loggerJson = Logger.fromJson(logMap);
3.7方法methods

  Dart中,方法一般是指对象方法(或称实例方法),即对象能够调用的函数;方法是一种特殊的函数,即只能被对象调用的函数。
  对象上的实例方法可以通过this(可省略)访问对象的属性和方法,可以通过ClassType.语法访问静态成员(包含静态变量、静态常量、静态函数等)。

class MethodPoint {
  static const String className = "MethodPoint";
  static String star = "123";

  double x = 0;
  double y = 0;

  MethodPoint(this.x, this.y);

  void show() {
    print(MethodPoint.className);
    print(MethodPoint.star);
  }

  double distanceTo(MethodPoint other) {
    var dx = x - other.x; // 等价于:var dx = this.x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}
3.8操作符方法:

  操作符可以作为特殊名称的实例方法。Dart允许你用以下名称定义操作符方法:

< + | >>>
> / ^ []
<= ~/ & []=
>= * << ~
% >> ==

  注意:您可能已经注意到一些操作符,比如!=,不在名称列表中。那是因为它们只是语法糖。例如,表达式e1 != e2是!(e1 == e2)的语法糖。

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);
}

// 调用
  final v = Vector(2, 3);
  final w = Vector(2, 2);

  print(v + w == Vector(4, 5));
  print(v - w == Vector(0, 1));
3.9获取getters和设置方法setters

  gettersetter是提供对对象属性的读写访问的特殊方法。每个实例变量都有一个隐式getter,如果合适的话还有一个setter。你可以通过实现getter和setter来创建额外的属性,使用getset关键字:

class Rectangle {
  double left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // Define two calculated properties: right and bottom.
  double get right => left + width;
  set right(double value) => left = value - width;
  double get bottom => top + height;
  set bottom(double value) => top = value - height;
}

    // 调用
    var rect = Rectangle(3, 4, 20, 15);
    print(rect.left == 3);
    rect.right = 12;
    print(rect.left == -8);

4.重写实例成员Overriding members

  子类可以覆盖实例方法(包括操作符方法)、getter和setter。你可以使用@override注释来表示你有意重写一个成员。
  重写实例方法的几个原则:

class Television {
  // ···
  set contrast(int value) {...}
}

class SmartTelevision extends Television {
  @override
  set contrast(num value) {...}
  // ···
}

5.noSuchMethod():

  当对象访问不存在的方法或实例变量时,你可以重写noSuchMethod()来检测或做出反应。
  未实现的方法一般情况下是不能调用的,以下是能够调用的情况:

有关更多信息,请参阅非正式的noSuchMethod转发规范

class A {
  // Unless you override noSuchMethod, using a
  // non-existent member results in a NoSuchMethodError.
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: '
        '${invocation.memberName}');
  }
}

6.枚举类型Enumerated types

  枚举类型是一种特殊的类,用于表示固定数量的常量值。
枚举类型注意的点:

// 定义枚举类型
enum Color { red, green, blue }

// 获取枚举类枚举值的索引值
print(Color.red.index == 0);
print(Color.green.index == 1);
print(Color.blue.index == 2);

// 获取枚举类的所有枚举值
List<Color> colors = Color.values;
print(colors[2] == Color.blue);

// switch判断枚举值
var aColor = Color.blue;
switch (aColor) {
  case Color.red:
    print('Red as roses!');
    break;
  case Color.green:
    print('Green as grass!');
    break;
  default: // Without this, you see a WARNING.
    print(aColor); // 'Color.blue'
}

7.类成员(静态成员):

  Dart中,静态成员static members也称为类成员,包含静态变量和静态方法(或类变量和类方法)。
  类成员只能通过Type.语法访问。类方法不操作实例,因此不能访问实例成员;但是类方法可以访问类变量;类方法可以作为编译时常量作为参数传递给常量构造函数。类变量在被使用之前不会被初始化。

class Person {
  static String className = 'Person';
  late final String name;
  late final int age;

  void show() {
    print(name);
  }

  static void showClassName() {
    print(className);
  }
}
上一篇下一篇

猜你喜欢

热点阅读