Flutter-Dart语法二

面向对象特性

1.类(class )

Dart是一个面向对象编程语言,同时支持基于mixin的继承机制。每个对象都是一个类的实例,所有的类都继承于object。

1)构造函数
构造函数不能继承。父类的命名构造函数也不会被继承,如果子类也有父类一样命名构造函数,就必须在子类中自己实现该构造函数。

  • 默认构造函数:如果未显式定义构造函数,会默认一个参数为空的构造函数。默认构造函数会调用父类的无参构造函数。
class  Person { //未定义父类的时候,默认继承自Object
  num x;
  num y;
  num z;
}

void main(List<String> args){
  var person = new Person();//调用默认的构造函数
  person.x = 10;   //使用点(.)引用实例变量或方法
  person.y = 11;
}
  • 类名构造函数:就是一个与类同名的函数,关键字 this 是指当前实例,只有在命名冲突时有效,否则dart会忽略处理。

class Point {
    int x;
    int y;
  //自己定义的类名构造函数
  Point(int x, int y) {
      this.x = x;
    this.y = y;
   }
   
   // 在构造函数里初始化成员属性是很常见的事情,因此Dart开发了新的语法糖来简化这种操作
   // 比如将Point的类名构造构造函数改写成

   // Point(this.x, this.y);
  // 注意x,y的赋值会在构造函数执行之前完成.
   
}
void main(){
    var point = new Point(1, 2);
}

  • 命名构造函数:(类名.函数名)使用命名构造函数可以为类提供多个构造函数。
class Point {
  num x, y;

  Point(this.x, this.y);

  // 命名构造函数
  Point.origin() {
    x = 0;
    y = 0;
  }
  // 简化
  // Point.origin(this.x,this.y);
  
}

  • 重定向构造函数:有时构造函数的唯一目的是重定向到同一类中的另一个构造函数。重定向构造函数的主体为空,构造函数调用出现在冒号( :)之后 。
    大意就是在创建类时,我定义一个命名构造函数,但是这个构造函式的主体我不实现。直接通过:调用另外一个构造函数,实现对外界传入的参数的接收并赋值给内部的变量。
class Point {
  num x, y;
  //类名构造函数
  Point(this.x, this.y);
  // 命名构造函数
 Point.order(this.x,this.y);
 Point.origin(num a,num b):this.order(a,b);  
 //重定向构造函数,origin构造函数将外界的传值,指向给了order构造函数。
}

  • 工厂构造函数:在实现一个构造函数时使用factory关键字,该构造函数并不总是创建其类的新实例。例如,工厂构造函数可能会从缓存中返回实例,也可能会返回子类型的实例。工厂构造者对this没有访问权限。
class Logger {
  final String name;
  bool mute = false;

 // _cache是私有变量
 //_在名称前,表示该变量为私有
  static final Map<String, Logger> _cache = <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
     } else {
       final logger = Logger._internal(name);
       _cache[name] = logger;
       return logger;
    }
  }

  Logger._internal(this.name);
  void log(String msg) {
    if (!mute) print(msg);
   }
}


调用:
var logger = Logger('UI');
logger.log('Button clicked');

  • 常量构造函数:如果你的类创建的对象从不改变,你可以创建一些编译时的常量对象。因此,定义一个const构造函数,且保证所有的对象变量都是final。
class ImmutablePoint {
  final num x;
  final num y;
  const ImmutablePoint(this.x, this.y);
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);
}

注意:如果父类中没有默认的构造函数,你必须手动调用父类的构造函数,在子类的构造函数体之前通过(:) 指定调用父类构造函数,示例如下:

// Person类中没有一个无参数,未命名的构造函数
class Person {
  String firstName;
  // 命名构造函数
  Person.fromJson(Map data) {
    print('in Person');
  }
}

class Employee extends Person {
  // 你必须调用父类的super.fromJson(data).
  Employee.fromJson(Map data) : super.fromJson(data) {
    print('in Employee');
  }
}

main() {
  var emp = new Employee.fromJson({});
}


2.实例变量

声明实例变量时,所有未初始化的实例变量的值为null。
每个实例变量都会自动生成一个getter方法,Non-final(没有被final修饰)实例变量还会自定生成一个setter方法。

class Point{
  num x;//声明实例变量x,初始化为空
  num y;//声明实例变量y,舒适化为空
  num z = 0;//声明实例变量z,初始化为0
  //如果在实例变量定义的时候初始化该变量(不是在构造函数或者其他方法中初始化),该值是在实例化对象的时
  //候初始化的,也就是在构造函数和初始化参数列表执行之前。
  
}
void main() {
  var point = new Point();
  point.x = 4;              //使用setter方法对x变量赋值
  print(point.x == 4);      //输出true 使用getter获取x变量的值
  print(point.y == null);   //输出true

}

静态(类)变量:使用static关键字来实现类级别的变量和方法,静态函数内部不能访问非静态成员,非静态函数能访问静态成员。

class Queue {
  // 静态变量在使用之前不会初始化
  static const initialCapacity = 16;
  // ···
}

void main() {
  assert(Queue.initialCapacity == 16);
}

3.方法

1)实例方法
对象的实例函数可以访问this。
import 'dart:math';

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

  num distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

2)类方法
使用static 修饰的方法,内部不能访问实例变量,没有访问this的权限。

class Page{
  // 添加 static 关键字
  static int currentPage = 1;
  num size ;
  
  //类方法
  static void scorllDown(){
    currentPage = 1;
    // 访问实例变量报错
    // size = 10;
    print("ScrollDown...");
  }
 
  void scorllUp(){
    currentPage ++;
    print("ScrollUp...");
  }
}

void main(List<String> args) {
  var page = new Page();
  // 调用类方法
  Page.scorllDown();
}


3)Getters和Setters 方法
Getters 和setters是用来设置和访问对象属性的特殊函数。每个实例变量都隐含的具有一个getter,如果变量不是final的则还有一个setter。使用get和set关键字定义getter和setter。

class Rectangle {
  num left;
  num top;
  num width;
  num height;

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

  // 定义两个计算属性:右和下。
  num get right             => left + width;
      set right(num value)  => left = value - width;
  num get bottom            => top + height;
      set bottom(num value) => top = value - height;
}

main() {
  var rect = new Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

4)抽象函数

抽象函数是只定义函数接口但是没有实现的函数,由子类来实现该函数。如果用分号来替代函数体则这个函数就是抽象函数。

abstract class Doer {
  // ...定义实例变量和方法...

  void doSomething(); // 定义一个抽象方法.
}

class EffectiveDoer extends Doer {
  void doSomething() {
    // ...提供实现,因此此处的方法不是抽象的...
  }
}

4.抽象类

使用abstract修饰符定义一个抽象类,一个不能被实例化的类。抽象类通常用来定义接口,如果你想实例化抽象类,你必须实现抽象类,才能被实例化。

// 这个类是抽象类,不能实例化
abstract class AbstractContainer {
  // ...定义构造函数, 变量, 方法...

  void updateChildren(); // 抽象方法.
}

class SpecializedContainer extends AbstractContainer {
  // ...定义更多的构造方法, 方法...

  void updateChildren() {
    // ...实现 updateChildren()...
  }

}


5.隐式接口

Dart中没有哪个关键字是来定义接口的, 默认情况下所有的类类都是都是隐式的接口,包括类的方法和属性。当将一个类当做接口使用时,那么实现这个接口的类,必须实现这个接口中所有的方法。

// A person. 隐式接口包含greet().
class Person {
  // 在接口中,但仅在此库中可见
  final _name;

  // 不在接口中,因为这是构造函数
  Person(this._name);

  // 在接口中
  String greet(who) => 'Hello, $who. I am $_name.';
}

// 实现Person 接口
class Imposter implements Person {
  // 我们必须定义这个,但我们不使用它。
  final _name = "";

  String greet(who) => 'Hi $who. Do you know who I am?';
}

6.类的继承

使用extends创建子类,super引用父类,子类可以重写实例方法、getter和setter,使用@override注释重写,使用@proxy注释来忽略警告

class Person {
  
 void run{
     print('people run');
 }
 
}

class Kids{
    @override
    void run{
     print('Kids run');
 }
}



重写object的noSuchMethod()
当用户调用你定义的类中不存在的属性与方法时,通过重写noSuchMethod(),可以做出一些响应。
class A {
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: ' +
        '${invocation.memberName}');
  }
}


7.访问控制

默认类中的所有属性和方法是public的。在dart中,可以在属性和方法名前添加“_”使私有化。

class Animal{
  String _name;   // 私有属性
  int age; 
  //默认构造函数的简写
  Animal(this._name,this.age);

  void printInfo(){   
    print("${this._name}----${this.age}");
  }

// 供外部调用私有属性
  String getName(){ 
    return this._name;
  } 
  // 私有方法
  void _run(){
    print('这是一个私有方法');
  }

  execRun(){
    this._run();  //类里面方法的相互调用
  }
}


void main(){
 
 Animal a=new Animal('小狗', 3);

 print(a.getName());

  a.execRun();   //间接的调用私有方法

}

8.枚举类型

枚举中的每个值都有一个index索引,它返回枚举声明中值的从零开始的位置。例如,第一个值具有索引0,第二个值具有索引1。

enum Color { red, green, blue }

assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);

可以在switch语句中使用枚举,如果不处理枚举的所有值,将会收到警告。

9.泛型

泛型就是定义的一个类型,类型暂不确定,给使用给一个占位符给代替,在使用的时候可以给确定其定义的类型。

main() {
// 如果自己希望List只包含字符串对象。则可以定义为List<String>代表("list of string")。

   List Tech = new List<String>();
   Tech.addAll(['Android','IOS','Flutter']);
   Tech.add(42);//运行时报错
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349