前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dart学习笔记(四)

Dart学习笔记(四)

作者头像
拉维
发布2019-08-12 15:56:24
8220
发布2019-08-12 15:56:24
举报
文章被收录于专栏:iOS小生活iOS小生活

1,Dart中的静态成员和静态方法

定义一个类的时候,默认的属性和方法都是非静态的(即实例的):

代码语言:javascript
复制
class Person{
  
  //实例成员
  String name;
  int age;

  //实例方法
  printInfo(){
    print('${this.name}---${this.age}');
  }

}

实例成员和实例方法都必须通过类的实例对象去调用

代码语言:javascript
复制
void main(){

  Person person = new Person();//新建一个类的实例对象
  person.printInfo();

}

可以通过static关键字来定义静态的属性和方法

代码语言:javascript
复制
class Person{
  
  //实例成员
  String name;
  int age;

  //静态成员
  static String sex;

  //实例方法
  printInfo(){
    print('${this.name}---${this.age}');
  }

  //静态方法
  static void staticPrintInfo(){

  }

}

在类外部访问静态成员的时候,都是通过类来访问,而不需要将类实例化:

代码语言:javascript
复制
void main(){
  
  //访问实例属性和实例方法
  Person person = new Person();//新建一个类的实例对象
  person.printInfo();

  //访问静态属性和静态方法
  print(Person.sex);
  Person.staticPrintInfo();
}

在类的内部,静态方法里面只能访问静态成员,实例方法里面可以访问任何成员

代码语言:javascript
复制
class Person{
  
  //实例属性
  String name;
  int age;

  //静态属性
  static String sex;

  //实例方法里面可以访问任何成员
  printInfo(){
    print('${this.name}---${this.age}');//实例方法中访问实例属性
    print(sex);//实例方法中访问静态属性
    staticPrintInfo();//实例方法中访问静态方法
  }

  //静态方法里面只能访问静态成员
  static void staticPrintInfo(){
    print('staticPrintInfo---$sex');//静态方法中访问静态属性
  }

}

我们不可以在类的外部通过类的实例直接调用类的静态成员,但是可以通过实例方法来隐式调用类的静态成员,因为在类的内部,实例方法是可以调用任何成员的

类的静态成员存在于类的定义体中,类的实例成员存在于类的实例中

2,Dart中的对象操作符

在dart中,如果声明一个实例对象后没有进行初始化,那么调用该对象的属性或者方法就会报错:

代码语言:javascript
复制
  Person person;
  print(person.name);

报错如下:

代码语言:javascript
复制
Unhandled exception:
NoSuchMethodError: The getter 'name' was called on null.
Receiver: null

此时就使用到条件运算符?

代码语言:javascript
复制
  Person person;
  print(person?.name);

这时就运行正常了。person?的意思是,如果对象person为空,那么就不会调用属性name;如果对象person为非空,那么就调用属性name。

is操作符用于判断对象是不是某个类或者某类的子类的对象

代码语言:javascript
复制
  Person person = new Person('liwei', 12);
  print(person is Person);
  print(person is Object);
  print(person is String);

打印结果如下:

代码语言:javascript
复制
true
true
false

as操作符用于强转类型

代码语言:javascript
复制
  var person;
  person = '';
  person = new Person('liwei', 12);
  (person as Person).printInfo();//转换类型

..连缀操作符用于级联操作

代码语言:javascript
复制
  var person = new Person('张三', 12);
  person.printInfo();
  person.name = "李四";
  person.age = 22;
  person.printInfo();

这段代码也可以使用级联操作符简化:

代码语言:javascript
复制
  var person = new Person('张三', 12);
  person..printInfo()
        ..name = '王五'
        ..age = 22
        ..printInfo();

其结果是一样的。

3,继承相关。

下面是Person类的定义:

代码语言:javascript
复制
class Person{
  String name;
  num age;
  Person(this.name, this.age);
  printInfo(){
    print('${this.name}, ${this.age}');
  }
}

接下来我创建一个Person的子类IronMan:

代码语言:javascript
复制
class IronMan extends Person{
  IronMan(String name, num age) : super(name, age);
}

可以看到,我们是通过extends关键字来继承的。子类可以继承父类的共有属性和方法,但是不能继承父类的构造函数

如果父类中实现了默认的构造函数,那么我们需要在子类中也实现构造函数来给父类的构造函数传值。如上面代码所示,子类中有下面一行代码:

代码语言:javascript
复制
IronMan(String name, num age) : super(name, age);

其中IronMan(String name, num age)是子类的构造函数,通过子类的构造函数,将参数值传给父类的构造函数super(name, age)。

在子类中也可以扩展定义自己特有的属性和方法,如下:

代码语言:javascript
复制
class IronMan extends Person{
  //在子类中定义自己的属性和方法
  String sex;
  //实现子类的构造函数,并且将参数值传给父类的构造函数
  IronMan(String sex, num age, String name) : super(name, age){
    this.sex = sex;
  }
  printIronManInfo(){
    print('${this.name}, ${this.age}, ${this.sex}');
  }
}

也可以在子类中覆写父类的方法

代码语言:javascript
复制
class IronMan extends Person{
  String sex;
  IronMan(String sex, num age, String name) : super(name, age){
    this.sex = sex;
  }

  //覆写父类的方法
  @override
  printInfo() {
    print('${this.name}, ${this.age}, ${this.sex}');
  }
}

4,抽象类

不管是在Objective-C中还是在Dart中,都有抽象类的概念。抽象类主要用于定义标准,不可使用抽象类直接生成实例,只有继承自抽象类的子类才可以实例化对象

使用abstract关键字来定义抽象类

代码语言:javascript
复制
//使用abstract关键字来定义抽象类
abstract class Animal{

}

如果我们要在抽象类中定义一个方法,要求该抽象类的子类必须实现该方法,那么可以将该方法定义成抽象方法

代码语言:javascript
复制
//使用abstract关键字来定义抽象类
abstract class Animal{
  //定义抽象方法(移除大括号的部分就是抽象方法了)
  printInfo();
}

class Cat extends Animal{
  @override
  //抽象类的子类中,必须要实现抽象类中的抽象方法,不然会报错。
  printInfo() {
    print('info');
  }
}

在抽象类中的定义的抽象方法,在抽象类的子类中必须实现,不然会报错。

当然了,在抽象类中也是可以定义非抽象方法的,但是在普通类中不可以定义抽象方法

5,多态。

多态,顾名思义,多种状态。大白话说,多态就是父类定义一个方法不去实现,让继承它的子类去实现,每个子类会有不同的表现

6,接口。

在Objective-C中,我们可以通过@interface关键字来定义接口。但是在Dart中,是没有interface关键字来定义接口的,dart里的普通类或者抽象类都可以作为接口被实现

Dart中的接口是比较奇怪的,属性倒还好,直接声明就OK了;但是对于方法就有点奇怪了,因为dart中的普通类定义里的方法是需要实现的,比如下面这样:

代码语言:javascript
复制
class Animal{
  //属性
  String name;
  //函数
  void printInfo(){

  }
}

当然,上面演示的是普通类的接口。下面来看一下抽象类的接口:

代码语言:javascript
复制
//抽象类
abstract class Animal{
  //属性
  String name;
  //抽象函数
  void printInfo();
}

通过比较我们发现,抽象类中是可以定义抽象函数的,该抽象函数在定义的时候不需要实现。所以,我们一般在Dart中通过抽象类来定义接口

如下是一个抽象类,里面定义了一个属性和一个抽象方法这两个接口:

代码语言:javascript
复制
//抽象类
abstract class Animal{
  //属性
  String name;
  //抽象函数
  void printInfo();
}

然后我在该抽象类的子类中对该接口进行实现:

代码语言:javascript
复制
class Cat implements Animal{
  @override
  String name;

  @override
  void printInfo() {
    print('Cat');
  }
}

class Dog implements Animal{
  @override
  String name;

  @override
  void printInfo() {
  }
}

需要注意的是,使用 implements 关键字来对抽象类中的接口进行实现。抽象类中定义的接口,在子类中实现的时候都需要实现

7,extends和implements的区别

extents用于继承,implements用于实现接口

看到这里,我们可能还是迷迷糊糊,这两者到底有啥区别呢?接下来可能会让你豁然开朗。

首先,我定义了两个抽象类:

代码语言:javascript
复制
abstract class Animal{
  String name;
  printInfo();
}

abstract class People{
  String nation;
  singASong();
}

我们知道,Dart中的类也是单继承的,比如下面这种写法就肯定会报错:

代码语言:javascript
复制
class Thing extends Animal,People{

}

但是我现在将上面的extends换成implements,也就是说,Animal,People相对于Thing这个类不是父类的存在,而是接口封装的存在,那么程序就不会有任何问题。

想必看到这里你应该弄清楚接口的概念了吧。

dart中的抽象类,既可以作为一个父类去生成对应的子类,也可以作为其他类的接口封装

在Dart中,我们使用implements关键字来实现使用抽象类来封装的接口,并且一个类可以实现多个接口,如下:

代码语言:javascript
复制
//封装接口的抽象类
abstract class Animal{
  String name;
  printInfo();
}

//封装接口的抽象类
abstract class People{
  String nation;
  singASong();
}

//一个类可以实现多个接口
class Thing implements Animal,People{
  @override
  String name;

  @override
  String nation;

  @override
  printInfo() {
    return null;
  }

  @override
  singASong() {
    return null;
  }

}

8,mixins(混入)

mixins的中文意思是混入,也就是在类中混入其他功能。mixins特性是Dart中特有的特性,可以用来实现类似多继承的功能

下面我定义了三个不同的类:

代码语言:javascript
复制
class A{
  printA(){
    print('A');
  }
}

class B{
  printB(){
    print('B');
  }
}

class C{
  printC(){
    print('C');
  }
}

然后我们使用Dart的mixins特性来创建一个类D:

代码语言:javascript
复制
class D with A,B,C {
  
}

然后我们新建一个D类的实例来验证一下,该实例是否具有类A、B、C的功能:

代码语言:javascript
复制
main(){

  D d = new D();
  d.printA();
  d.printB();
  d.printC();

}

打印结果如下:

代码语言:javascript
复制
A
B
C

这说明类D的实例具有了类A、B、C的功能。

需要注意的是,作为mixins的类只能继承自Object,而不能继承自其他的类。也就是说,上例中的 A,B,C 都必须是继承自Object,否则就会报错。比如下面的例子:

代码语言:javascript
复制
class A{
  printA(){
    print('A');
  }
}

class B extends A{
  printB(){
    print('B');
  }
}

class C {
  printC(){
    print('C');
  }
}

class D with B,C {
  
}

C默认继承自Object,这是没有问题的。但是B继承自A,程序会报错如下:

代码语言:javascript
复制
The class 'B' can't be used as a mixin because it extends 
a class other than Object.

另外一点需要注意的是,作为mixins的类不能有构造函数。比如下面这个类就不能作为mixins的类:

代码语言:javascript
复制
class A{
  A(){
    //这里是类A的构造函数
  }
  printA(){
    print('A');
  }
}

当A作为mixins的类的时候就会报错:

继承与mixins也可以同时使用

代码语言:javascript
复制
class A{
  A(){
    //这里是类A的构造函数
  }
  printA(){
    print('A');
  }
}

class B {
  printB(){
    print('B');
  }
}

class C {
  printC(){
    print('C');
  }
}

//D继承自A,并且混入B和C的功能
class D extends A with B,C{
  
}

我们知道,可以通过 is 关键字来判断对象的类型。那么大家看一下下面这个例子,猜猜生成的实例d是什么类型:

代码语言:javascript
复制
class A{
  A(){
    //这里是类A的构造函数
  }
  printA(){
    print('A');
  }
}

class B {
  printB(){
    print('B');
  }
}

class C {
  printC(){
    print('C');
  }
}

//D继承自A,并且混入B和C的功能
class D extends A with B,C{
  
}

main(){

  D d = new D();
  print(d is A);
  print(d is B);
  print(d is C);
  print(d is D);

}

打印结果如下:

代码语言:javascript
复制
true
true
true
true

可以看到,实例对象d既是A类型,也是B类型,也是C类型,也是D类型。D继承自A,所以 d is D 和 d is A 都返回 true 这很容易理解,但是其他两个也返回 true 就很难理解了是吧?这其实是Dart语言的特性。我们可以将mixins理解成多继承(但是实际并不是多继承),这样就可以将B和C理解成D的超类,这样 d is B 和 d is C 也返回 true 就很容易理解了。

以上。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档