
声明:
// 所有的类都集成于Object ,Object没有父类class Person1 {//定义属性String name;int age;String _sex; //通过下划线定义私有属性//构造函数Person1(this.name,this.age);//定义实例方法void fun1() {}//重写父类方法@overrideString toString() {// TODO: implement toStringreturn 'name: $name, age: $age';}
创建实例
var person = Person1('wei',18);person.fun1();
构造函数
默认构造函数
默认构造函数,如果类没有显示声明构造函数,那么就有默认构造函数,默认构造函数是与类同名且无参数无返回值的函数。
class Person3{String name;int age;//未声明,默认}
自定义构造函数
可选参数、默认参数
class Person2 {String name;int age;String city;String country;//自定义构造方法{}中为可选参数, this.country = 'china' 参数设置默认值Person2(this.name,this.age,{this.city,this.country ='China'});
}
void main() {var person = Person2('wei', 18);print('name: $person.name,age:$person.age');//调用可选参数需要 paramName: value的形式指定为哪个可选参数赋值:如cityvar person1 = Person2('dong', 18,city: '济南');print('city: $person.city');}
<a name="FOBOJ"></a>### 命名构造方法可以为类声明多个构造函数的方式
class Person3{ String name; int age; //命名构造函数:类名+.+方法名 Person3.run(String name, int age){ this.name = name; this.age = age; }
Person3.run2(String name){this.name = name;}
}
<a name="qbyqM"></a>### 工厂构造方法- 使用factory修饰- 也是单例模式- 构造函数内有返回值,类型是当前类或子类```dart///工厂构造方法演示class Logger {static Logger _cache;// 工厂构造方法:// 不仅仅是构造方法,还是单例模式factory Logger() {if (_cache == null) {_cache = Logger._internal();}return _cache;}Logger._internal();void log(String msg) {print(msg);}
}
* **命名工厂构造方法*** factory 类名+.+方法,其实就是在命名构造方法前面加 factory* 一种灵活获取类对象的方式
class Person3{ String name; int age; //工厂命名构造函数 factory 类名+.+方法名 factory Person3.run3(String name){ print(name) } }
* **静态构造方法*** 类的对象不会改变* 类的变了不会改变=》常量* 使用final修饰变量* 创建实例时,使用const
class Class1{ final int a; final String b; const Class04(this.a,this.b); void fun01(){ print(“aa”); } } void main(){ var class06 = const Class1(4, “ccc”); class06.fun01(); print(class06.a); }
* **重定向构造函数**在类的构造函数中,有时我们只是需要调用到另一个构造函数。
class Class05{ int a; String b; Class05(int a,String b){ this.a = a; this.b = b; } Class05.fun1(int a){ this.a = a; } Class05.fun2(String b):this.fun1(33);//重定向到fun1 Class05.fun3(String b):this(33,”ddddd”);//重定向到构造函数 }
## setters 和 getters* 修饰属性* 使用set赋值* 使用get获取值
class Person5 {
String _school; //私有属性String name ;//可以为私有字段设置getter来让外界获取到私有字段String get school => _school;//可以为私有字段设置setter来控制外界对私有字段的修改set school(String value) {_school = value;}
}
var main() {
var person = Person5();
//用set方法赋值
person.school = ‘衡水中学’;
//用getang方法获取到school的值
print(person.school);
}
## 抽象类* 使用abstract 修饰* 不能被实例化,可以定义抽象方法* 在定义接口的时候非常有用
///继承抽象类要实现它的抽象方法,否则也需要将自己定义成抽象类
class StudyFlutter extends Study {
@override
void study() {
print(‘我爱学习,我爱Flutter’);
}
}
abstract class Study {
void study();
}
## 继承* 使用extends 关键字标示继承* 构造方法不能被继承* 使用@override 重写函数* 如果继承的抽象类,要实现所有抽象函数继承普通类* 子类至少定义一个构造函数调用父类的任一构造函数,使用:super。* 子类的每个构造函数都要继承父类的任一构造函数。* 子类可重写父类的函数。
class PersonO {
String name;int age;PersonO(this.name,this.age);//普通构造函数PersonO.run(String name){ //命名构造函数this.name = 'my name: $name';}fun1() {print('fun1');}
}
class StudentO extends PersonO {
String name;int nums;int color;//至少需要定义一个构造函数调用父类的任一构造函数StudentO(String name, int age) : super(name, age);//重写父类的方法@overridefun1() {// TODO: implement fun1return super.fun1();}//子类自己的方法void fun2(){print(nums);}}
按住option会给出提示## minxins* minmins 是在多个类层次结构中重用代码的一种方式,类型swift中协议,当然swift中协议比这个用处大多了.也像python中的装饰器执行顺序也是一样* 使用minmins 要加with关键字.多个名字用逗号隔开.* 不用声明任何构造方法,不调用super
class Person001 {
String getName() => ‘wei1’ ;//三个类都有
String getAddress() => ‘历下区’; //该类独有
}
class Person002 {
String getName() => ‘wei2’;//三个类都有该方法
String getColor() => “2 red”;//该类独有
int getNum()=> 6;//该类和OtherClass都有
String getCity()=>”济南”;
}
class OtherPerson {
String getName() => ‘wei2’;//三个类都有该方法
int getNum() => 3; //该类和With2都有
int getDesk() => 333;//该类独有
String getPhone()=>”OtherPerson 123”;//该类和子类
String getCity()=>”青岛”;
}
class Child1 extends OtherPerson with Person001,Person002 {
@override
String getPhone() {
// TODO: implement getPhone
print(‘child 1 1’);
}
@override
String getCity() {
// TODO: implement getCity
print(‘city child 11 ‘);
}
}
class Child2 extends OtherPerson with Person001, Person002 { }
print(‘——————minxins—————-Start’);
Child1 c1 = Child1();print(c1.getPhone());//Child1 iphone 重写了函数,调用时用的是自身的函数print(c1.getCity());//Child1 oriange 重写了函数,调用时用的是自身的函数print(c1.getDesk());//333 调用的是OtherPerson的函数 person1 person2中没有同名函数print(c1.getNum());//6 调用的是person2中的函数print(c1.getAddress());//person1 历下区 调用的是person1中的函数print(c1.getColor());//person2 2 red 调用的是person2中的函数print(c1.getName());//person2 wei2 调用的是person2中的函数 person2在声明顺序中更靠后print("-----------------------");Child2 c2 = Child2();print(c2.getPhone());//OtherPerson 123 没有重写函数,调用时用的是OtherPerson的函数print(c2.getCity());//济南 没有重写函数,调用时用的是person2的函数,虽然OtherPerson也有,但person2在声明顺序中更靠后print(c2.getDesk());//333 调用的是OtherPerson的函数 person1 person2中没有同名函数print(c2.getNum());//6 调用的是person2中的函数print(c2.getAddress());//历下区 调用的是Person1中的函数print(c2.getColor());//2 red 调用的是Person2中的函数print(c2.getName());//wei2 调用的是Person2中的函数 Person1在声明顺序中更靠后print('------------minxins-----------end');
理解:1. A extends B with C,D{}2. A 继承了B 并拥有了C和D所有的属性和函数,可以用A的实例直接调用CD的属性方法。3. 如果B有函数fun1,A重写了这个函数 那么以后A的实例调用的fun1,都是A重写后的方法。4. 如果B有函数fun1,CD中也有函数fun1,A重写了这个函数 那么以后A的实例调用的fun1,都是A重写后的方法。5. 如果B有函数fun1,CD中也有函数fun1,A没有重写这个函数 那么以后A的实例调用的fun1,是声明方法时最后的那个类的函数,比如“A extends B with C,D”,那么就是D中的fun1,如果是“A extends B with D,C”,那么就是C中的fun1。也就是说优先级是从后向前的(前提是子类没有重写函数)。6. 和Python中装饰器是一样的参考: https://www.jianshu.com/p/232271ad2768
