Dart入门04 -- 类,构造函数,setter,getter
2022-02-19 本文已影响0人
YanZi_33
类
- Dart 是一种面向对象的语言,具有类和基于 mixin 的继承,每个对象都是一个类的实例,所有类都来自
Object
类; - Dart 使用
class
关键字表示一个类,对象具有由函数和数据(分别为方法和实例变量)组成的成员,我们通过 new 关键字来创建一个实例对象; - Dart关于class类的定义,与
Java
完全类似;
void main(List<String> args) {
Person person = new Person("yanzi", 33);
person.run();
person.eat();
}
class Person {
//属性成员
String name;
int age;
//构造方法
Person(String name, int age) {
this.name = name;
this.age = age;
}
//实例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
- 构造函数:类的构造函数,是用来创建实例对象的函数;
默认构造函数
- 当class没有自定义构造函数时,系统会默认生成无参的构造函数;
void main(List<String> args) {
//无参构造函数
Person person = new Person();
person.run();
person.eat();
}
class Person {
//属性成员
String name;
int age;
//实例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
自定义构造函数
- 如果class自定义了构造函数,那么默认构造函数为Person()就会被覆盖,不能使用了;
void main(List<String> args) {
Person person = new Person("yanzi", 33);
person.run();
person.eat();
}
class Person {
//属性成员
String name;
int age;
//自定义构造函数
Person(String name, int age) {
this.name = name;
this.age = age;
}
//实例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
- 上述自定义构造函数,可采用语法糖的简洁写法,如下所示:
void main(List<String> args) {
Person person = new Person("yanzi", 33);
person.run();
person.eat();
}
class Person {
//属性成员
String name;
int age;
//自定义构造函数 -- 语法糖
Person(this.name, this.age);
//实例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
命名构造函数
- 为构造函数,定义一个指定的名称;
void main(List<String> args) {
Person person = Person.withNameAndAge("yanzi", 32);
person.run();
person.eat();
Person person1 = Person.fromMap({"name": "li", "age": 30});
person1.run();
person1.eat();
}
class Person {
//属性成员
String name;
int age;
//命名构造函数
Person.withNameAndAge(this.name, this.age);
Person.fromMap(Map<String, dynamic> map) {
this.name = map["name"];
this.age = map["age"];
}
//实例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
-
withNameAndAge
与fromMap
,都是Person类的命名构造函数,有自己独有的函数名称;
构造函数包含可选参数
- 在构造函数中,支持可选参数,在调用构造函数时,对于可选参数,可传或者不传;
void main(List<String> args) {
Person person1 = Person("yanzi");
Person person2 = Person("sss", age: 22);
Person person3 = Person.init("aaa");
Person person4 = Person.init("cccc", age: 26);
}
class Person {
String name;
int age;
//其中age为可选参数
Person(String name, {int age}) {
this.name = name;
this.age = age;
}
//其中age为可选参数
Person.init(this.name, {this.age});
}
初始化列表
- 与C++的语法类似;
- 初始化列表的使用
只能在构造函数中
; - 在构造函数的小括号后面,使用
冒号:
连接初始化的列表;
main(List<String> args) {
var p = Person("SF");
print(p.age);
}
class Person {
//被final修饰的变量为常量 只能被赋值一次
final String name;
final int age;
//初始化列表与C++语法类似
//创建对象时,若传入age,那么就使用传入的age,如果没有传入age,那么使用默认值10,age为可选参数
Person(this.name, {int age}) : this.age = age ?? 10 {
//在执行此大括号的代码时,对象已经初始化完毕了
//必须保证在执行此大括号的代码之前,final修饰的name与age必须已经初始化
//所以下面代码报错
//this.age = 10;
}
//存在局限性
//Person(this.name, {this.age = 10});
}
-
Person(this.name, {int age}) : this.age = age ?? 10
:初始化列表,在执行大括号中的代码之前,完成对象的初始化; - 可以在构造的时候初始化一些参数值,对于一些
final修饰的属性
初始化以后固定值不会在变,使用初始化列表,就非常合适;
重定向构造函数
-
在一个构造函数中,去调用另一个构造函数
,注意⚠️是在冒号
后面使用this进行调用
;
main(List<String> args) {
var p = Person("SF");
print(p.age); //22
}
class Person {
String name;
int age;
//调用自定义构造函数Person._internal
Person(String name) : this._internal(name, 22);
Person._internal(this.name, this.age);
}
常量构造函数
- 在某些情况下,
传入相同值时
,我们希望返回同一个对象
,这个时候,可以使用常量构造方法; - 默认情况下,创建对象时,即使传入相同的参数,创建出来的也不是同一个对象,但是若在构造函数前加上
const
进行修饰,那么可以保证同一个参数,创建出来的对象是相同的,这样的构造函数称之为常量构造函数
;
main(List<String> args) {
const p1 = Person("liyanyan");
const p2 = Person("liyanyan");
//p1与p2是同一个对象
print(identical(p1, p2));
}
class Person {
final String name;
const Person(this.name);
}
- 注意常量构造函数,只存在一个final属性;
- 拥有常量构造函数的类中,所有的成员变量必须是final修饰的;
工厂构造函数
- Dart提供了
factory
关键字,用于通过工厂
去获取对象; - 普通的构造函数,会默认返回创建出来的对象,而工厂构造函数,
需要手动返回一个对象
; - 案例代码:
main(List<String> args) {
final p1 = Person.withName("liyanyan");
final p2 = Person.withName("liyanyan");
print(identical(p1, p2)); //true
}
class Person {
//对象属性
String name;
String color;
//类属性
static final Map<String, Person> _nameCache = {};
static final Map<String, Person> _colorCache = {};
//工厂构造函数
//1.根据key值从缓存中获取对象,存在直接返回,不存在
factory Person.withName(String name) {
if (_nameCache.containsKey(name)) {
return _nameCache[name];
} else {
final p = Person(name, "default");
_nameCache[name] = p;
return p;
}
}
factory Person.withColor(String color) {
if (_colorCache.containsKey(color)) {
return _colorCache[color];
} else {
final p = Person("default", color);
_colorCache[color] = p;
return p;
}
}
Person(this.name, this.color);
}
- 用
final
修饰变量,保证变量不被胡乱修改;
setter与getter方法
- setter方法中,可使用关键字
set
; - getter方法中,可使用关键字
get
;
void main(List<String> args) {
Person person4 = Person.init("cccc", age: 26);
person4.setNamee("ssssss");
print(person4.name);
print(person4.getNamee());
person4.name = "gggg";
print(person4.name);
print(person4.getNamee());
}
class Person {
String name;
int age;
//其中age为可选参数
Person.init(this.name, {this.age});
//使用set,get关键字的setter,getter方法
set setName(String name) {
this.name = name;
}
String get getName {
return this.name;
}
//不采用set,get关键字的setter,getter方法
void setNamee(String name) {
this.name = name;
}
String getNamee() {
return this.name;
}
}
- setter与getter方法中使用了
set
与get
关键字,格式如代码所示; - setter与getter方法中可以使用
箭头函数
,更加简便; - Dart中属性的get/set方法名是可以任意取;