Dart入门—类与方法

作者: aries 分类: Flutter 发布时间: 2018-11-16 13:30 ė 1715次浏览 6 0评论

实例变量

声明实例变量时,所有未初始化的实例变量的值为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;

<span class="highlight-n">Point</span><span class="highlight-p">(</span><span class="highlight-kt">int</span> <span class="highlight-n">x</span><span class="highlight-p">,</span> <span class="highlight-kt">int</span> <span class="highlight-n">y</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
    <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">x</span> <span class="highlight-o">=</span> <span class="highlight-n">x</span><span class="highlight-p">;</span>
    <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">y</span> <span class="highlight-o">=</span> <span class="highlight-n">y</span><span class="highlight-p">;</span>
<span class="highlight-p">}</span>

}

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

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

class Point {
int x;
int y;

<span class="highlight-n">Point</span><span class="highlight-p">(</span><span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">x</span><span class="highlight-p">,</span> <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">y</span><span class="highlight-p">);</span>

}

命名构造函数

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

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

class Point {
int x;
int y;

<span class="highlight-n">Point</span><span class="highlight-p">(</span><span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">x</span><span class="highlight-p">,</span> <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">y</span><span class="highlight-p">);</span>

<span class="highlight-c1">// 命名构造函数

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;

<span class="highlight-n">Point</span><span class="highlight-p">(</span><span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">x</span><span class="highlight-p">,</span> <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">y</span><span class="highlight-p">);</span>

<span class="highlight-n">Point</span><span class="highlight-p">.</span><span class="highlight-n">fromJson</span><span class="highlight-p">(</span><span class="highlight-n">Map</span> <span class="highlight-n">jsonMap</span><span class="highlight-p">)</span><span class="highlight-o">:</span> <span class="highlight-n">x</span> <span class="highlight-o">=</span> <span class="highlight-n">jsonMap</span><span class="highlight-p">[</span><span class="highlight-s1">&#39;x&#39;</span><span class="highlight-p">],</span> <span class="highlight-n">y</span> <span class="highlight-o">=</span> <span class="highlight-n">jsonMap</span><span class="highlight-p">[</span><span class="highlight-s1">&#39;y&#39;</span><span class="highlight-p">]</span> <span class="highlight-p">{</span>
    <span class="highlight-n">print</span><span class="highlight-p">(</span><span class="highlight-s2">&#34;In Point.fromJson(): (</span><span class="highlight-si">$</span><span class="highlight-n">x</span><span class="highlight-s2">, </span><span class="highlight-si">$</span><span class="highlight-n">y</span><span class="highlight-s2">)&#34;</span><span class="highlight-p">);</span>
<span class="highlight-p">}</span>

}

重定向构造函数

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

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

class Point {
int x;
int y;

<span class="highlight-n">Point</span><span class="highlight-p">(</span><span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">x</span><span class="highlight-p">,</span> <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">y</span><span class="highlight-p">);</span>

<span class="highlight-n">Point</span><span class="highlight-p">.</span><span class="highlight-n">alongXAxis</span><span class="highlight-p">(</span><span class="highlight-kt">int</span> <span class="highlight-n">x</span><span class="highlight-p">)</span><span class="highlight-o">:</span> <span class="highlight-k">this</span><span class="highlight-p">(</span><span class="highlight-n">x</span><span class="highlight-p">,</span> <span class="highlight-m">0</span><span class="highlight-p">);</span>

}

常量构造函数

想让类生成的对象永远不会改变,可以让这些对象变成编译时常量,定义一个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;

<span class="highlight-kd">static</span> <span class="highlight-kd">final</span> <span class="highlight-n">Map</span> <span class="highlight-n">_cache</span> <span class="highlight-o">=</span> <span class="highlight-p">{};</span>

<span class="highlight-kd">factory</span> <span class="highlight-n">Logger</span><span class="highlight-p">(</span><span class="highlight-kt">String</span> <span class="highlight-n">name</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
    <span class="highlight-k">if</span> <span class="highlight-p">(</span><span class="highlight-n">_cache</span><span class="highlight-p">.</span><span class="highlight-n">containsKey</span><span class="highlight-p">(</span><span class="highlight-n">name</span><span class="highlight-p">))</span> <span class="highlight-p">{</span>
        <span class="highlight-k">return</span> <span class="highlight-n">_cache</span><span class="highlight-p">[</span><span class="highlight-n">name</span><span class="highlight-p">];</span>
    <span class="highlight-p">}</span> <span class="highlight-k">else</span> <span class="highlight-p">{</span>
        <span class="highlight-kd">final</span> <span class="highlight-n">logger</span> <span class="highlight-o">=</span> <span class="highlight-k">new</span> <span class="highlight-n">Logger</span><span class="highlight-p">.</span><span class="highlight-n">_internal</span><span class="highlight-p">(</span><span class="highlight-n">name</span><span class="highlight-p">);</span>
        <span class="highlight-n">_cache</span><span class="highlight-p">[</span><span class="highlight-n">name</span><span class="highlight-p">]</span> <span class="highlight-o">=</span> <span class="highlight-n">logger</span><span class="highlight-p">;</span>
        <span class="highlight-k">return</span> <span class="highlight-n">logger</span><span class="highlight-p">;</span>
    <span class="highlight-p">}</span>
<span class="highlight-p">}</span>

<span class="highlight-n">Logger</span><span class="highlight-p">.</span><span class="highlight-n">_internal</span><span class="highlight-p">(</span><span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">name</span><span class="highlight-p">);</span>

<span class="highlight-kt">void</span> <span class="highlight-n">log</span><span class="highlight-p">(</span><span class="highlight-kt">String</span> <span class="highlight-n">msg</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
    <span class="highlight-k">if</span> <span class="highlight-p">(</span><span class="highlight-o">!</span><span class="highlight-n">mute</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
        <span class="highlight-n">print</span><span class="highlight-p">(</span><span class="highlight-n">msg</span><span class="highlight-p">);</span>
    <span class="highlight-p">}</span>
<span class="highlight-p">}</span>

}

实例方法

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

import "dart:math";

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

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

<span class="highlight-kt">int</span> <span class="highlight-n">distanceTo</span><span class="highlight-p">(</span><span class="highlight-n">Point</span> <span class="highlight-n">other</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
    <span class="highlight-kt">int</span> <span class="highlight-n">dx</span> <span class="highlight-o">=</span> <span class="highlight-n">x</span> <span class="highlight-o">-</span> <span class="highlight-n">other</span><span class="highlight-p">.</span><span class="highlight-n">x</span><span class="highlight-p">;</span>
    <span class="highlight-kt">int</span> <span class="highlight-n">dy</span> <span class="highlight-o">=</span> <span class="highlight-n">y</span> <span class="highlight-o">-</span> <span class="highlight-n">other</span><span class="highlight-p">.</span><span class="highlight-n">y</span><span class="highlight-p">;</span>
    <span class="highlight-k">return</span> <span class="highlight-n">sqrt</span><span class="highlight-p">(</span><span class="highlight-n">dx</span> <span class="highlight-o">*</span> <span class="highlight-n">dx</span> <span class="highlight-o">+</span> <span class="highlight-n">dy</span> <span class="highlight-o">*</span> <span class="highlight-n">dy</span><span class="highlight-p">);</span>
<span class="highlight-p">}</span>

}

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;

<span class="highlight-n">Rectangle</span><span class="highlight-p">(</span><span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">left</span><span class="highlight-p">,</span> <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">top</span><span class="highlight-p">,</span> <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">width</span><span class="highlight-p">,</span> <span class="highlight-k">this</span><span class="highlight-p">.</span><span class="highlight-n">height</span><span class="highlight-p">);</span>

<span class="highlight-kt">int</span> <span class="highlight-kd">get</span> <span class="highlight-n">right</span> <span class="highlight-o">=&gt;</span> <span class="highlight-n">left</span> <span class="highlight-o">+</span> <span class="highlight-n">width</span><span class="highlight-p">;</span>
    <span class="highlight-kd">set</span> <span class="highlight-n">right</span><span class="highlight-p">(</span><span class="highlight-kt">int</span> <span class="highlight-n">value</span><span class="highlight-p">)</span> <span class="highlight-o">=&gt;</span> <span class="highlight-n">left</span> <span class="highlight-o">=</span> <span class="highlight-n">value</span> <span class="highlight-o">-</span> <span class="highlight-n">width</span><span class="highlight-p">;</span>
<span class="highlight-kt">int</span> <span class="highlight-kd">get</span> <span class="highlight-n">botton</span> <span class="highlight-o">=&gt;</span> <span class="highlight-n">top</span> <span class="highlight-o">+</span> <span class="highlight-n">height</span><span class="highlight-p">;</span>
    <span class="highlight-kd">set</span> <span class="highlight-n">botton</span><span class="highlight-p">(</span><span class="highlight-kt">int</span> <span class="highlight-n">value</span><span class="highlight-p">)</span> <span class="highlight-o">=&gt;</span> <span class="highlight-n">top</span> <span class="highlight-o">=</span> <span class="highlight-n">value</span> <span class="highlight-o">-</span> <span class="highlight-n">height</span><span class="highlight-p">;</span>

}

抽象方法

实例、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);
<span class="highlight-n">print</span><span class="highlight-p">(</span><span class="highlight-n">v</span><span class="highlight-p">.</span><span class="highlight-n">x</span> <span class="highlight-o">==</span> <span class="highlight-m">2</span> <span class="highlight-o">&amp;&amp;</span> <span class="highlight-n">v</span><span class="highlight-p">.</span><span class="highlight-n">y</span> <span class="highlight-o">==</span> <span class="highlight-m">3</span><span class="highlight-p">);</span>
<span class="highlight-n">print</span><span class="highlight-p">((</span><span class="highlight-n">v</span> <span class="highlight-o">+</span> <span class="highlight-n">w</span><span class="highlight-p">).</span><span class="highlight-n">x</span> <span class="highlight-o">==</span> <span class="highlight-m">4</span> <span class="highlight-o">&amp;&amp;</span> <span class="highlight-p">(</span><span class="highlight-n">v</span> <span class="highlight-o">+</span> <span class="highlight-n">w</span><span class="highlight-p">).</span><span class="highlight-n">y</span> <span class="highlight-o">==</span> <span class="highlight-m">5</span><span class="highlight-p">);</span>
<span class="highlight-n">print</span><span class="highlight-p">((</span><span class="highlight-n">v</span> <span class="highlight-o">-</span> <span class="highlight-n">w</span><span class="highlight-p">).</span><span class="highlight-n">x</span> <span class="highlight-o">==</span> <span class="highlight-m">0</span> <span class="highlight-o">&amp;&amp;</span> <span class="highlight-p">(</span><span class="highlight-n">v</span> <span class="highlight-o">-</span> <span class="highlight-n">w</span><span class="highlight-p">).</span><span class="highlight-n">y</span> <span class="highlight-o">==</span> <span class="highlight-m">1</span><span class="highlight-p">);</span>

}

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

<span class="highlight-c1">// 重写 + (a+b)

Vector operator +(Vector v) {
return new Vector(x + v.x, y + v.y);
}

<span class="highlight-c1">// 重写 - (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, </span><span class="highlight-n">who</span><span class="highlight-s2">. I am </span><span class="highlight-si">_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 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;
<span class="highlight-kt">void</span> <span class="highlight-n">entertainMe</span><span class="highlight-p">()</span> <span class="highlight-p">{</span>
    <span class="highlight-k">if</span> <span class="highlight-p">(</span><span class="highlight-n">canPlayPiano</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
        <span class="highlight-n">print</span><span class="highlight-p">(</span><span class="highlight-s1">&#39;Playing piano&#39;</span><span class="highlight-p">);</span>
    <span class="highlight-p">}</span> <span class="highlight-k">else</span> <span class="highlight-k">if</span> <span class="highlight-p">(</span><span class="highlight-n">canConduct</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
        <span class="highlight-n">print</span><span class="highlight-p">(</span><span class="highlight-s1">&#39;Waving hands&#39;</span><span class="highlight-p">);</span>
    <span class="highlight-p">}</span> <span class="highlight-k">else</span> <span class="highlight-p">{</span>
        <span class="highlight-n">print</span><span class="highlight-p">(</span><span class="highlight-s1">&#39;Humming to self&#39;</span><span class="highlight-p">);</span>
    <span class="highlight-p">}</span>
<span class="highlight-p">}</span>

}

类的变量和方法

使用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);

<span class="highlight-kd">static</span> <span class="highlight-kt">int</span> <span class="highlight-n">distanceBetween</span><span class="highlight-p">(</span><span class="highlight-n">Point</span> <span class="highlight-n">a</span><span class="highlight-p">,</span> <span class="highlight-n">Point</span> <span class="highlight-n">b</span><span class="highlight-p">)</span> <span class="highlight-p">{</span>
    <span class="highlight-kd">var</span> <span class="highlight-n">dx</span> <span class="highlight-o">=</span> <span class="highlight-n">a</span><span class="highlight-p">.</span><span class="highlight-n">x</span> <span class="highlight-o">-</span> <span class="highlight-n">b</span><span class="highlight-p">.</span><span class="highlight-n">x</span><span class="highlight-p">;</span>
    <span class="highlight-kd">var</span> <span class="highlight-n">dy</span> <span class="highlight-o">=</span> <span class="highlight-n">a</span><span class="highlight-p">.</span><span class="highlight-n">y</span> <span class="highlight-o">-</span> <span class="highlight-n">b</span><span class="highlight-p">.</span><span class="highlight-n">y</span><span class="highlight-p">;</span>
    <span class="highlight-k">return</span> <span class="highlight-n">sqrt</span><span class="highlight-p">(</span><span class="highlight-n">dx</span> <span class="highlight-o">*</span> <span class="highlight-n">dx</span> <span class="highlight-o">+</span> <span class="highlight-n">dy</span> <span class="highlight-o">*</span> <span class="highlight-n">dy</span><span class="highlight-p">);</span>
<span class="highlight-p">}</span>

}

0 flutterdart
换一个
暂无评论
Ɣ回顶部