一. 类与对象
- 使用
class
关键字声明一个类
- 可以使用
new
跟上构造函数
- 所有的对象都继承
Object
- Dart中默认会生成
getter
和setter
方法
- 变量/方法前加_表示只能在这个文件内部访问
void main() {
Person p = Person();
p.showDetail(); //name=flutter, age=2, height=null
Person p1 = new Person();
p1.name = 'flutter_new';
p1.height = 0;
p1.showDetail();//name=flutter_new, age=2, height=0
}
class Person {
String name = 'flutter';
final int age = 2;
int? height;
showDetail() {
print('name=$name, age=$age, height=$height');
}
}
二.构造函数
1.重写构造方法
- 一旦有了新的构造方法,默认构造方法会失效。不能使用
Person()
创建对象
void main() {
//不能使用Person()创建对象
Person p = Person('flutter_new', 1, 1);
p.showDetail(); //name=flutter_new, age=1, height=1
}
class Person {
String name = 'flutter';
late final int? age;
int? height;
Person(String n, int a, int h) {
name = n;
age = a;
height = h;
}
showDetail() {
print('name=$name, age=$age, height=$height');
}
}
2.使用this关键字的构造方法
-
this
与self
类似,表示当前对象
- 当构造函数使用
this
后,变量可以不设定初始值
void main() {
Person p = Person('flutter_new', 2, 1);
p.showDetail(); //name=flutter_new, age=2, height=1
}
class Person {
String name;
final int? age;
int? height;
//相当于直接将传入的参数赋值给name,age,height
Person(this.name, this.age, this.height);
showDetail() {
print('name=$name, age=$age, height=$height');
}
}
3.构造方法中有可选参数
void main() {
Person p = Person('flutter_new');
p.showDetail(); //name=flutter_new, age=null, height=null
Person p1 = Person('flutter_new', height: 10);
p1.showDetail(); //name=flutter_new, age=null, height=10
}
class Person {
String name;
final int? age;
int? height;
Person(this.name, {this.age, this.height});
showDetail() {
print('name=$name, age=$age, height=$height');
}
}
4.命名构造方法
void main() {
Person p = Person.withName('flutter_new');
p.showDetail(); //name=flutter_new, age=null, height=null
Person p1 = Person.withName('flutter_new', age: 2);
p1.showDetail(); //name=flutter_new, age=2, height=null
}
class Person {
String name;
final int? age;
int? height;
Person.withName(this.name, {this.age, this.height});
showDetail() {
print('name=$name, age=$age, height=$height');
}
}
5.初始化列表
- 给final变量赋值
- 校验传递的值
- 如果asset不满足条件,程序会报错
- 执行的顺序为先调用assert,然后通过this赋值,最后执行{}
void main() {
Person p = Person.withName('fultter_new', 1, 0); //name=fultter_new, age=1, height=0
Person p1 = Person.withName('flutter_old', 2, 2); //name=flutter_old, age=2, height=2
}
class Person {
String name;
final int? age;
int? height;
Person.withName(this.name, int age, int height) : this.age = age, this.height = height, assert(age>0) {
print('name=$name, age=$age, height=$height');
}
}
6.Dart中最常见的构造方法
- 由于Flutter底层的增量渲染逻辑,绝大部分类的成员变量,全部使用final修饰
- 表明创建的对象是不可变的,符合底层逻辑设计
class Person {
final String? name;
final int? age;
final int? height;
const Person({this.name, this.age, this.height});
}
三.单例
void main() => print(FactoryClass() == FactoryClass()); //true
class FactoryClass {
static FactoryClass? _instance;
factory FactoryClass() => _instance ??= FactoryClass._init();
FactoryClass._init();
}
四.类方法
- 静态方法/变量,与其它语言类似,使用关键字
static
- 静态方法可以访问静态属性,不能访问实例属性
- 实例方法可以访问静态属性,可以访问实例属性
void main() {
print(StaticClass.name); //flutter
StaticClass.name = 'flutter_new';
print(StaticClass.name); //flutter_new
StaticClass.changeName('flutter_old');
print(StaticClass.name); //flutter_old
print(StaticClass().sumWithStaticAge(20)); //30
}
class StaticClass {
static String name = 'flutter';
static int staticAge = 10;
int age = 0;
static changeName(String newName) {
name = newName;
}
sumWithStaticAge(int newAge) {
this.age = newAge;
return age + staticAge;
}
}
五.对象操作符
-
?
,使用在对象后面表明对象可空。(类似swift)
-
as
, 将对象类型强转到另一个类型,前提逻辑得没问题(类似于swift中as?/as!
)
-
is
,判断对象是不是某个类型(类似swift)
-
..
,调用..,执行了方法后,会返回self。链式编程
void main() {
instanceOperator();
}
instanceOperator() {
//?
var obj;
obj = Object();
obj = InstanceOperatorClass();
obj.test(); //it's ok!
obj = null;
/*
如果不使用obj?.test(),程序会报错。因为你使用了一个null去调用实例方法。
如果使用了?后,如果obj为null。不会执行该方法。
*/
obj?.test();
//as
obj = InstanceOperatorClass();
(obj as InstanceOperatorClass).test(); //it's ok!
//is
if (obj is InstanceOperatorClass) {
obj.test(); //it's ok!
}
/* ..
* 调用..,执行了方法后,会返回self。链式编程
*
*/
print(obj..test()..test());
/*
it's ok!
it's ok!
Instance of 'InstanceOperatorClass'
*/
}
class InstanceOperatorClass {
test() {
print('it\'s ok!');
}
}
六.Dart继承
- 使用
extend
关键字继承一个类
- 使用
override
关键字继承方法
- 子类会继承除了构造方法以外的属性和方法
- 继承的子类会自动继承默认构造方法
- Dart是单继承
- 如果父类有自定义构造方法,子类必须显性的调用super的任意一个构造方法
void main() {
FlutterBook flutterook = FlutterBook();
flutterook.name = 'Flutter';
flutterook.price = 50;
print(flutterook.isExpensive); //false
//多态
flutterook.learnExtends(); //learn extends of flutter...
flutterook.readBook(); //read FlutterBook...
Book book = FlutterBook();
flutterook.name = 'Flutter_book';
flutterook.price = 60;
print(flutterook.isExpensive); //true
if (book is FlutterBook) {
flutterook.learnExtends(); //learn extends of flutter...
flutterook.readBook(); //read FlutterBook...
print(book); //Flutter
}
}
class FlutterBook extends Book {
final String? subName;
//因为父类有3种构造方法,因此需要创建3个构造方法的任意一个/自己写一个。
// FlutterBook.withName(String? name) : super.withName(name);
// FlutterBook.init() : super.init();
// FlutterBook(String? name) : super(name);
FlutterBook({String? name}) : subName = name, super.init();
@override
readBook() {
// TODO: implement readBook
print('read FlutterBook...');
}
learnExtends() {
print('learn extends of flutter...');
}
/*
* 类似于iOS中的describtion
*/
@override
String toString() {
// TODO: implement toString
return 'Flutter';
}
}
class Book extends Object {
//默认会继承默认构造方法
// Book() {
// print('Book init');
// }
String? name;
double? price;
Color? _color;
bool get isExpensive => price! > 50;
Book(this.name);
Book.init();
Book.withName(this.name);
readBook() {
print('read book...');
}
}
七.Dart中抽象类和接口
- 不能被实例化的类,使用
abstract
修饰
- 类型与iOS中协议很像
void main() {
AbstractClass as = SubClass();
as.sum(1, 2); //a + b = 3
}
/*
* 抽象类
* 不能被实例化的类,使用abstract修饰
* 类型与iOS中协议很像
*/
abstract class AbstractClass {
//抽象方法
int sum(int a, int b);
}
class SubClass extends AbstractClass {
@override
int sum(int a, int b) {
print('a + b = ${a + b}');
return a + b;
}
}
void main() {
SubClass as = SubClass();
as.sum(1, 2); //a + b = 3
as.sum1(1, 2); //a x b = 2
as.sum2(1, 2); //a ~/ b = 0
}
/*
* 抽象类
* 不能被实例化的类,使用abstract修饰
* 类型与iOS中协议很像
*/
abstract class AbstractClass {
//抽象方法
int sum(int a, int b);
}
abstract class AbstractClass1 {
//抽象方法
int sum1(int a, int b);
}
abstract class AbstractClass2 {
//抽象方法
int sum2(int a, int b);
}
class SubClass implements AbstractClass, AbstractClass1, AbstractClass2 {
@override
int sum(int a, int b) {
print('a + b = ${a + b}');
return a + b;
}
@override
int sum1(int a, int b) {
print('a x b = ${a * b}');
return a * b;
}
@override
int sum2(int a, int b) {
print('a ~/ b = ${a ~/ b}');
return a~/b;
}
}
八.Mixins混入
-
Mixins
就是多继承
- 格式为
class 类名 extends A with B + C
。
void main() {
MixinsClass mc = MixinsClass();
mc.sum(1, 2); //a ~/ b = 0
}
class MixinsClass extends ClassA with ClassB, ClassC {}
//当MixinsClass没有成员/方法时,可以使用下面这种方法实现混入。
// class MixinsClass = ClassA with ClassB, ClassC;
class ClassA {
sum(int a, int b) {
print("a + b = ${a + b}");
return a + b;
}
}
class ClassB {
sum(int a, int b) {
print("a * b = ${a * b}");
return a * b;
}
}
class ClassC {
sum(int a, int b) {
print("a ~/ b = ${a ~/ b}");
return a ~/ b;
}
}
- 可以看出上面的ClassA、ClassB、ClassC的方法名都是sum,执行的是ClassC中的sum。当继承的所有类的方法一致时,执行最后继承的。
void main() {
MixinsClass mc = MixinsClass();
mc.sum(1, 2); //a + b = 3
mc.sum1(1, 2); //a * b = 2
mc.sum2(1, 2); //a ~/ b = 0
}
class MixinsClass = ClassA with ClassB, ClassC;
class ClassA {
sum(int a, int b) {
print("a + b = ${a + b}");
return a + b;
}
}
class ClassB {
sum1(int a, int b) {
print("a * b = ${a * b}");
return a * b;
}
}
class ClassC {
sum2(int a, int b) {
print("a ~/ b = ${a ~/ b}");
return a ~/ b;
}
}
九.运算符重载
- 使用关键字
operator
- 格式为
返回值类型+operator+运算符+(参数列表){}
void main() {
OperatorClass oc1 = OperatorClass(30);
OperatorClass oc2 = OperatorClass(20);
print(oc1 > oc2); //false
print(oc1 + oc2); //50
}
class OperatorClass {
final int num;
OperatorClass(this.num);
bool operator > (OperatorClass other) => this.num > other.num;
int operator + (OperatorClass other) => this.num + other.num;
}
网友评论