美文网首页IT@程序员猿媛
第7章 Dart面向对象 -- 类和函数

第7章 Dart面向对象 -- 类和函数

作者: yangsg | 来源:发表于2019-05-13 16:50 被阅读20次

Dart是一种面向对象的语言,具有类和基于mixin(混入)的继承。每个对象都是一个类的实例, 与Java语言的继承体系类似,Dart中的每个类(除了Object)都只能有一个超类,但是类体可以在多个类层次结构中重用。

1. 类

1.1 普通类

1.1.1 普通成员

Dart使用class关键字表示一个类,对象具有由函数数据(可以理解为Java语言的方法属性)组成的成员。
与Java语言类似的是使用new XXX()方式创建类的对象,然后使用“.”或“?.”访问对象的函数或数据。
示例代码:

main() {
  var p1 = new Person();
  var p2 = new Person();
  p1.num = 10;
  p1.name = "赵四";
  p2.num = 20;
  p2.name = "刘能";
  p1.display();
  p2.display();
}
class Person{
  int num;
  String name;

  void display(){
    print("编号:${num}, 名字:${name}");
  }
}

运行结果:

运行结果

如果Person类定义在其他dart文件中,需要在main方法前引入其他dart文件。

import 'person.dart';
1.1.2 静态static

与Java中的静态static关键字类似,Dart语言中的static表达了“类成员”的含义,即这个成员不属于某个对象,而是属于整个类。
示例代码:将1.1.1示例中的num数据更改为“类数据”

main() {
  var p1 = new Person();
  var p2 = new Person();
  Person.num = 10;
  p1.name = "赵四";
  Person.num = 20;
  p2.name = "刘能";
  p1.display();
  p2.display();
}
class Person{
  static int num;
  String name;

  void display(){
    print("编号:${num}, 名字:${name}");
  }
}

运行结果:

运行结果

可以看到Person类的num属性通过类进行控制,不能通过对象控制。,Dart语言中对于“静态”方式调用的约束和理解与Java相似。

  • 静态函数只能访问类中其他的静态成员,不能访问普通的成员。(静态函数只能访问静态函数和静态数据)
  • 非静态函数可以访问类中的任意其他成员(非静态函数可以访问静态函数和静态数据)
  • 类的外部只能通过类名.xxx的方式访问静态资源,不能使用对象.xxx的方式访问静态资源。(Java语言允许对象访问静态资源,Dart语言不允许这样做)

1.2 可调用类(Callable Class)

Dart语言中允许以使用函数的方式来调用类,必须通过在类中实现call()方法完成将类模拟成函数的操作
示例代码

main(){
  var c = new Cxtest();
  var x = c(2,3);
  print(x);
}
class Cxtest{
  call(dynamic a, dynamic b){
     return a+b;
  }
}

运行结果:5

1.3 枚举(enum)

与Java中枚举的使用方式类似
声明枚举

enum Color{red, green, blue, yellow, white, black}

使用枚举

 var c = Color.blue;

遍历枚举

List<Color> list = Color.values;
list.forEach((Color c) => print("颜色:${c}"));

1.4 泛型编程(类型参数化)

Dart中的泛型使用方式与Java语言类似,使用泛型带来编程中的许多好处,此处不再累述(详见本人Java文章:《第16章 集合类》第4小节-泛型)。

在Dart中也可以向Java一样使用泛型编程,这种形式可以理解为将输入的类型参数化。
泛型声明可以使用在

  • 函数参数
  • 函数返回值

演示示例

main(){
  DataUtil<int> d = new DataUtil();
  d.show(32);
}
class DataUtil<T>{
  void show(T a) => print("数据:${a}");
}

此处也可以像Java语言一样使用T extends num形式约束泛型只能输入num或num类型的子类。详细用法请参照《第8章 Dart面向对象 -- 类的继承与混入(mixin)》)的第6节。

2. 函数

2.1 普通函数

Dart是一种纯粹的面向对象的语言,所以即使是函数也是对象。类似Javascript语言,Dart中的函数属于Function类型。可以通过函数指定变量或者把函数作为其他函数的参数。main函数是程序入口
Dart语言中函数结构与Java语言中的方法类似

返回值类型 函数名(参数列表){
  函数体代码
  return 返回值;
}

演示示例:两个数字相加的方法,并返回相加结果

main() {
  var c = addition(3, 2.14);
  print(c);
}

num addition(num a, num b){
  return a+b;
}

可以使用=>表示函数内容
比如

void main(){
  runApp(new MyApp());
}

等价于

void main() => runApp(new MyApp());

如果某个函数的返回值类型是void,可以省略void关键字
比如

void main(){}

等价于

main(){}

2.2 构造函数

构造函数是在创建Dart类实例(对象)时进行调用的,可以参考Java的构造方法进行理解。

2.2.1 常规构造函数

与Java语言的语法类似,在Dart语言中如果没有显式声明构造函数,系统会提供默认无参的构造函数,但如果显式声明了构造函数,系统不再提供默认的无参构造函数。
构造函数不能声明返回值类型,函数名必须与类名一致

类名(参数列表){
}

演示示例

void main(){
  var a = new NumberTest(2, 3);
  a.display();
}
class NumberTest{
  num a;
  num b;
  NumberTest(num a, num b){
    this.a = a;
    this.b = b;
  }
  void display(){
    print("数据:${a},${b}");
  }
}

上面示例的构造函数也可以写成下面这种形式,效果是一样的。

 NumberTest(this.a, this.b){}
2.2.2 命名构造函数

Dart的语法不支持函数重载,无法像Java语言一样使用构造方法重载。因此当需要使用多个构造函数时,需要使用命名构造函数这种形式。
演示示例

void main(){
  var a = new NumberTest(2,3);
  var b = new NumberTest.cons1();
  var c = new NumberTest.cons2(5);
  a.display();
  b.display();
  c.display();
}

class NumberTest{
  num a;
  num b;

  NumberTest(this.a, this.b){} //构造函数
  NumberTest.cons1(){//命名构造函数1
    this.a = 0;
    this.b = 0;
  }
  NumberTest.cons2(this.a){//命名构造函数2
    this.a = a;
    this.b = 0;
  }
  void display(){
    print("数据:${this.a},${this.b}");
  }
}

运行结果


运行结果
2.2.3 构造函数之间的调用

当需要构造函数之间互相调用时需要使用this关键字
演示示例

void main(){
  var a = new NumberTest(2,3);
  var b = new NumberTest.cons1();
  var c = new NumberTest.cons2(5);
  a.display();
  b.display();
  c.display();
}

class NumberTest{
  num a;
  num b;

  NumberTest(this.a, this.b){} //构造函数
  NumberTest.cons1() : this(0,0); //命名构造函数1
  NumberTest.cons2(num a) : this(a, 0); //命名构造函数2
  void display(){
    print("数据:${this.a},${this.b}");
  }
}
2.2.4 工厂构造函数

通过使用factory声明工厂构造函数,控制对象实例的数量。
语法

factory 类名(参数列表){
}

工厂函数中不能使用this关键字,有时需要借助命名构造函数完成功能
演示示例

void main(){
  var a = FactoryTest("haha");
  var b = FactoryTest("haha");
  var c = FactoryTest("xixi");
  print(a.hashCode);
  print(b.hashCode);
  print(c.hashCode);
  print(a == b);
}

class FactoryTest{
  String _name;
  static Map<String, FactoryTest> cache_map = new Map();

  factory FactoryTest(String name){ //工厂构造函数
    if(cache_map.containsKey(name)){
      return cache_map[name];
    }else{
      FactoryTest temp = FactoryTest.createInstance(name);
      cache_map[name] = temp;
      return temp;
    }
  }
  FactoryTest.createInstance(this._name);//命名构造函数
  void test(){
    print(_name);
  }
}

运行结果

运行结果

2.3 可选参数函数

Dart语言支持像Javascript中函数传递json的方式一样使用可选参数函数
声明语法

返回值类型 函数名({参数1,参数2...参数n})

演示示例

void main(){
  display1(1, "haha", 3.14); //必须补足实参
  display2(a:1, c:3.14);  //选择实参传入,此时只提供了a和c的实参
}

void display1(dynamic a, dynamic b, dynamic c){
  print("a:${a},b:${b},c:${c}");
}
void display2({dynamic a, dynamic b, dynamic c}){
  print("a:${a},b:${b},c:${c}");
}

运行结果

运行结果
可以为可选参数函数设置参数的默认值
void display2({dynamic a, dynamic b = 0, dynamic c}){
  print("a:${a},b:${b},c:${c}");
}

上面的代码将参数b的默认值设置为0,再次调用display2函数会得到如下结果:


运行结果

2.4 函数参数和匿名函数

Dart语言中函数被认为是一种类型Function,所以也可以将函数作为另一个函数的参数使用,此时类似Javascript语言中的函数参数的使用方式。

2.4.1 函数参数

演示示例:使用函数haha作为回调函数的参数

void main(){
  doSomeThing(3, haha);
}
void doSomeThing(num a, Function callback){
  print("do sth.${a} times");
  callback();
}
void haha(){
  print("done, good job");
}

运行结果

运行结果
2.4.2 匿名函数

如果不想显示声明haha函数,可以通过声明匿名函数的方式来完成函数参数的实现
语法

(){
  //功能代码
}

演示示例:使用匿名函数

void main(){
  doSomeThing(3, (){
    print("done, good job");
  });
}
void doSomeThing(num a, Function callback){
  print("do sth.${a} times");
  callback();
}

如果只有一行代码也可以写成

doSomeThing(3, () => print("done, good job"));

2.5 闭包

一个函数的作用范围为其函数体的{}内。当函数定义和函数表达式位于另一个函数的函数体内,内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
演示示例

void main(){
  var r = 2;
  var getCircleArea = (){
      const PI = 3.1415926536;
      return PI*r*r;  //匿名方法可以访问外部函数的数据r,形成闭包。
  };
  print(getCircleArea());
}

2.6 等价函数

由于函数可以被当做变量看待,那么当多个变量指向同一个函数时,它们之间就可以理解为互为等价函数
演示示例

void topMethod(){}

class Test{
  static void staticMethod(){}
  void instanceMethod(){}
}
void main(){
  dynamic temp1 = topMethod;
  dynamic temp2 = Test.staticMethod;
  dynamic t1 = new Test();
  dynamic t2 = new Test();
  dynamic temp3 = t1.instanceMethod;

  print("顶级函数比较结果: ${temp1 == topMethod}");
  print("静态函数比较结果: ${temp2 == Test.staticMethod}");
  print("实例函数比较结果1: ${temp3 == t1.instanceMethod}");
  print("实例函数比较结果2: ${temp3 == t2.instanceMethod}");
}

运行结果

运行结果

2.7 初始化列表

可以在构造函数体运行之前初始化实例变量,用逗号分隔初始化。
演示示例

main (){
  new NumberTest(2, 3).display();
}

class NumberTest{
  num x;
  num y;
  num z;
  NumberTest(this.x, this.y)
    : z=x+y{}  //带有初始化列表的构造方法,方法体内没有写代码
    
  void display(){
    print(z);
  }  
}

运行结果:5

相关文章

  • 2019-09-20: 九: Flutter之Dart第六节(类

    九: Flutter之Dart第六节(类和对象)? Dart 是一个面向对象的语言、面向对象中非常重要的概念就是类...

  • 第7章 Dart面向对象 -- 类和函数

    Dart是一种面向对象的语言,具有类和基于mixin(混入)的继承。每个对象都是一个类的实例, 与Java语言的继...

  • Dart语法 -- [06 - 类和对象]

    Dart是一个面向对象的语言,面向对象中非常重要的概念就是类,类产生了对象。 1.1. 类的定义 在Dart中,定...

  • Dart语法(下)

    前文链接: Dart简介 Dart语法(上) 内容: 函数(方法)函数定义及各类函数;函数参数;闭包 面向对象定义...

  • 三.Flutter之Dart语法(类和对象)

    一.类和对象: Dart是一个面向对象的语言,面向对象中非常重要的概念就是类,类产生了对象。 1.类的定义 2.构...

  • 2018-10-17类,对象

    1、面向过程编程 --> C,算法、逻辑 2、函数式编程 --> 函数 3、面向对象编程 --> 类和对象 一、类...

  • Flutter(六) Dart语言基础-面向对象特性

    Dart是一个面向对象的语言,面向对象中非常重要的概念就是类,类产生了对象。今天,我们就具体来学习Dart 中重要...

  • dart快速入门教程 (7.1)

    7.面向对象 dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,所有的类都是Object的子类,...

  • Dart-04 类、对象、mixins

    Dart所有的东西都是对象,所有的对象都继承自Object类。Dart是一门使用类和单继承的面向对象语言,所有的对...

  • flutter【7】dart语言--类

    类 dart 是纯面向对象语言,每个对象都是某个类的实例,并且所有类都是继承自 Object。 dart中继承使用...

网友评论

    本文标题:第7章 Dart面向对象 -- 类和函数

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