简单易懂的Dart基础语法,类和对象。
Dart中的类
使用关键字class声明一个类。可以使用new创建构造函数,所有的对象默认都集成Object类
void main() {
LGPerson p = LGPerson();
p.run();
}
class LGPerson {
String? name;
int? age;
void run() {
print('name: $name, age: $age');
}
}

赋值的话使用点语法:
p.name = 'hello';
p.age = 18;
在Dart中默认会生成getter和setter方法,属性和方法都通过.语法来访问。注意:final修饰的属性必须要有初始值。在Dart中方法是不能重载的。本质的原理是方法的名称是寻找方法的唯一标识
class LGPerson {
String? name;
int? age;
void run() {
print('name: $name, age: $age');
}
int run() {
return 10;
}
}

在Dart中,用一份文件下里面的方法都是可以访问的,是不在私有化的。对于不想暴露出来的属性和方法我们可以这么处理:新创建一个Dart文件,注意命名规范。

然后把Person类放到这里的lg_person.dart文件里,此时main中引用会报错:找不到该文件。解决的办法是,选中main中的LGPerson然后option + 回车,这里就自动导入了头文件import lg_person.dart,
对于类中的属性和方法,只要加上_前缀外界就不能访问。但是在lg_person.dart这个文件内是可以访问。所谓的私有其实是跨文件。
class LGPerson {
String? name;
int? age;
void _run() {
print('name: $name, age: $age');
}
}

Dart中的构造函数
在Dart中默认会生成构造函数,但是我们也可以自定义
class LGPerson {
String? _name;
int? _age;
void _run() {
print('name: $_name, age: $_age');
}
LGPerson(int age, String name) {
_name = name;
_age = age;
_run();
}
}
这里需要注意一点:如果构造函数的形参和属性保持一致的话,那么外层LGPerson p = LGPerson(18, 'hello')赋值是不会成功的

Dart有一个语法糖写法更优美, 而且String也不用给默认值。
class LGPerson {
String _name;
int _age;
void run() {
print('name: $_name, age: $_age');
}
LGPerson(this._age, this._name);
}
属性一旦使用final修饰的话,这个就是个最终变量,所以中途不能被修改。

final修饰的成员变量可以不用一开始就给初始值,可以在构造函数中赋值。final实际应用场景:当一个对象的所有成员属性都是使用final来修饰的话,那么这个对象可以被创建为常量对象,使用const修饰构造函数。
class LGPerson {
final String _name;
final int _age;
void run() {
print('name: $_name, age: $_age');
}
const LGPerson(this._age, this._name); /// const修饰构造函数
// 命名构造函数
const LGPerson.withName(this._name, this._age);
}
构造函数的另外一种写法:命名构造函数
// 命名构造函数
LGPerson.withName(this._name, this._age);
#### Dart的工厂构造&单例对象
void factoryDemo(){
FactoryClass fact1 = FactoryClass('hello',12);
FactoryClass fact2 = FactoryClass('hello',12);
print(fact1 == fact2);
}
如果想让fact1 == fact2有什么办法?我们想到上面介绍的常量对象,那么来试一下
class FactoryClass {
final String name;
final int age;
const FactoryClass(this.name, this.age);
}

很明显使用常量对象并不可以,那么怎么做呢?
class FactoryClass {
// 需要一个单例对象
static FactoryClass _instance;
factory FactoryClass(){
if(_instance == null){
_instance = FactoryClass._init()
}
return _instance!;
}
// 私有的命名构造函数
FactoryClass._init();
}

注意:在Dart中,我们发现构造函数是没有return的,如果想要return的话需要加上关键字factory,修改之后成了下面这样:
class FactoryClass {
// 需要一个单例对象
static FactoryClass? _instance;
factory FactoryClass(){
if(_instance == null){
_instance = FactoryClass._init();
}
return _instance!;
}
// 私有的命名构造函数
FactoryClass._init();
}
我们其实还可以优化:
class FactoryClass {
// 需要一个单例对象
static FactoryClass? _instance;
// 利用前面学过的为空赋值运算“??=”
factory FactoryClass(){
_instance ??= FactoryClass._init();
return _instance;
}
// 私有的命名构造函数
FactoryClass._init();
}
继续化简能够得到:
class FactoryClass {
// 需要一个单例对象
static FactoryClass? _instance;
factory FactoryClass(){
return _instance ??= FactoryClass._init();;
}
// 私有的命名构造函数
FactoryClass._init();
}
还能继续化简,当方法的执行语句只有一句的时候,可以使用箭头函数=>表达式
class FactoryClass {
// 需要一个单例对象
static FactoryClass? _instance;
factory FactoryClass() => _instance ??= FactoryClass._init();
// 私有的命名构造函数
FactoryClass._init();
}
此时再次打印来验证单例是否创建成功

初始化列表
初始化列表的目的:给final变量赋值;校验传递的参数。
class LGPerson {
String name;
int age;
final height;
LGPerson(this.name, this.age, int h):
height = h, assert(h > 0){
print('name:$name,age:$age,height:$height');
}
}
void factoryDemo(){
LGPerson p = LGPerson('hello', 18, 0);
}
这里报错,是因为校验h>0没有通过

LGPerson p = LGPerson('hello', 18, 1);

转载自:https://juejin.cn/post/7020964484365680676