原谅我的懒惰,我自罚一杯奶茶,已喝上(嚼芋圆)
类
dart是一个面向对象的语言,类是里面一个很重要的概念
定义类的伪代码:
class 类名 {
类型 成员名;
返回值类型 方法名(参数列表) {
方法体
}
}
实例:
main() {}
class Person {
String? name;
int? age;
void eating() {
print(‘${name} is eating’);
}
}
注意一下,我们在print(‘${name} is eating’);这一句代码中,并没有写this,是因为现在的情况是可以省略的,但是下面这种命名有冲突的时候就需要加上this
class Person {
String? name;
int? age;
void eating() {
var name = ‘yyy’;
print(‘${this.name} is eating’);
}
}
使用:
main() {
final p = Person(); // 后续版本new可省略
p.name = ‘yft’;
p.eating();
}
class Person {
String? name;
int? age;
void eating() {
var name = ‘yyy’;
print(‘${name} is eating’); // 此时的name为yyy而不是yft
}
}
当类中没有构造函数时,会默认创建一个无参的函数,上面的例子就是一个无参的构造函数,所有的属性我们都得单独赋值,如果我们希望在创建时就给他赋值,那我们只能自定义构造函数
自定义构造函数
main() {
final p = Person(‘yft’, 20);
p.eating();
}
class Person {
String? name;
int? age;
Person(String name, int age) {
this.name = name;
this.age = age; // 这里使用this也是因为命名冲突
}
void eating() {
var name = ‘yyy’;
print(‘${name} is eating’);
}
}
里面的参数也可以写成可选参数
class Person {
String? name;
int? age;
int? height;
Person(String name, [int? age, int? height]) {
this.name = name;
this.age = age;
this.height = height; // 这里使用this也是因为命名冲突
}
void eating() {
var name = ‘yyy’;
print(‘${name} is eating’);
}
}
上面的写法有点复杂了,下面看看语法糖的写法
class Person {
String? name;
int? age;
int? height;
//原写法
// Person(String name, [int? age, int? height]) {
// this.name = name;
// this.age = age;
// this.height = height; // 这里使用this也是因为命名冲突
// }
// 语法糖, 上面的必须注释掉,因为dart不支持重载
Person(String name, [int? age, int? height]);
// 还可以这么写
Person({this.name, this,age, this.height})
void eating() {
var name = ‘yyy’;
print(‘${name} is eating’);
}
}
现在又有一个问题,假如我有一个Map,我要传给这个构造函数,我要怎么传呢
main() {
Map map1 = {“name”: ‘yft’, “age”: 20, “height”: 156};
final p = Person(map1[‘name’], map1[‘age’], map1[‘height’]);
}
但是我们会发现非常的麻烦,所以我们再写一个构造函数
main() {
Map map1 = {“name”: ‘yft’, “age”: 20, “height”: 156};
final p = Person(map1);
}
class Person {
String? name;
int? age;
int? height;
// Person(String name, [int? age, int? height]);
Person(Map map) {
this.name = map[‘name’];
this.age = map[‘age’];
this.height = map[‘height’];
}
}
但是又有个新的问题,我们上面写的语法糖就得注释掉了,因为两个函数名都是Person,前面写了dart不支持函数重载,需要继续改造
我们可以使用命名构造函数,现在我们多加一个.fromMap试试(这个是自己命名的)
main() {
Map map1 = {“name”: ‘yft’, “age”: 20, “height”: 156};
final p = Person.fromMap(map1);
print(p.height); //156
}
class Person {
String? name;
int? age;
int? height;
Person(String name, [int? age, int? height]); // 放开注释
Person.fromMap(Map map) {
this.name = map[‘name’];
this.age = map[‘age’];
this.height = map[‘height’];
}
}
初始化列表
现在我们写一个面积计算的类
void main(List args) {
final p = Rectangle(10, 20 )
}
class Rectangle {
int? width;
int? height;
int? area;
Rectangle(this.width, this.height) {
this.area = (width ?? 0) * (height ?? 0);
// 需要做一下判断,不然会报错;或者在上面直接给出初始值为0
}
}
重写toString
为什么要重写这个方法呢,因为我们在打印我们的实例对象的时候会自动调用toString方法,所以得到的是这个东西 Instance of ‘Rectangle’
void main(List args) {
final re = Rectangle(10, 20);
print(re); // Instance of ‘Rectangle’
}
class Rectangle {
int? width;
int? height;
int? area;
Rectangle(this.width, this.height) {
this.area = (width ?? 0) * (height ?? 0);
}
}
显然没有任何的用处,如果我们想要看里面的属性,那么每次都要单独取值,所以我们重写一下这个方法
void main(List args) {
final re = Rectangle(10, 20);
print(re); //width:10, height:20, area: 200
}
class Rectangle {
int? width;
int? height;
int? area;
Rectangle(this.width, this.height) {
this.area = (width ?? 0) * (height ?? 0);
}
@override
String toString() {
return “width:$width, height:$height, area: $area”;
}
}
在开发中会经常用到这个方法
其实上面的内容,还可以更加简洁,我们不用再大括号中对area进行初始化,可以改成下面这样
class Rectangle {
int? width;
int? height;
int? area;
int? xxx;
Rectangle(this.width, this.height)
: area = (width ?? 0) * (height ?? 0),
xxx = (width ?? 0) * 3;
// 有多个用逗号隔开即可
@override
String toString() {
return “width:$width, height:$height, area: $area”;
}
}
这就是初始化列表
重定向构造函数
其实他的意思就是,在一个构造函数中调用另一个构造函数,主要作用是: 当一个类需要通过多个不同的方式进行初始化,但这些方式的初始化逻辑相似时,重定向构造函数可以将重复的逻辑集中到一个地方。
现在我们看一个需求
假设我们有一个 Rectangle 类,可以通过不同的方式创建矩形,比如使用长和宽,或使用边长(正方形)。我们希望在这两种情况下使用相同的初始化逻辑。
可以这样写
class Rectangle {
int? width;
int? height;
int? area;
Rectangle(this.width, this.height) : area = (width ?? 0) * (height ?? 0);
Rectangle.square(int side) : this(side, side); // 这里的this就是上面的构造函数
}
void main(List args) {
final rectangle = Rectangle(10, 20);
print(rectangle.area); // 200
final square = Rectangle.square(10);
print(square.area); //100
}
工厂构造函数
功能:工厂构造函数用于控制对象的创建。在这个例子中,Person 类实现了一个简单的单例模式(或对象缓存),即相同名字的 Person 对象只会被创建一次,后续调用将返回缓存的对象。
逻辑:如果 _cache 中已存在这个名字的 Person 对象,则直接返回这个对象。如果不存在,则调用私有构造函数 Person._internal(name) 创建新对象 p,然后将其存入 _cache 中,并返回这个新对象。
class Person {
String? name;
static final Map _cache = {};
factory Person(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final p = Person._internal(name);
_cache[name] = p;
return p;
}
}
Person._internal(this.name);
}
void main(List args) {
final p1 = Person(‘yft’);
final p2 = Person(‘yft’);
print(identical(p1, p2)); //true,这个方法用于检查两个引用是否指向同一个对象。
}
嗯我学累了,大脑需要消化一下,看会书休息了。
此刻:
我放着咖啡厅的音乐假装自己在咖啡厅,点着香薰,喷点香水,好舒服。我最近学习很开心,觉得充满着动力^ ^ 🥰
最近看的书里有一句话我觉得很棒,我需要分享出来,拜拜啦👋🏻
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/423521.html