Getter 和 Setter在 Dart 中,对 Getter 和 Setter 方法有专门的优化 。即便没有声明,每个类变量也会默认有一个get方法,在隐含接口章节会有体现 。
class Rectangle {num left, top, width, 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;}void main() {var rect = Rectangle(3, 4, 20, 15);assert(rect.left == 3);rect.right = 12;assert(rect.left == -8);}
抽象类Dart 的抽象类和Java差不多,除了不可以实例化,可以声明抽象方法之外,和一般类没有区别 。
abstract class AbstractContainer {num _width;void updateChildren(); // 抽象方法,强制继承子类实现该方法 。get width => this._width;int sqrt(){return _width * _width;}}
隐含接口Dart 中的每个类都隐含了定义了一个接口,这个接口包含了这个类的所有成员变量和方法,你可以通过implements关键词来重新实现相关的接口方法:
class Person {//隐含了 get 方法final _name;Person(this._name);String greet(String who) => 'Hello, $who. I am $_name.';}class Impostor implements Person {// 需要重新实现get _name => '';// 需要重新实现String greet(String who) => 'Hi $who. Do you know who I am?';}
实现多个接口:
class Point implements Comparable, Location {...}
继承和Java基本一致,继承使用extends关键词:
class Television {void turnOn() {doSomthing();}}class SmartTelevision extends Television {@overridevoid turnOn() {super.turnOn(); //调用父类方法doMore();}}
重载操作符比较特别的是,Dart 还允许重载操作符,比如List类支持的下标访问元素,就定义了相关的接口:
E operator [](int index);
我们通过下面的实例来进一步说明重载操作符:
class MyList{var list = [1,2,3];operator [](int index){return list[index];}}void main() {var list = MyList();print(list[1]); //输出 2}
扩展方法这个特性也是Dart让人眼前一亮的地方(Dart2.7之后才支持),可以对标到 JavaScript 中的 prototype 。通过这个特性,你甚至可以给类库添加新的方法:
//通过关键词 extension 给 String 类添加新方法extension NumberParsing on String {int parseInt() {return int.parse(this);}}
后面String对象就可以调用该方法了:
print('42'.parseInt());
枚举类型枚举类型和保持和Java的关键词一致:
enum Color { red, green, blue }
在switch中使用:
// color 是 enmu Color 类型switch(color){case Color.red:break;case Color.blue:break;case Color.green:break;default:break;}
枚举类型还有一个index的getter,它是个连续的数字序列,从0开始:
assert(Color.red.index == 0);assert(Color.green.index == 1);assert(Color.blue.index == 2);
新特性:Mixins这个特性进一步增强了代码复用的能力,如果你有写过Android的布局XML代码或者Freemaker模板的话,那这个特性就可以理解为其中inlclude 的功能 。
声明一个mixin类:
mixin 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');}}}
通过with关键词进行复用:
class Musician extends Performer with Musical {// ···}class Maestro extends Personwith Musical, Aggressive, Demented {Maestro(String maestroName) {name = maestroName;canConduct = true;}}
mixin类甚至可以通过on关键词实现继承的功能:
mixin MusicalPerformer on Musician {// ···}
类变量和类方法class Queue {//类变量static int maxLength = 1000;// 类常量static const initialCapacity = 16;// 类方法static void modifyMax(int max){_maxLength = max;}}void main() {print(Queue.initialCapacity);Queue.modifyMax(2);print(Queue._maxLength);}
泛型在面向对象的语言中,泛型主要的作用有两点:
1、类型安全检查,把错误扼杀在编译期:
var names = List<String>();names.addAll(['Seth', 'Kathy', 'Lars']);//编译错误names.add(42);
2、增强代码复用,比如下面的代码:
abstract class ObjectCache {Object getByKey(String key);void setByKey(String key, Object value);}abstract class StringCache {String getByKey(String key);void setByKey(String key, String value);}
你可以通过泛型把它们合并成一个类:
abstract class Cache<T> {T getByKey(String key);void setByKey(String key, T value);}
推荐阅读
- PHP 安全问题入门:10 个常见安全问题 + 实例讲解
- 混元太极拳入门须知及修炼纲要
- hacker入门方向
- 买8折奔驰还是9折的奥迪?豪华入门级车型怎么选
- macOS 10.15 新手入门,使用技巧分享
- 黑客入门利器,dvwa文件上传漏洞,带你进入黑客大门
- mysql入门级,20分钟搞定
- IP地址基础入门知识
- 最经典的黑客技术入门知识大全
- GNOME Linux 桌面入门