Dart入门—类与方法

Dart入门—类与方法

实例变量

声明实例变量时,所有未初始化的实例变量的值为null

void main(){
    var point = new Point();
    point.x = 4;
    print(point.x);
    print(point.y);
}

class Point {
    int x;      // null
    int y;      // null
    int z = 0;  // 0
}

构造函数

声明构造函数

如果你没有声明构造函数,默认有构造函数,默认构造函数没有参数,调用父类的无参构造函数。子类不能继承父类的构造函数

构造函数就是一个与类同名的函数,关键字 this 是指当前的,只有在命名冲突时有效,否则dart会忽略处理

void main(){
    var point = new Point(4, 5);
}

class Point {
    int x;
    int y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

一个实例变量分配一个构造函数参数会使语法更简单

void main(){
    var point = new Point(1, 3);
}

class Point {
    int x;
    int y;

    Point(this.x, this.y);
}

命名构造函数

使用命名构造函数让类有多个构造函数

void main(){
    var point = new Point.fromJson({‘x‘:2, ‘y‘:4});
}

class Point {
    int x;
    int y;

    Point(this.x, this.y);

    // 命名构造函数
    Point.fromJson(Map json) {
        x = json[‘x‘];
        y = json[‘y‘];
    }
}

父类的构造函数

子类构造函数调用父类的默认构造函数,如果父类没有默认构造函数,必须手动调用父类的构造函数,在 : 号后面指定父类的构造函数

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

class Person {
    Person.fromJson(Map data) {
        print("in Person");
    }
}

class Employee extends Person {
    Employee.fromJson(Map data) : super.fromJson(data) {
        print("in Employye");
    }
}

初始化实例变量

除了调用父类的构造函数,还可以在构造函数体运行之前初始化实例变量

void main(){
    var emp = new Point.fromJson({‘x‘:5, ‘y‘:6});
}

class Point {
    int x;
    int y;

    Point(this.x, this.y);

    Point.fromJson(Map jsonMap): x = jsonMap[‘x‘], y = jsonMap[‘y‘] {
        print("In Point.fromJson(): ($x, $y)");
    }
}

重定向构造函数

构造函数可以重定向到同类的另一个构造函数

void main(){
    var emp = new Point.alongXAxis(7);
}

class Point {
    int x;
    int y;

    Point(this.x, this.y);

    Point.alongXAxis(int x): this(x, 0);
}

常量构造函数

想让类生成的对象永远不会改变,可以让这些对象变成编译时常量,定义一个const构造函数并确保所有实例变量是final的

void main(){
    var emp = new ImmutablePoint(7, 8);
}

class ImmutablePoint {
    final int x;
    final int y;
    const ImmutablePoint(this.x, this.y);
    static final ImmutablePoint origin = const ImmutablePoint(0, 0);
}

工厂构造函数

使用factory关键字实现构造函数时,不一定要创建一个类的新实例,例如,一个工厂的构造函数可能从缓存中返回一个实例,或者返回一个子类的实例

void main(){
    var logger = new Logger("UI");
    logger.log("Button clicked");
}

class Logger {
    final String name;
    bool mute = false;

    static final Map<String, Logger> _cache = <String, Logger>{};

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

    Logger._internal(this.name);

    void log(String msg) {
        if (!mute) {
            print(msg);
        }
    }
}

实例方法

实例对象可以访问实例变量和方法

import "dart:math";

void main(){
    var point = new Point(12, 24);
}

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

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

getter和setter

getter和setter是特殊的方法,可以读写访问对象的属性,每个实例变量都有一个隐式的getter,适当的加上一个setter,可以通过实现getter和setter创建附加属性,使用get和set关键词

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

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

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

    int get right => left + width;
        set right(int value) => left = value - width;
    int get botton => top + height;
        set botton(int value) => top = value - height;
}

抽象方法

实例、getter和setter方法可以是抽象的,抽象方法使用分号 ; 而不是方法体

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

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

class EffectiveDoer extends Doer {
    void doSomething() {
      //...实现一个抽象方法...
    }
}

重写运算符

您可以覆盖的运算符:<、+、|、[]、>、/、^、[]=、<= 、~/、&、~、>=、*、<<、==、– 、%、>>

void main(){
    final v = new Vector(2, 3);
    final w = new Vector(2, 2);

    print(v.x == 2 && v.y == 3);
    print((v + w).x == 4 && (v + w).y == 5);
    print((v - w).x == 0 && (v - w).y == 1);
}

class Vector {
    final int x;
    final int y;
    const Vector(this.x, this.y);

    // 重写 + (a+b)
    Vector operator +(Vector v) {
        return new Vector(x + v.x, y + v.y);
    }

    // 重写 - (a-b)
    Vector operator -(Vector v) {
        return new Vector(x - v.x, y - v.y);
    }
}

抽象类

使用abstract修饰符定义的抽象类不能被实例化,抽象类用于定义接口,常用于实现,抽象类里通常有抽象方法,有抽象方法的不一定是抽象类

abstract class AbstractContainer {
  //...定义构造函数,字段、方法...

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

隐式接口

每个类都有一个隐式定义的接口,包含所有类和实例成员,通过implements子句声明一个类实现一个或多个接口,然后提供所需的api接口

void main(){
    print(greetBob(new Person("kathy")));
    print(greetBob(new Imposter()));
}

class Person {
    final _name;
    Person(this._name);
    String greet(who) => "Hello, $who. I am $_name.";
}

class Imposter implements Person {
    final name = "";
    String greet(who) => "Hi $who. Do you know who I am?";
}

greetBob(Person person) => person.greet("bob");

实现多个接口

class Point implements Comparable, Location {
    // ...
}

类的继承

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

class Television {
    void turnOn() {
        _illuminateDisplay();
        _activateIrSensor();
    }
}

class SmartTelevision extends Television {
    void turnOn();
    _bootNetworkInterface();
    _initializeMemory();
    _upgradeApps();
}

枚举类型

枚举类型是一种特殊的类,用于表示一个固定数量的常量值,不能实例化,使用enum关键字声明一个枚举类型

void main(){
    print(Color.red.index);     // 0
    print(Color.green.index);   // 1
    print(Color.blue.index);    // 2

    // 获得枚举值的列表
    List<Color> colore = Color.values;
    print(colore[2]);   // Color.blue

    // 在switch语句中使用枚举
    Color aColor = Color.blue;
    switch(aColor) {
        case Color.red:
            print("Red as Roses!");
            break;
        case Color.green:
            print("Green as grass!");
            break;
        default:
            print(aColor);
    }
}

enum Color {
    red,
    green,
    blue
}

扩展类

使用with关键字后面跟着一个或多个扩展类名

class Musician extends Performer with Mnsical {
    // ...
}

class Maestro extends Person with Musical, Aggressive, Demented {
    Maestro(String maestroName) {
        name = maestroName;
        canConduct = true;
    }
}

要实现扩展类,创建一个没有构造函数,没有父类调用的类

abstract class Musical {
    bool canPlayPiano = false;
    bool canCompose = false;
    bool canConduct = false;

    void entertainMe() {
        if (canPlayPiano) {
            print(‘Playing piano‘);
        } else if (canConduct) {
            print(‘Waving hands‘);
        } else {
            print(‘Humming to self‘);
        }
    }
}

类的变量和方法

使用static关键字实现类的变量和方法

静态变量

静态变量即类变量,是类的常量

void main(){
    print(Color.red.name);  // red
}

class Color {
    // 静态常量
    static const red = const Color("red");
    // 不可变的实例变量
    final String name;
    // 构造常量函数
    const Color(this.name);
}

静态方法

静态方法即类方法,没有实例,因此无法通过实例访问

import "dart:math";

void main(){
    var a = new Point(2, 2);
    var b = new Point(4, 4);
    var distance = Point.distanceBetween(a, b);
    print(distance);    // 2.8284271247461903
}

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

    static int distanceBetween(Point a, Point b) {
        var dx = a.x - b.x;
        var dy = a.y - b.y;
        return sqrt(dx * dx + dy * dy);
    }
}
时间: 2024-10-28 21:08:20

Dart入门—类与方法的相关文章

《java入门第一季》之类(String类常见方法小叙)

String类下面的构造方法和一些常见的方法: /* * 字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. * 通过查看API,可以知道 * A:字符串字面值"abc"也可以看成是一个字符串对象. * B:字符串是常量,一旦被赋值,就不能被改变. * * 构造方法: * public String():空构造 * public String(byte[] bytes):把字节数组转成字符串 * public String(byte[] bytes,int index,i

Dart入门—控制流程与其他

Dart入门-控制流程与其他 控制流程 if~else if语句和可选的else语句,简单的if语句可以用条件运算符( ? : )来处理 if (isRaining()) { you.bringRainCoat(); } else if (isSnowing()) { you.wearJacket(); } else { car.putTopDown(); } for 使用for循环进行迭代 var message = new StringBuffer("Dart is fun");

Dart入门—Linux开发环境

Dart入门-Linux开发环境 在正文开始前,希望大家能看一下这段,我第一次听说Dart是在去年5月份,那段时间工作比较闲,在网上看到<Google 演示用 Dart 开发 Android 应用>,然后就开始去了解,而且认识了很多朋友,其中就有"河马",他说:"Dart所有的资料都是英文的,我们需要建立一个中文社区,让更多人了解.学习它". 后来他真的就建立了DartLang中文社区,我当时就觉得我应该也能做点什么,于是就组织了几个好友对Dart的官方

Dart入门—集合类型

Dart入门-集合类型 Dart核心库提供了List(列表).Map(映射).Set(集)三种集合类型 列表(List) 固定长度的列表,一旦定义就无法改变长度 List<int> fixedLengthList = new List(5); fixedLengthList[0] = 87; print(fixedLengthList); print(fixedLengthList[0]); 可改变长度的列表,可以根据需要改变长度 List<int> growableList =

Dart入门?一篇文章就够了!

近期公司准备启动新项目,经过技术团队一番调研,决定采用 Flutter 来开发第一版App,故作此文,常来回顾温习.由于项目采用敏捷开发模式,故本文主要总结和记录 Dart 常用语法,更多高级和生僻用法将在后面开发过程中不定期更新. First of all 在我们正式接触 Dart 语法之前,需要铭记以下内容,这将会对后续 Dart 语法的学习.理解和应用有很大帮助: 万物皆对象, 每个对象都是一个类的实例.在 Dart 中,甚至连数字.方法和 null 都是对象,并且所有的对象都继承于 Ob

反射之获取类,方法等

1 反射之获取类      获取类有三种方法 public interface Person { public void sayHi(); }   public class Student  implements Person{ private String id; private String name; private int age; public int sex=1; //省去构造方法和get set方法 } Class c1 = Student.class; Class c2=Clas

【Android 工具类】经常使用工具类(方法)大全

收集经常使用的工具类或者方法: 1.获取手机分辨率 /** * 获取手机分辨率 */ public static String getDisplayMetrix(Context context) { if (Constant.Screen.SCREEN_WIDTH == 0 || Constant.Screen.SCREEN_HEIGHT == 0) { if (context != null) { int width = 0; int height = 0; SharedPreferences

PHP类和对象之定义类的方法

方法就是在类中的function,很多时候我们分不清方法与函数有什么差别,在面向过程的程序设计中function叫做函数,在面向对象中function则被称之为方法. 同属性一样,类的方法也具有public,protected 以及 private 的访问控制. 访问控制的关键字代表的意义为:public:公开的protected:受保护的private:私有的 我们可以这样定义方法: class Car { public function getName() { return '汽车'; }

c#类的方法表的建立和方法的调用

对于方法的调用,很是令我头疼,什么静态方法,实例方法,实例虚方法,这里查了很多资料,总结如下: 这里声明,我也是菜鸟,这里只讨论方法的调用相关的技术,属于个人理解,如有错误,请指正 思路: 1 clr在加载类型的过程中方法表是怎么样构建的? 2 在程序调用方法时是怎样确定使用哪个类型的方法表的? 3 在程序调用方法时是怎样确定方法在方法表中的位置的(位于方法表的第几个方法)? 一 .方法在方法表中的排列顺序: 继承的实例虚方法.实例虚方法.构造函数.静态方法.实例方法 方法表排列原则: 1 在类