Dart语言基础(二)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


函数

可选的位置参数

要指定可选的位置参数,请使用方括号 [ ] 。

void function_name(param1,[optional_param1,optional_param2]){ }

如果未传递可选参数,则将其设为null。

viod main(){
   test(123);
}

// 可选参数添加可空标识符
test(int n,[String? m]){   
  print(n);    // 123
  print(m);    // null
}

可选的命名参数

与位置参数不同,必须在传递值时指定参数的名称,花括号 { } 可用于指定可选的命名参数。

void function_name(a,{optional_param1,optional_param2}){ }

示例

void main(){
   test(123,s1:'hello');
   test(123,s2:'hello',s1:'world')
}

// 可选的命名参数要不给予一个默认值,要不添加关键字required表示该命名参数必须要赋值
test(int n,{required String s1,String s2='world'}){
   print(n);
   print(s1);
   print(s2);
}

带有默认值的可选参数

默认情况下,还可以为函数参数指定值,但是,这些参数也可以显式传递值。

function_name(param1,{param2 : defalut_value}){ }

示例

void main(){
   test(123);
}
void test(n,{s1:12}){
   print(n);
   print(s1);
}

注:函数中所有必须参数必须要写在可选参数之前。

匿名函数

创建没有名字的函数。这种函数被称为匿名函数。

([[Type] param1[, ...]]) { codeBlock;};

示例

void main() { 
   var list = ['apple', 'bananas', 'oranges'];
   list.forEach((item){
      print('${list.indexOf(item)}: $item');
   });
}

如果函数只有一条语句,可以使用箭头简写。

list.forEach((item) => print('${list.indexOf(item)}: $item'));

Lambda函数

Lambda函数是表示函数的简洁机制,这些函数可以使用箭头简写。

void main(){
    printMsg();
    print(test());            
}
printMsg() => print('hello');
int test() => 123;

内嵌函数

在Dart中,支持函数的嵌套,嵌套函数可以访问上一层的函数变量。例如在该示例中,内嵌函数push()可以访问夫函数的count变量:

int add(){
  var count = 0;
  int plus() {
     count += 1;
   }
   plus();
   return count;
}

main(){
  print(add());
  print(add());
  print(add());
}

自执行函数

在Dart中,可以定义一个没有函数名的并且在定义完成后自己执行一次。

mian(){
  (x,y) {
     print('$x,$y');
  }(3,5);
}

闭包

闭包是一种保护私有变量的机制,在函数执行是形成私有的作用域,保护里面的私有变量不受外界干扰,直观的说就是形成一个不销毁的栈环境。

声明方式

class class_name {
    <Fields>
    <getters/setters>
    <constructors>
    <functions>
}

示例

class Car {
   // field
   String engine = 'EA888';

   // function
   void disp() {
   print(engine);
   }
}

构造函数

默认构造函数,在实例化时,自动得调用

class Point {
    num x, y;
    // 默认构造函数
    Point() {
    print('这是默认的构造函数,实例化时,会被第一个调用。');
    }
}

class Car {
    // late String engine;
    String? engine;
    Car(String engine){
    this.engine = engine;
    print('This engine is : ${engine}');
    }
}

class Book {
   String name;
   String autor;
   
   Book(this.name,this.autor);
}

void main() {
    Point p = Point();
    Car car = Car('EA888');
    Book b = Book('西游记''吴承恩');
    print(p.x);
    print('${b.name}, ${b.autor}');
    // The engine is EA888
    // 这是默认的构造函数,实例化时,会被第一个调用。
    // null
    // 西游记,吴承恩
}

命名构造函数

在类中可以使用命名构造函数 (类名.函数名)实现多个构造器。

class_name.constructor_name(param_list);

示例

void main() {
   Car c1 = Car.namedConst('EA888');
   Car c2 = Car();
   // 在dart中,例如DateTime
   DateTime d = DateTime.now();
}

class Car {
   String wheels;
   Car() {
      print('Non-parameterized constructor invoked');
   }
   Car.namedConst(String engine) {
      print('The engine is : ${engine}');
   }
   
   Car.namedConst2(this.wheels);
}

常量构造函数

如果类生成的对象不会改变,可以通过常量构造函数使这些对象成为编译时常量

class Book {
   // 属性必须通过 final 声明
   final String name;
   final String author;
   // 常量构造函数,必须通过const声明
   const Book(this.name,this.author);
}

viod main() {
  // 通过常量构造函数创建参数相同的对象时,内存中只保留一份
  //  声明不可变对象,必须通过const关键字
  var b1 = const Book('西游记','吴承恩');
  var b2 = const Book('西游记','吴承恩');
  print(b1 == b2); // true

  // 常量构造函数,可以当作普通构造函数使用
  var b3 = new Book('西游记','吴承恩');
  var b4 = new Book('西游记','吴承恩');
  print(b3 == b4); // false

  // 实例化时,new关键词可以省略
  var b5 = Book('西游记','吴承恩');
  var b6 = Book('西游记','吴承恩');
  print(b5 == b6); // false
}

identical

检查两个引用是否指向同一个对象

class Book {
   // 属性必须通过 final 声明
   final String name;
   final String autor;
   // 常量构造函数,必须通过const声明
   const Book(this.name,this.author);
}

// 声明不可变对象,必须通过const关键字
   var b1 = const Book('西游记''吴承恩');
   var b2 = const Book('西游记''吴承恩');
   print(b1 == b2); // true
   print(identical(c1,c2)); // true

   // 常量构造函数,可以当作普通构造函数使用
   var b3 = Book('西游记''吴承恩');
   var b4 = Book('西游记''吴承恩');
   print(b3 == b4); // false
   print(identical(c3,c4)); // false

工厂构造函数

通过factory声明,工厂函数不会自动生成实例,而实通过代码来决定返回的实例

class Car {
  int wheels;
  static Car? instance;
  // 命名构造函数
  Car.newCar(this.wheels){
    print('我执行了一次');
  }
  // 工厂构造函数 -- 接受一个可选参数并赋默认值4
  factory Car([int wheels = 4]) {
    // 工厂构造函数中,不能使用this关键字
    //  print(this.wheels);
    // 如果instance为空,则实例化并把值赋给instance
    // ??= 赋值运算符表示的是左边的值是否为空,如果为空,则把右边的值赋给左边
    return instance ??= Car.newCar(wheels);
  }
}

void main() {
   Car c1 = Car(6);
   Car c2 = Car();
   print(c1.wheels); // 6
   print(c2.wheels); // 6
   print(c1 == c2); // true
}

Getter,Setter

默认的getter/setter与每个类相关联。但是,可以通过显式定义getter/setter来覆盖默认值。getter没有参数并返回一个值,setter只有一个参数但不返回值。

class Student {
   String name;
   int age;
   
   get studentName {
      return name;
   }
   set studentName(String name) {
      this.name = name;
   }
   
   get studentAge {
      return age;
   }
   
   set studentAge(int age) {
      this.age = age;
   }
}

void main() {
   Student s = new Student();
   s.studentName = '张三';
   print('${s.studentName}');
   s.studentAge = 18;
   print('${s.studentAge}');
   
}

访问修饰符

Dart没有访问修饰符,在Dart类中,默认的访问修饰符是公开的,如果要使用私用属性,需要同时满足以下两个条件:

  • 属性或方法以 _(下划线)开头
  • 只有把类单独抽离出来,私有属性和方法才起作用,因为同一个文件下不存在私用的情况
class Person {
   String name;
   // 声明私有属性
   num _age = 8;
   Person(this.name);
   num getAge() {
      return this._age;  
   }
}
import 'lib/Person.dart';

void main() {
   Person p = new Person('jeck');
   print(p.name);
   print(p.getAge());
}

抽象类

在Dart中,没有接口,只有抽象类使用abstract class表示。通过使用关键字implements可以多实现,通过使用关键字extends可以继承,只能单继承。

abstract class A {
   late String name;
   printA();
}

abstract class B {
   printB();
}

class C implements A,B {
   
   late String name;
   
   printA() {
      print('A');
   }
   
   
   printB() {
      print('B');
   }
}

mixins

在Dart中本不可以实现多继承,利用mixins可实现类似多继承的功能。

  • 作为mixins的类只能继承自Object,不能继承其他类。
  • 作为mixins的类不能有构造函数。
  • 一个类可以mixins多个mixins类。
  • mixins绝不是继承,也不是接口,而是一种全新的特性。
class A {
   String info = 'this is A';
   void printA() {
      print('A');
   }
}

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

class Person {
   String name;
   num age;
   Person(this.name,this.age);
   
   void printInfo() {
      print('name is ${this.name}, age is ${this.age}');
   }
}

//使用with关键字实现mixins
class C with A,B {}

// 即继承自Person有mixins A和B,with后跟的类有顺序之分,后类的方法会覆盖前类的方法
class D extends Person with A,B {}

void main() {
   var c = new C();
   c.printA(); // A
   c.printB(); // B
   print(c.info); // This is A
}

mixins的类型就是其超类的子类型。

class A {
   String info = 'this is A';
   void printA() {
      print('A');
   }
}

class B {
   String info = 'this is B';
   void printB() {
      print('B');
   }
}

class C with A,B {}

void main() {
  var c = C();
  // 如果混入的类中存在相同属性和方法,后面的类会把覆盖前面的类的属性和方法
  print(c.info);  // this is B
  print(c is C); // true
  print(c is A); // true
  print(c is B); // true
}

extends,implements,with可以同时使用,但是有前后顺序:extends - with- implements。

class A extends B with C, D implements E, F {}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值