# 类与对象
面向对象编程(OOP)d的三个基本特征:封装、继承、多态
Dart所有的东西皆为对象,所有对象继承自Object类。
Dart是一门使用类和单继承的面向对象语言,所有对象都是类的示例,并且所有类都是Object的子类。
一个类通常有属性及方法组成。
class Person {
String name;
int age;
void setName(String name) {
this.name = name;
}
String getName() {
return this.name;
}
void setAge(int age) {
this.age = age;
}
int getAge() {
return this.age;
}
}
main() {
var p = new Person();
p.setName('Sogrey');
print(p.getName());//Sogrey
p.age = 30;
print(p.getAge());//30
}
# 构造函数
像Java一样,类的构造函数:
Person([String name,int age]){//[]内为可选参数
print('构造方法,实例化时自动触发');
this.name = name;
this.age = age;
}
更简洁,与上同效:
Person([this.name,this.age]);
# 命名构造函数
Person.work(){
print('命名构造函数');
}
var work = new Person.work();
# 引入外部类
import
关键字
import 'lib/Person.dart';
main() {
var p = new Person();
p.setName('Sogrey');
print(p.getName());
p.age = 30;
print(p.getAge());
}
Person.dart:
class Person {
String name;
int age;
// Person([String name,int age]){
// print('构造方法,实例化时自动触发');
// this.name = name;
// this.age = age;
// }
Person([this.name,this.age]);
Person.work(){
print('命名构造函数');
}
void setName(String name) {
this.name = name;
}
String getName() {
return this.name;
}
void setAge(int age) {
this.age = age;
}
int getAge() {
return this.age;
}
}
# 私有变量、属性
变量前加下划线_
.
私有属性外部不能访问,只能在当前类内访问。
如何访问私有属性,定义一个共有的方法,返回该私有属性。私有方法一样。
# getter/setter 方法
class Rect {
num height;
num width;
Rect(this.width, this.height);
// num area(){
// return this.width*this.height;
// }
//简写
get area {
return this.width * this.height;
}
//Setters should declare exactly one required parameter.
//Setters应该只声明一个必需的参数。
set areaWidth(num width) {
this.width = width;
}
set areaHeight(num height) {
this.height = height;
}
}
main() {
var r = new Rect(20, 2);
// print(r.area());
print(r.area);//40
r.areaWidth = 20;
r.areaHeight = 10;
print(r.area);//200
}
# 实例化之前做些事
class Rect {
num height;
num width;
// 实例化之前做些事( 给属性赋默认值 )
Rect():width=2, height=20{
}
// num area(){
// return this.width*this.height;
// }
//简写
get area {
return this.width * this.height;
}
//Setters should declare exactly one required parameter.
//Setters应该只声明一个必需的参数。
set areaWidth(num width) {
this.width = width;
}
set areaHeight(num height) {
this.height = height;
}
}
main() {
var r0 = new Rect();
print(r0.area);//40
}
# 静态成员
- 使用
static
关键字修饰 - 静态方法不能访问非静态成员,非静态方法可以访问静态成员。
//静态成员
class Animal {
static String type = 'Animal';
static String name = 'Dog';
static String getName() {
return name;
}
void setName(n) {
name = n;
}
}
main() {
var a = new Animal();
a.setName('Cat');
print(Animal.getName());//Cat
}
# 操作符
?
条件运算符as
类型转换is
类型判断,如果对象具有指定类型则为trueis!
类型判断,如果对象具有指定类型则为false..
级联操作(链式调用)
String aa=null;
// print(aa.indexOf('a'));
// Unhandled exception:
// NoSuchMethodError: The method 'indexOf' was called on null.
// Receiver: null
// Tried calling: indexOf("a")
print(aa?.indexOf('a'));//null
var a = new Animal();
if(a is Animal){
print('a is Animal');
}
(a as Animal).setName('Fish');
class Person {
String name;
int age;
String sex;
String getInfo() {
return 'My name is ${this.name},${this.sex},${this.age},${this.age}';
}
}
Person pp = new Person();
pp
..name = 'Sogrey'
..age = 31
..sex = '男';
print(pp.getInfo());
//My name is Sogrey,男,31 years old.
# 类的继承
Dart中类的继承:
- 子类使用
extends
关键字来继承父类 - 子类会继承父类里面可见的属性和方法,但是不会继承构造函数
- 子类能覆写父类的方法 getter和setter
class Person {
String name;
int age;
String sex;
Person([this.name, this.age]);
void setName(String name) {
this.name = name;
}
}
class Child extends Person{
Child(String name,int age,String sex):super(name,age){
this.sex = sex;
}
//覆写父类方法
void setName(String name) {
this.name ='Child\'s ${name}';
}
}
Child c = new Child('张三', 12,'男');
print(c.getInfo());
//My name is 张三,男,12 years old.
c.setName('李四');
print(c.getInfo());
//My name is Child's 李四,男,12 years old.
# 抽象类
Dart中抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
- 抽象类通过
abstract
关键字定义。 - Dart中抽象类方法不能用
abstract
声明,Dart中没有方法体的方法称为抽象方法。 - 如果子类继承抽象类,就必须实现父类的抽象方法。
- 如果把抽象类当接口使用,就必须实现抽象类中的所有属性和方法。
- 抽象类不能被实例化,只有继承他的子类可以。
extends
抽象类与implements
的区别:
- 如果要复用抽象类里的方法,并且要用抽象方法约束子类的话,我们就是用
extends
继承抽象类。 - 如果只是将抽象类当做标准就是用
implements
实现继承。
案例:定义抽象Person类,要求子类必须实现getSex方法:
abstract class Person {
//抽象类通过`abstract`关键字定义
getSex(); //没有方法体的方法称为抽象方
String getMsg(){
return '抽象类中的普通方法';
}
}
class Man extends Person {
//子类必须实现父类里的抽象方法
getSex() {
return 'Man';
}
}
class Woman extends Person {
//子类必须实现父类里的抽象方法
getSex() {
return 'Woman';
}
}
main() {
var man = new Man();
print(man.getSex()); //Man
print(man.getMsg()); //抽象类中的普通方法
var woman = new Woman();
print(woman.getSex()); //Woman
print(woman.getMsg()); //抽象类中的普通方法
}
# 多态
允许将子类类型的指针赋值给父类类型的指针,统一个函数调用会有不同的执行结果。
子类的实例赋值给父类的引用。
多态就是父类定义一个方法不去实现,由子类实现,不同子类又不用的实现方法,得到的执行结果也不同。
abstract class Person {
//抽象类通过`abstract`关键字定义
getSex(); //没有方法体的方法称为抽象方
}
class Man extends Person {
//子类必须实现父类里的抽象方法
getSex() {
return 'Man';
}
String getMsg() {
return '抽象类Man中的普通方法';
}
}
class Woman extends Person {
//子类必须实现父类里的抽象方法
getSex() {
return 'Woman';
}
String getMsg() {
return '抽象类Woman中的普通方法';
}
}
main() {
var man = new Man();
print(man.getSex()); //Man
print(man.getMsg()); //抽象类中的普通方法
var woman = new Woman();
print(woman.getSex()); //Woman
print(woman.getMsg()); //抽象类中的普通方法
Person man1 = new Man();
print(man1.getSex()); //Man
// print(man1.getMsg()); //子类的实例赋值给父类的引用,父类引用不能调用子类中的方法
}
# 接口
和Java一样,Dart也有接口,区别在于:
- Dart的接口没有
interface
关键字,普通类和抽象类都可以作为接口被实现,使用implements
关键字实现。 - Dart中,如果接口的实现类是普通类,会将普通类和抽象类中属性和方法全部覆写一遍
- 抽象类可以定义抽象方法,普通类不行,建议使用抽象类做接口。
abstract class DB {
add(String data);
delete(int id);
update(int id,String data);
query(int id);
}
class MySql implements DB{
add(String data) {
// TODO: implement add
return null;
}
delete(int id) {
// TODO: implement delete
return null;
}
query(int id) {
// TODO: implement query
return null;
}
update(int id, String data) {
// TODO: implement update
return null;
}
}
class msSql implements DB{
add(String data) {
// TODO: implement add
return null;
}
delete(int id) {
// TODO: implement delete
return null;
}
query(int id) {
// TODO: implement query
return null;
}
update(int id, String data) {
// TODO: implement update
return null;
}
}
main(){
MySql mySql = new MySql();
mySql.add('data...');
mySql.delete(1);
//...
}
# 一个类实现多个接口
abstract class A {
String name;
printA();
}
abstract class B {
printB();
}
class C implements A,B{
//C继承自接口A和B,就要实现A和B中所有方法
String name;
printA(){
//实现
}
printB(){
//实现
}
}
# Dart中的Mixins
Dart2中Mixins的使用条件:
- 作为Mixins的类智能继承自Object,不能继承自其他类
- 作为Mixins的类不能有构造函数
- 一个类可以Mixins多个Mixins类
- Mixins绝不是继承,也不是借口,而是一种全新的特性
class Person {
String name;
num age;
Person(this.name, this.age);
printInfo() {
print('${this.name} is ${this.age} years old.');
}
void run() {
print('This is Person.');
}
}
// 继承父类
class A {
void printA() {
print('A');
}
void run() {
print('This is A.');
}
}
class B {
void printB() {
print('B');
}
void run() {
print('This is B.');
}
}
//Mixins 类
class C extends Person with A, B {
C(String name, num age) : super(name, age);
}
main() {
var c = new C('Sogrey', 31);
c.printInfo(); //Sogrey is 31 years old.
// 继承自不同类,调用他们各自的方法
c.printA(); //A
c.printB(); //B
// 继承多个类以及其他接口类中有相同方法,后面的会覆盖前面的
c.run(); //This is B.
// Mixins类的类型判断
print(c is A); //true
print(c is B); //true
print(c is C); //true
print(c is Person); //true
print(c is Object); //true
}
← 函数 泛型 泛型方法 泛型类 泛型接口 →