类与对象
- 使用关键字 class 声明一个类
- 使用关键字 new 创建一个对象,new 可以省略
- 所有对象都继承于 Object 类
对象的基础定义与创建
// 定义一个Person类
class Person{
}
void main(){
//创建方式一: 可以通过 new 关键字创建
Person person = new Person();
// 创建方式二:直接使用 Person()
Person person1 = Person();
}
属性和方法
- 属性默认会生成 getter 和 setter 方法
- 使用 final 声明的属性只有 getter 方法
- 属性和方法通过 . 访问
- 方法不能被重载
图:final 属性报错图示
图:方法不能重载报错图示
类以及成员可见性
- Dart 中的可见性以 library(库)为单位
- 默认情况下,每一个 Dart 文件就是一个库
- 使用 _ 表示库的私有性
- 使用 import 导入库
将成员变量或者方法加上 “_” 就表示私有的(;类似于 Java 中的 private),在另外一个 dart 文件中就无法访问。
A类的 属性 或者 方法 如果是以下划线开头命名的,则在 B类 则不能访问A类的属性和方法。
如果 A类 声明也是下划线开头命名的则 A类的访问范围只能在 A类 所处的 dart 文件,出了这个 dart 文件的范围 在别的文件是访问不到的。
类的计算属性
前面介绍的是存储属性,是可以存入这个类的一些特性的值
- 顾明思议,计算属性的值是通过计算而来,本身不存储值
- 计算属性赋值,其实是通过计算转换到其他实例变量
计算属性指的是和一般的类成员属性一样,具有 getter 与 setter 方法,但是不能作为存储值使用,只能返回的是结算之后的结果值。
class Rectangle {
num width, heigth;
/** 计算属性的写法 */
//这个写法和下面的写法一致 num get area { return width * heigth; }
num get area => width * heigth;
void set area(value) {
width = width / 20;
}
}
void main(List<String> args) {
var rect = new Rectangle();
rect.heigth = 20;
rect.width = 10;
// 获取属性
print(rect.area); // 200
// 设置属性
rect.area = 2; // 将宽度修改为 0.5
print(rect.area); // 10
}
构造方法
关于构造方法的几点总结:
- 如果没有自定义构造方法,则会有个默认构造方法
- 如果存在自定义构造方法,则默认构造方法无效
- 构造方法不能重载
- 使用命名构造方法,可以实现多个构造方法
- 使用类名.方法的形式实现
默认的构造方法 与 带参数的构造方法
class Person{
String name;
int age;
// 默认的构造方法,无参的构造方法可以省略
// Person (){}
// 带参数的构造方法
Person(String name, int age){
this.name = name;
this.age = age;
}
//带参数的构造方法还可以写成这种格式 Person(this.name, this.age){}
}
构造方法不能重载,多个构方法同时存在会报错
给 final 关键字修饰的属性赋值
class Person {
String name;
int age;
final String gender;
// 通过构造器给 final 修饰的属性赋值
Person(this.age, this.name, this.gender);
}
多个构造方法同时存在的情况
class Person{
String name;
int age;
// 默认的构造方法,无参的构造方法可以省略
Person (){}
// 带参数的构造方法
Person.withName(String name){
this.name = name;
}
Person.withNameAndAge(this.name, this.age){}
}
void main(List<String> args) {
Person person = new Person();
Person person1 = new Person.withName("name");
Person person2 = new Person.withNameAndAge("name", 12);
}
常量构造方法声明
- 如果类是不可变状态,可以把对象定义为编译时常量
- 使用 const 声明构造方法,并且所有变量都为 final
- 使用 const 声明对象,可以省略
重要说明:
要声明常量类需要使用 const 修饰,并且还需要所声明类有 常量构造方法 。
const 修饰的构造方法叫常量构造方法,所有属性也必须用final修饰。
工厂构造方法
- 工厂构造方法类似于设计模式中的工厂模式
- 在构造方法前添加关键字 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 属性赋值。看图中 Person.withMap ( Map map ) 这一段