1. 封装
1.1 概念
封装是面向对象编程中的一个基本概念,它的主要目的是将对象的状态(数据)和行为(方法)组合 在一起,并隐藏对象的内部实现细节,只暴露必要的接口给外部使用。
1.2 封装的特点
- 隐藏实现细节 :封装允许类的
内部属性和方法
隐藏起来,外部代码无法直接访问这些私有数据。 - 控制访问:通过公共方法(通常称为 getter 和 setter),外部代码可以安全地访问或修改内部数据。
- 提高安全性:封装防止外部代码随意修改对象的状态,从而保护数据的完整性和安全性。
1.3 实现
1.3.1 使用私有变量
在 Dart 中,私有变量通过在变量名前加下划线(_
)来定义。这样,只有定义该变量的类内部可以访问它。
dart
class BankAccount {
String _accountNumber; // 私有变量
double _balance; // 私有变量
BankAccount(this._accountNumber, this._balance);
// 公共方法,用于存款
void deposit(double amount) {
if (amount > 0) {
_balance += amount;
}
}
// 公共方法,用于取款
bool withdraw(double amount) {
if (amount > 0 && amount <= _balance) {
_balance -= amount;
return true;
}
return false;
}
// 公共方法,用于查询余额
double get balance => _balance; // 只读属性
}
1.3.2. 使用 Getter 和 Setter
Dart 提供了 getter 和 setter 方法,以便访问和修改私有属性。
dart
class Person {
String _name; // 私有变量
Person(this._name);
// Getter 方法
String get name => _name;
// Setter 方法
set name(String newName) {
if (newName.isNotEmpty) {
_name = newName;
}
}
}
1.4 总结
封装是 Dart 和其他面向对象语言中的一个重要特性,它通过隐藏类的内部实现,控制外部对数据的访问,增强了代码的安全性和可维护性。通过使用私有变量和公共方法,我们可以有效地管理对象的状态和行为,使代码更加整洁和易于理解。
2. 继承
2.1 继承的概念
继承 是面向对象编程(OOP)
中的一个重要特性,允许一个类(子类)继承另一个类(父类)的属性和方法。
通过继承,子类可以复用父类的代码,同时可以根据需要对父类的行为进行扩展或修改。
在 Dart 中,继承是通过 extends
关键字来实现的。子类继承父类后,能够访问父类的公共成员(字段和方法)。
同时,Dart 支持单继承 ,即一个类只能继承一个父类,但可以通过 混入(mixins)
来实现多个类的特性。
2.2 单继承
单继承:这种类型的继承中,一个类只能从一个类继承。在 Dart 中,我们一次只能扩展一个类。
dart
class Car {
String? color;
String? name;
}
// 特斯拉 继承 car 父类
class Tesla extends Car {
void show() {
print('颜色:$color, 品牌:$name');
}
}
void main(List<String> args) {
Tesla tesla = Tesla();
tesla.color = '白色';
tesla.name = '特斯拉';
tesla.show(); // 颜色:白色, 品牌:特斯拉
}
2.3 多继承
多继承: 在这种类型的继承中,一个类可以从另一个类继承,而该类也可以从另一个类继承。在 Dart 中,我们可以从另一个类扩展一个类,而该类已经从另一个类扩展。
dart
class Car {
String? color;
String? name;
}
// 特斯拉 继承 car 父类
class Tesla extends Car {
String? price;
void show() {
print('颜色:$color, 品牌:$name');
}
}
// model3 继承 特斯拉 父类
class Model3 extends Tesla {
void show() {
// 调用父类中的方法
super.show();
print('价格:$price');
}
}
void main(List<String> args) {
Tesla tesla = Tesla();
tesla.color = '白色';
tesla.name = '特斯拉';
tesla.show(); // 颜色:白色, 品牌:特斯拉
Model3 model3 = Model3();
model3.color = '红色';
model3.name = 'model3';
model3.price = '10000';
model3.show(); // 颜色:红色, 品牌:特斯拉, 价格:10000
}
2.4 层级继承
层次继承: 在这种类型的继承中,父类被多个子类继承。例如,Car类可以被Toyota类和Honda类继承。
dart
class Person {
String? name;
int? age;
String? sex;
}
class Student extends Person {
String? school;
void show() {
print('姓名:$name, 年龄:$age, 性别:$sex, 学校:$school');
}
}
class Teacher extends Student {
String? subject;
double? salary;
void show() {
print('姓名:$name, 年龄:$age, 性别:$sex, 学校:$school, 科目:$subject, 薪水:$salary');
}
}
void main(List<String> args) {
Teacher teacher = Teacher();
teacher.name = '张三';
teacher.age = 20;
teacher.sex = '男';
teacher.school = '清华大学';
teacher.subject = '数学';
teacher.salary = 5000.0;
teacher.show(); // 姓名:张三, 年龄:20, 性别:男, 学校:清华大学, 科目:数学, 薪水:5000.0
Student student = Student();
student.name = '李四';
student.age = 21;
student.sex = '女';
student.school = '北京大学';
student.show(); // 姓名:李四, 年龄:21, 性别:女, 学校:北京大学
}
2.5 总结
- 继承用于重用代码。
- 继承是一个通过使用extends关键字实现的概念。
- 子类可以访问超类的属性和方法。
- Class Dog extends class Animal {} 表示 Dog 是子类,而 Animal 是超类。
- 子类可以有自己的属性和方法。
3. 多态
多态性是指对象具有多种形式的能力。作为人类,我们有能力呈现多种形式。我们可以是学生、老师、父母、朋友等等。同样,在面向对象编程中,多态性是指对象具有多种形式的能力。
3.1 Dart 中的多态实现方式
- 方法重写(Method Overriding):子类重写父类的方法。
- 接口和实现(Interfaces & Implementation):类实现接口(Dart 中的每个类都隐式地实现了接口)。
3.2 方法重写(Method Overriding)
通过 extends
关键字继承父类后,子类可以使用 override
关键字 重写父类的方法。
dart
class Animal {
void speakc(){}
}
class Dog extends Animal {
@override
void speakc() {
print('小狗汪汪叫');
}
}
class Cat extends Animal {
@override
void speakc() {
print('小猫喵喵叫');
}
}
void main(List<String> args) {
Animal dog = Dog();
dog.speakc(); // 输出 "小狗汪汪叫"
Animal cat = Cat();
cat.speakc(); // 输出 "小猫喵喵叫"
}
解释:
父类提供了一个通用的方法
speak()
,而子类通过方法重写
提供了不同的实现
。 即使通过父类类型的引用来调用 speak()
,具体执行的仍然是子类中重写
的方法,这就是多态的表现。
注意
- 如果不写@override,程序仍会运行。但是,写@override是一种很好的做法。
3.3 接口与实现(Interfaces & Implementation)
实现接口时,必须实现接口中定义的所有属性和方法。关键字implements用于实现接口。
dart
class Animal {
void speak();
}
class Dog implements Animal {
@override
void speak() {
print("小狗汪汪叫");
}
}
class Cat implements Animal {
@override
void speak() {
print("小猫喵喵叫");
}
}
void main(List<String> args) {
Animal dog = Dog();
dog.speak(); // 输出 "小狗汪汪叫"
Animal cat = Cat();
cat.speak(); // 输出 "小猫喵喵叫"
}
与继承不同,implements 并不会从接口类继承任何实现,只会强制子类实现接口中的方法。
4. 总结
- 封装:通过私有属性和公共方法提供数据访问接口,确保数据的安全性。
- 继承:通过继承父类,避免重复代码,且可以扩展新的功能。
- 多态:通过方法重写和接口实现,使得不同的对象可以在运行时表现出不同的行为,提高系统的灵活性和可扩展性。