Dart之面向对象基本概念

一、前言
什么是面向对象呢?
如果只看概念,面向对象很容易变成一堆词:类、对象、属性、方法、继承、多态、封装、动态绑定。
但换个角度就容易理解很多。我们写程序,其实经常是在把现实世界里的事物搬进代码里。
比如一个动物园管理系统里,有动物、笼子、饲养员;一个商城系统里,有用户、商品、订单;一个 Flutter 页面里,有按钮、输入框、列表项。
面向对象就是一种把现实世界中的实体、特征、行为和关系映射到程序里的思考方式。
这一篇我们先不急着写复杂代码,而是把 Dart 面向对象的基础概念系统讲清楚。
二、一句话理解
面向对象是一种以“对象”为中心组织代码的方法:用类描述一类事物,用对象表示具体事物,用属性保存状态,用方法描述行为。
简单说:
- 类:设计图。
- 对象:按设计图造出来的具体东西。
- 属性:对象有什么状态。
- 方法:对象能做什么事情。
- 继承:复用已有类的能力。
- 多态:同一个行为,不同对象有不同表现。
三、面向对象方法
面向对象方法不只是语法,它是一种分析和设计软件的方式。
它鼓励我们从现实世界出发,先找到系统里的实体,再分析这些实体有什么属性、能做什么行为、彼此之间有什么关系。
比如动物园系统:
| 现实事物 | 程序中的对象 |
|---|---|
| 动物 | Animal |
| 笼子 | Enclosure |
| 饲养员 | Keeper |
继续拆:
- 动物有种类、年龄、健康状况。
- 动物可以吃东西、睡觉、发出声音。
- 笼子有编号、面积、环境类型。
- 饲养员可以喂食、清洁笼子、记录日志。
这就是面向对象的入口:先理解真实问题,再映射成程序结构。
四、面向对象建模
建模就是把现实世界的问题变成代码可以表达的模型。
可以分五步:
4.1 识别实体
先找名词。
例如动物园系统中:
- 动物
- 笼子
- 饲养员
这些名词通常会成为类或对象。
4.2 定义属性
属性描述实体的状态或特征。
例如:
- 动物:种类、年龄、健康状况。
- 笼子:编号、面积、环境类型。
- 饲养员:姓名、工作经验、负责区域。
在 Dart 中,属性通常对应类中的字段。
class Animal {
String species;
int age;
String healthStatus;
Animal(this.species, this.age, this.healthStatus);
}
4.3 确定行为
行为描述实体能做什么。
例如:
- 动物可以吃、睡、叫。
- 饲养员可以喂食、清洁、记录。
在 Dart 中,行为通常对应方法。
class Animal {
String species;
Animal(this.species);
void eat() {
print('$species is eating');
}
void sleep() {
print('$species is sleeping');
}
}
4.4 建立关系
对象之间不是孤立存在的,它们通常会有关系。
例如:
- 动物住在笼子里。
- 饲养员负责某些笼子。
- 狮子是动物的一种。
这些关系在代码里可能表现为:
- 组合:一个类持有另一个类。
- 继承:一个类继承另一个类。
- 依赖:一个方法使用另一个对象。
4.5 抽象与分类
抽象就是提取共同点。
比如狮子、大象、猴子都属于动物。它们都有吃、睡等共同能力,但叫声、行为细节可能不同。
我们可以先抽象出 Animal,再定义具体动物。
class Animal {
void eat() {
print('animal eat');
}
}
class Lion extends Animal {
void roar() {
print('lion roar');
}
}
抽象能让代码更有结构,也能减少重复。
五、类与对象
类与对象是面向对象里最核心的一组概念。
5.1 类是什么
类是创建对象的蓝图或模板。
可以把类想象成房子的设计图。设计图不是房子,但它规定了房子应该有什么结构、多少房间、能开门关门。
class House {
String color = 'white';
double height = 3.5;
void open() {
print('Please open the door!');
}
void close() {
print('Please close the door!');
}
}
这里的 House 是类,它描述了一类房子的属性和行为。
5.2 类的抽象性
类不是某一个具体对象,而是一组对象共同特征的抽象。
比如 House 类不是某一栋真实房子,而是“房子这种东西”的抽象描述。
我们不需要为每一栋房子重新写一套代码,只需要定义一个类,然后创建多个对象。
5.3 对象是什么
对象是类的具体实例。
void main() {
House house = House();
house.color = 'blue';
house.height = 4.0;
house.open();
house.close();
}
这里的 house 就是一个对象。
同一个类可以创建多个对象。
void main() {
House houseA = House();
House houseB = House();
houseA.color = 'blue';
houseB.color = 'yellow';
print(houseA.color);
print(houseB.color);
}
houseA 和 houseB 都来自 House 类,但它们是两个独立对象。
5.4 对象的组成
一个对象通常由三部分组成:
| 组成 | 含义 |
|---|---|
| 标识 | 这个对象是谁 |
| 属性 | 这个对象有什么状态 |
| 方法 | 这个对象能做什么 |
例如一辆车:
- 标识:这辆具体的车。
- 属性:颜色、品牌、型号。
- 方法:启动、停止、加速。
5.5 类和对象的关系
一句话:
- 类是设计图。
- 对象是按照设计图创建出来的具体实例。
类定义结构,对象保存具体数据。
六、消息与消息传递
在面向对象里,对象之间通过方法调用进行协作。
你可以把它理解成“给对象发消息”。
class Printer {
void printText(String text) {
print(text);
}
}
void main() {
Printer printer = Printer();
printer.printText('hello');
}
printer.printText('hello') 就像是给 printer 这个对象发送了一条消息:请打印这段文字。
消息传递的好处是:
- 对象之间通过明确的方法交互。
- 调用方不需要知道对象内部怎么实现。
- 有利于封装和协作。
七、继承
继承用于复用已有类的属性和方法。
如果多个类有共同特征,可以把共同部分放到父类中,子类再扩展自己的能力。
class Animal {
void eat() {
print('animal eat');
}
}
class Dog extends Animal {
void bark() {
print('dog bark');
}
}
void main() {
Dog dog = Dog();
dog.eat();
dog.bark();
}
这里 Dog 继承了 Animal,所以 Dog 对象可以调用 eat()。
继承适合表达“是什么”的关系。
例如:
- 狗是动物。
- 学生是人。
- 轿车是车辆。
不要为了复用几行代码就随便继承。继承表达的是类型关系,滥用继承会让结构变复杂。
八、多态
多态的意思是:同一个行为,在不同对象上可以有不同表现。
class Animal {
void makeSound() {
print('animal sound');
}
}
class Dog extends Animal {
@override
void makeSound() {
print('wang wang');
}
}
class Cat extends Animal {
@override
void makeSound() {
print('miao miao');
}
}
void main() {
List<Animal> animals = [Dog(), Cat()];
for (final animal in animals) {
animal.makeSound();
}
}
这里同样调用 makeSound(),狗和猫表现不同。
多态的价值是让代码面向更抽象的类型编程。
调用方只关心“这是 Animal,能 makeSound”,不需要关心它具体是 Dog 还是 Cat。
九、动态绑定
动态绑定是多态背后的重要机制。
简单说:程序运行时会根据对象的真实类型,决定调用哪个方法。
Animal animal = Dog();
animal.makeSound();
变量类型是 Animal,但对象真实类型是 Dog。运行时调用的是 Dog 重写后的 makeSound()。
这就是动态绑定。
它让代码可以写得更抽象,也让不同子类能够在同一调用方式下表现出不同结果。
十、常见误区
10.1 把类和对象混为一谈
类是模板,对象是实例。
House house = House();
左边的 House 是类型,右边的 House() 是创建对象,house 是对象变量。
10.2 为了复用就滥用继承
继承表达“是什么”的关系。
如果只是想复用功能,不一定非要继承,也可以考虑组合。
10.3 只记概念,不会建模
面向对象最重要的不是背术语,而是从问题中找实体、属性、行为和关系。
看到一个业务场景时,先问:
- 有哪些实体?
- 每个实体有什么属性?
- 每个实体能做什么?
- 它们之间有什么关系?
10.4 以为多态只是重写方法
重写是实现多态的一种方式,但多态的重点是:调用方可以面向父类型或接口编程,让不同对象表现出不同行为。
十一、总结
这一篇我们系统讲了 Dart 面向对象的基本概念。
面向对象是一种从现实世界出发组织代码的方式。它关注对象、属性、行为和对象之间的关系。
核心概念可以这样记:
- 类:创建对象的蓝图。
- 对象:类的具体实例。
- 属性:对象的状态。
- 方法:对象的行为。
- 消息传递:对象之间通过方法调用协作。
- 继承:子类复用父类能力。
- 多态:同一行为在不同对象上有不同表现。
- 动态绑定:运行时根据真实对象类型选择方法。
学习面向对象,不要只停留在语法层面。真正重要的是学会建模:把现实问题拆成对象,再把对象的属性、行为和关系表达成代码。
浙公网安备 33010602011771号