06-Dart 对象和类
本篇从大地老师《Dart 入门实战教程》学习整理而来。
面向对象编程
- 面向对象编程(OOP)的三个基本特征是:封装、继承、多态
- 封装:封装是对象和类概念的主要特性。封装,把客观事物封装成抽象的类,并且把自己的部分属性和方法提供给其他对象调用, 而一部分属性和方法则隐藏。
- 继承:面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
- 多态:允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果。
- Dart所有的东西都是对象,所有的对象都继承自Object类。
- Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类。
- 一个类通常由属性和方法组成。
// 所有的对象都继承自Object类
Object a = 123;
Object v = true;
Object o = {'name': '张三'};
Object l = ['name', 2323, true];
print(a);
print(v);
print(o);
print(l);
创建使用类
class Person {
String name = "张三";
int age = 23;
void getInfo() {
print("$name----$age");
// 使用大括号包裹 {this.name} 来表示是个整体
print("${this.name}----${this.age}");
}
void setInfo(int age) {
this.age = age;
}
}
void main() {
//实例化
Person p1 = new Person();
p1.setInfo(28); // 调用类的方法设置 age
p1.getInfo(); // 调用类的方法获取 name age
}
构造函数
默认构造函数
最新版本的dart中需要初始化不可为null的实例字段,如果不初始化的话需要在属性前面加上late
- 默认构造函数,实例化的时候自动触发
class Person{
String name='张三';
int age=20;
// 默认构造函数,实例化的时候自动触发
Person(){
print('这是构造函数里面的内容 这个方法在实例化的时候触发');
}
}
void main() {
// 实例化
new Person();
}
命名构造函数
- dart里面构造函数可以写多个
class Person {
late String name;
late int age;
//默认构造函数的简写
Person(this.name, this.age);
Person.now() {
print('我是命名构造函数');
}
Person.setInfo(String name, int age) {
this.name = name;
this.age = age;
}
void printInfo() {
print("${this.name}----${this.age}");
}
}
void main() {
Person p1 = new Person.now(); //命名构造函数
// Person p1 = new Person.setInfo('李四', 30);
// p1.printInfo(); // 李四----30
}
类的模块化
- 将类抽离成文件并导入
// 文件 Person.dart
class Person{
late String name;
late int age;
Person.setInfo(String name,int age){
this.name=name;
this.age=age;
}
void printInfo(){
print("${this.name}----${this.age}");
}
}
// 主文件
import 'lib/Person.dart';
void main() {
Person p1 = new Person.setInfo('李四1', 30);
p1.printInfo(); // 李四1----30
}
私有方法和私有属性
- Dart和其他面向对象语言不一样,Data中没有 public private protected这些访问修饰符
- 使用_(下划线)属性名或方法名以下划线开始,把一个属性或者方法定义成私有。
- 在类里可以使用公有方法调用私有属性或方法来使用私有属性或方法
class Animal {
late String _name; //私有属性
late int age;
// _name为私有属性
Animal(this._name, this.age);
// 类里可调用私有属性
String getName() {
return this._name;
}
// _run为私有方法
void _run() {
print('这是一个私有方法');
}
// 类里可调用私有方法
execRun() {
this._run(); //类里面方法的相互调用
}
}
void main(){
Animal a=new Animal('小狗', 3);
// 间接获取私有属性
print(a.getName()); // 小狗
// 间接的调用私有方法
a.execRun(); // 这是一个私有方法
}
getter 和 setter
- dart 中通过 get set关键字来取值或设值
class Rect {
late num height;
late num width;
Rect(this.height, this.width);
get area {
return this.height * this.width;
}
set areaHeight(value) {
this.height = value;
}
}
void main() {
Rect r = new Rect(10, 4);
print("面积:${r.area}"); // 面积:40
r.areaHeight = 6;
print(r.area); // 24
}
类的初始化列表
- Dart中我们也可以在构造函数体运行之前初始化实例变量
class Rect{
int height;
int width;
Rect():height=2,width=10{
print("${this.height}---${this.width}"); // 2---10
}
getArea(){
return this.height*this.width;
}
}
void main(){
Rect r=new Rect();
print(r.getArea()); // 20
}
类的静态成员
- 使用static 关键字来实现类级别的变量和函数。
- 静态方法不能访问非静态成员,非静态方法可以访问静态成员。
- 静态属性和方法可以直接通过类来访问,非静态方法和属性要通过实例来调用。
class Person {
static String name = '张三'; // 静态属性
static void show() { // 静态方法
print(name);
}
}
main(){
// 调用静态方法和属性
print(Person.name);
Person.show();
}
class Person {
static String name = '张三';
int age = 20;
static void show() {
print(name);
}
void printInfo() {
/*非静态方法可以访问静态成员以及非静态成员*/
print(name); //访问静态属性
print(this.age); //访问非静态属性
show(); //调用静态方法
}
static void printUserInfo() {
//静态方法
print(name); //静态属性
show(); //静态方法
//print(this.age); //静态方法没法访问非静态的属性
// this.printInfo(); //静态方法没法访问非静态的方法
// printInfo();
}
}
对象操作符
- ? 条件运算符 已被最新的dart废弃
- as 类型转换
- is 类型判断
- .. 级联操作
class Person {
String name;
num age;
Person(this.name, this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
main() {
Person p = new Person('王五', 2);
p?.printInfo(); //已被最新的dart废弃
// as 是类型转换,其相当于 先检测 其是不是,然后再调用的一种简写。
(p as Person).printInfo(); // 王五---2
// is 判断是否是某个类型,返回true或者false。
if(p is Person){
p.name="李四";
}
p.printInfo(); // 李四---2
// .. 将多行操作简写
p
..name = "赵六"
..age = 30
..printInfo(); // 赵六---30
}