面向对象
类与对象,声明、创建及基本特性
构造方法及初始化列表
静态成员及对象操作符的使用
类与对象
- 使用关键字class声明一个类
- 使用关键字new创建一个对象,new可以省略
- 所有对象都继承与Object类
属性与方法
- 属性默认会生成getter和setter方法
- 使用final声明的属性只有getter方法
- 属性和方法通过 . 访问
- 方法不能被重载
void main(){
//可以省略new
//var person = new Person();
var person = Person();
//赋值和获取值
person.name = "Tom";
person.age = 20;
print(person.name);
print(person.address);
person.work();
}
class Person{
String name;
int age;
final String address;
void work(){
print("Name is $name,Age is $age,He is working...")
}
}
类及成员可见性
- Dart中的可见性以library(库)为单位
- 默认情况下,每一个Dart文件就是一个库
- 使用_表示库的私有性(类、属性、方法)
- 使用import导入库
计算属性
(自定义getter和setter方法)
- 计算属性的值是通过计算而来,本身不存储值
- 计算属性赋值,其实是通过计算转换到其他实例变量
void main(){
var rect = new Rectangle()
rect.height = 20;
rect.width =10;
print(rect.area);
rect.area = 200;
print(rect.width);
}
class Rectangle{
num width,height;
num get area{
return width*height;
}
set area(value){
//高度先写死
width = value/20;
}
}
构造方法
- 如果没有自定义构造方法,则会有个默认构造方法
- 如果存在自定义构造防范,则默认构造方法无效
- 构造方法不能重载
class person{
String name;
int age;
final String gender;
//构造方法
person(this.name,this.age,this.gender){
//是可以打印出值的,说明语法糖的赋值操作是在构造方法执行之前
//语法糖的方式可以对final属性赋值
print(name);
}
}
命名构造方法
- 使用命名构造方法,可以实现多个构造方法(弥补构造方法不能重载)
- 使用类名**.**方法的形式实现
void main(){
var person = new Person("Jim",20,"Male");
new Person.withName("Jone");
}
class person{
String name;
int age;
final String gender;
//构造方法
person(this.name,this.age,this.gender);
//命名构造方法
Person.withName(String name){
this.name = name;
}
}
常量构造方法
- 如果类是不可变状态,可以把对象定义为编译时常量
- 使用const声明构造方法,并且所有变量都为final
- 使用const声明对象,可以省略
void main(){
var person = Person("Jim",20,"Male");
}
class person{
final String name;
final int age;
final String gender;
//构造方法
const person(this.name,this.age,this.gender);
}
在对象所有属性只需赋值一次的情况下使用常量构造方法,常量在运行时效率也更高,因为在编译时期已经确定了
工厂构造方法
- 工厂构造方法类似于设计模式中的工厂模式
- 在构造方法前添加关键字factory实现一个工厂构造方法
- 在工厂构造方法中可返回对象
class Logger{
final String name;
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){
print(msg);
}
}
初始化列表
- 初始化列表会在构造方法体执行之前执行
- 使用逗号分隔初始化表达式
- 初始化列表常用于设置final变量的值
void main(){
var person = Person("Jim",20,"Male");
}
class person{
final String name;
final int age;
final String gender;
语法糖可以给final赋值
person(this.name,this.age,this.gender);
//初始化列表给final赋值
Person.withMap(Map map):gender = map["gender"]{
this.name = map["name"];
this.age = map["age"];
}
//同样普通属性也可以用初始化列表方式,用逗号分隔
Person.withMap(Map map):name = map["name"],age = map["age"] gender = map["gender"]{
}
}
静态成员
- 使用static关键字来实现类及别变量和函数
- 静态成员不能访问非静态成员,非静态成员可以访问静态成员
- 类中的常量需要使用static const 声明
- 不能使用对象.方法访问静态方法,只能通过类名.方法名访问,与java相同
对象操作符
- 条件成员访问:?.
void main(){
Person person;
//对象为空?后面逻辑就不执行了,很方便的处理了空指针的问题
person?.name;
person?.work();
}
class person{
String name;
int age;
void work(){
print("working...");
}
}
- 类型转换:as
void main(){
var person;
person = "";
person =new Person();
(person as Person).work();
}
- 是否制定类型:is ,is!
void main(){
var person;
person = "";
person =new Person();
if(person is Person){
person.work();
}
}
- 级联操作:. .
void main(){
new Person()
..name ="Tom"
..age = "20"
..work();
}
赋值后返回对象然后可以继续赋值,和build模式是不是一样样的
对象call方法
之前讲过方法可以作为对象来使用,在Dart中对象也可以作为方法来使用
- 如果类实现了 call()方法,则该类的对象可以作为方法使用
void main(){
var person = new Person();
print(person("Test",30));
}
class Person{
String name;
int age;
String call(String name,int age){
return "Name is $name,Age is $age";
}
}
小结
- 类声明、对象创建、属性、方法、可见性、计算属性
- 构造方法、命名构造方法、常量构造方法、工厂构造方法
- 初始化列表、静态成员、操作符、call方法