美文网首页
06——类

06——类

作者: 转移到CSDN名字丹丹的小跟班 | 来源:发表于2021-04-07 16:29 被阅读0次

类的定义

class 类名 {
  类型 成员名;
  返回值类型 方法名(参数列表) {
    方法体
  }
}

定义一个简单的“人”类

class Person {
  String name = "张三";
  int age = 20;
  void getInfo() {
    print('我的名字是:${name},我今年${age}');
  }
}

void main(List<String> args) {
  Person p1 = Person();
  p1.getInfo(); //我的名字是:张三,我今年20
}

类里面的this指向
在任何语言里面this指向都是一个比较头疼的问题,但是在dart类里,官方却并不推荐经常使用this,dart建议只有在两种情况下使用this。
类里面的new
在dart里面,官方建议为了减少代码迁移时的痛苦, Dart 语言仍允许使用 new 关键字, 但请考在你的代码中弃用和删除 new 。

  • 其中一种情况是要访问的局部变量和成员变量命名一样的时候:
class Person {
  String name = "张三";
  int age = 20;
  void getInfo() {
    String name = '李四';
    print('我的名字是:${this.name},我今年${age}');
  }
}

void main(List<String> args) {
  // Person p1 = new Person();
  Person p1 = Person();
  p1.getInfo(); //我的名字是:张三,我今年20
}
  • 还有一种就是使用了重定向

类里面肯定少不了构造函数了。
在dart里面有两种构造函数,一种是默认的构造函数,只能存在一个,可以省略不写,也可以自己定义,自己定义的会覆盖默认的。因为dart语言会自动编写。还有一种是命名构造函数,是自己编写的构造函数,可以写多个。dart里子类不会继承父类的构造函数。

默认构造函数

class Person {
  String name = "张三";
  int age = 20;
  Person(name, age) {
    this.name = name;
    this.age = age;
    print("我是默认的构造函数,对属性进行了赋值操作");
  }
  void getInfo() {
    print('我的名字是:${name},我今年${age}');
  }
}

void main() {
  Person p1 = Person("李四", 21);
  p1.getInfo();
//我是默认的构造函数,对属性进行了赋值操作
//我的名字是:李四,我今年21
}

默认构造函数的语法糖
dart里面提供了一种对构造函数的语法糖,能够更轻易的进行赋值操作。

class Person {
  String name = "张三";
  int age = 20;
  Person(this.name, this.age)
  void getInfo() {
    print('我的名字是:${name},我今年${age}');
  }
}

void main() {
  Person p1 = Person("李四", 21);
  p1.getInfo();
//我是默认的构造函数,对属性进行了赋值操作
//我的名字是:李四,我今年21
}

自定义构造函数

class Person {
  String name = "张三";
  int age = 20;
  Person(this.name, this.age);
  Person.children(this.name, this.age);
  Person.elderly(this.name, this.age);
  void getInfo() {
    print('我的名字是:${name},我今年${age}');
  }
}

void main() {
  Person p1 = Person.children("大熊", 12);  
  Person p2 = Person.elderly("鬼谷子", 66);
  p1.getInfo();  //我的名字是:大熊,我今年12
  p2.getInfo();  //我的名字是:鬼谷子,我今年66
}

初始化列表(Initializer list)
可以在构造函数体执行之前初始化实例变量。 各参数的初始化用逗号分隔。(在“=”右边不能使用this)

class Sum {
  int num1 = 0;
  int num2 = 20;
  final num sum;
  Sum(int num1, int num2)
    :num1 = num1,
    num2 = num2,
    sum = num1 + num2;
}

void main() {
  Sum s1 = Sum(1,2);
  print(s1.sum);  //3
}

重定向构造方法
在某些情况下, 我们希望在一个构造方法中去调用另外一个构造方法, 这个时候可以使用重定向构造方法

class Sum {
  int num1 = 0;
  int num2 = 20;
  final num sum;
  Sum(int num1, int num2)
    :num1 = num1,
    num2 = num2,
    sum = num1 + num2;
  Sum.sum2(int x, int y): this(x, y);
  Sum.sum3(int x, int y): this.sum2(x, y);
}

void main() {
//向找到sum3.然后重定向到sum2,最后重定向到sum。
  Sum s1 = Sum.sum3(10, 20);
  print(s1.sum);  //30
}

常量构造方法
默认情况下,创建对象时,即使传入相同的参数,创建出来的也不是同一个对象。

class Point {
  late num x;
  late num y;
  Point(this.x, this.y);
}

void main() {
  Point p1 = Point(1,2);
  Point p2 = Point(1,2);
  print(identical(p1, p2));  //false
}

在某些情况下,传入相同值时,我们希望返回同一个对象,这个时候,可以使用常量构造方法。就是在构造方法前加const进行修饰,那么可以保证同一个参数,创建出来的对象是相同的。

class Point {
  final num x;
  final num y;
  const Point(this.x, this.y);
}

void main() {
  Point p1 = const Point(1,2);
  Point p2 = const Point(1,2);
  print(identical(p1, p2));  //false
}

常量注意点:
注意一:拥有常量构造方法的类中,所有的成员变量必须是final修饰的.
注意二: 为了可以通过常量构造方法,创建出相同的对象,不再使用 new关键字,而是使用const关键字,如果是将结果赋值给const修饰的标识符时,const可以省略.

setter和getter
默认情况下,Dart中类定义的属性是可以直接被外界访问的。

但是某些情况下,我们希望监控这个类的属性被访问的过程,这个时候就可以使用setter和getter了。

class Color {
  String color = 'green';
  Color(this.color);
  String get getColor{
    return color;
  }
  void set setColor(String val) {
    color = val;
  } 
}

void main() {
  Color c1 = Color("red");
  print(c1.getColor);  //red
  c1.setColor = "black";
  print(c1.getColor);  //black
}

类的继承
面向对象的其中一大特性就是继承,继承不仅仅可以减少我们的代码量,也是多态的使用前提。

  • Dart中的继承使用extends关键字,子类中使用super来访问父类。
  • 父类中的所有成员变量和方法都会被继承,,但是构造方法除外。
  • 子类可以重写父类的属性和方法,
  • 子类中可以调用父类的构造方法,对某些属性进行初始化:
    1. 子类的构造方法在执行前,将隐含调用父类的无参默认构造方法(没有参数且与类同名的构造方法)。
    2. 如果父类没有无参默认构造方法,则子类的构造方法必须在初始化列表中通过super显式调用父类的某个构造方法。
class Son extends Father {
  String name;
  Son(String name) : name = name, super(name);
  Money() {
    print("我有100美金");
  }
  getFatherAge() {
    print("父亲今年${age}");
  }
}

void main() {
  Son s1 = Son('fufu');
  s1.Money();  //我有100美金
  s1.getFatherAge();  //父亲今年50
}

抽象类
使用 abstract 修饰符来定义 抽象类 — 抽象类不能实例化。 抽象类通常用来定义接口,以及部分实现。 如果希望抽象类能够被实例化,那么可以通过定义一个工厂构造函数来实现。
抽象类中一般存在抽象方法。没有方法体只有方法名的就是抽象方法,它一般用于当作一个规范。继承了抽象类子类就必须有抽象类的所有方法。

abstract class Animal {
  eat();
  run();
}

class Cat extends Animal {
  @override
  eat() {
    print("🐱喜欢吃草");
  }

  @override
  run() {
    print("🐱跑起来并不快");
  }
}

main() {
  Cat c1 = Cat();
  c1.eat(); //🐱喜欢吃草
  c1.run(); //🐱跑起来并不快
}

注意
注意一:抽象类不能实例化.
注意二:抽象类中的抽象方法必须被子类实现, 抽象类中的已经被实现方法, 可以不被子类重写.

隐式接口
Dart中每个类都隐式的定义了一个包含所有实例成员的接口,并且这个类实现了这个接口,如果我们需要A类支持B类的方法的话,我们可以选择继承,但是我们可能不想继承B类,或者已经继承了其他类,我们可以选择实现B类隐式接口。在实际开发中,我们通常使用抽象类作为接口。因为接口与继承抽象类相似,都需要重写被调用方法的所有属性和方法。

abstract class Animal {
  eat();
  run();
}

class Cat implements Animal {
  @override
  eat() {
    print("🐱喜欢吃草");
  }

  @override
  run() {
    print("🐱跑起来并不快");
  }
}

main() {
  Cat c1 = Cat();
  c1.eat(); //🐱喜欢吃草
  c1.run(); //🐱跑起来并不快
}

Mixin混入
如果想要一个类的某个方法,用接口的话需要重写类里的所有属性方法,用继承又只能继承一个类,dart不支持多继承,那么这个时候可以使用Mixin混入。
dart中新支持了一个类的特性,即为mixins(混入),按照dart官方的说明,这个混入的特性,可以同时混入多个类的属性和方法,使用混入只需要在类上使用with关键字,并可以混入多个。(注意混入与接口不能一起使用,但是可以与继承一起使用)

class Runner {
  run() {
    print('在奔跑');
  }
}

class Flyer {
  fly() {
    print('在飞翔');
  }
}
class Cat extends Runner with Flyer{
  
}

main() {
  Cat c1 = Cat();
  c1.fly(); //在飞翔
  c1.run(); //在奔跑
}

类成员和方法
使用 static 关键字实现类范围的变量和方法。也就是我们常说的静态方法和静态属性。

  • 静态方法(类方法)不能在实例上使用,因此它们不能访问 this
class Animal {
  static String name = '动物';
  String color = 'red';
  static void type() {
    print(Animal.name);
  }
  run() {
    print("${Animal.name}在奔跑");
  }
}

void main() {
  Animal a1 = Animal();
  a1.run();  //动物在奔跑
  print(Animal.name);//动物
  Animal.type(); //动物
}

注意
静态成员不能访问非静态成员( static 关键字修饰的成员 不能访问 非 static 关键字修饰的成员)
非静态成员可以访问静态成员

枚举类型
枚举类型也称为 enumerations 或 enums , 是一种特殊的类,用于表示数量固定的常量值。

enum Color { red, green, blue }
main(List<String> args) {
  // 枚举中的每个值都有一个 index getter 方法, 该方法返回值所在枚举类型定义中的位置(从 0 开始)。 
  // 例如,第一个枚举值的索引是 0 , 第二个枚举值的索引是 1。
  print(Color.red.index);  //0
  print(Color.green.index);  //1
  List<Color> colors = Color.values;
  print(colors);  //[Color.red, Color.green, Color.blue]
}

注意
枚举不能被子类化,混合或实现。
枚举不能被显式实例化。

相关文章

  • CPP:06类的模版

    CPP06-类的模版

  • 2020-06-06Java 集合类对比总结

    【2020-06-06--02期】Java 集合类 提纲 ArrayList 与LinkedList 异同; Ha...

  • 2022-06-06

    Trends Biotech | 四大类癌症模型指南 原创huacishu图灵基因2022-06-06 10:14...

  • 精选|11类推荐书单整理汇总

    书籍推荐类别索引 01 读书方法类 02 时间管理类 03 个人管理类 04 思维逻辑类 05 个人成长类 06 ...

  • 06类

    [TOC]根据类来创建对象被称为实例化,能让你使用类的实例. 创建和使用类 1.方法init() 类中的函数称为方...

  • 06——类

    类的定义 定义一个简单的“人”类 类里面的this指向在任何语言里面this指向都是一个比较头疼的问题,但是在da...

  • iOS开发中工具类(方法)

    同步发布在我的博客:http://he8090.cn/2017/06/06/iOS开发中工具类(方法)/本文章主要...

  • 2019-02-12

    保过计划【经管类】仍在继续 保研人保研人2018-06-06 点击蓝字关注 保研黄埔军校 我们用双手开拓进取 我们...

  • Swift 扩展:Extension

    (转载自http://letsswift.com/2014/06/extensions/) 扩展就是向一个已有的类...

  • mybitas笔记02

    2017 06 11 搭建环境 配置 主配置文件(Mybatis-Config.xml) 封装工具类 MyBati...

网友评论

      本文标题:06——类

      本文链接:https://www.haomeiwen.com/subject/gxgdkltx.html