文章目录
-
- 摘要
- 前言
- 一、类与对象
-
- [1.1 类的定义](#1.1 类的定义)
- [1.2 构造函数详解](#1.2 构造函数详解)
- [1.3 可空对象与空安全](#1.3 可空对象与空安全)
- [1.4 操作符重载](#1.4 操作符重载)
- 二、继承与多态
-
- [2.1 继承](#2.1 继承)
- [2.2 方法重写](#2.2 方法重写)
- [2.3 covariant协变](#2.3 covariant协变)
- 三、抽象类与接口
-
- [3.1 抽象类](#3.1 抽象类)
- [3.2 接口](#3.2 接口)
- [3.3 抽象类与接口的区别](#3.3 抽象类与接口的区别)
- 四、Mixins混入
-
- [4.1 Mixin基础](#4.1 Mixin基础)
- [4.2 Mixin约束](#4.2 Mixin约束)
- [4.3 Mixin方法覆盖](#4.3 Mixin方法覆盖)
- 总结
摘要
Dart是完全面向对象的语言,一切皆对象。类是面向对象编程的核心,继承、多态、接口是OOP的三大特性。这篇文章我想深入讲解Dart的面向对象编程。
前言
我在学dart之前学过java,java最出名的就是面向对象。
面向对象编程一开始觉得很抽象,类、对象、继承、接口...这些概念让人头大。
但实际项目做多了,发现OOP让代码更有组织、更易维护。这篇文章我想分享Dart面向对象编程的学习和实践经验。
其实如果你学过java,这篇文章对你来说也是小菜一碟
一、类与对象
1.1 类的定义
dart
class Person {
// 属性
String name;
int age;
// 构造函数
Person(this.name, this.age);
// 命名构造函数
Person.withName(String name) : this(name, 0);
Person.fromJson(Map<String, dynamic> json)
: name = json['name'],
age = json['age'];
// 方法
void introduce() {
print('我是$name,$age岁');
}
// Getter
bool get isAdult => age >= 18;
// Setter
set updateAge(int newAge) {
if (newAge > 0) {
age = newAge;
}
}
@override
String toString() => 'Person(name: $name, age: $age)';
}
// 使用
var person = Person('张三', 25);
person.introduce();
print(person.isAdult); // true
person.updateAge = 26;
print(person); // Person(name: 张三, age: 26)

事先声明:我这里的运行结果是为了好看加了指示
1.2 构造函数详解
dart
class Point {
final double x;
final double y;
// 常量构造函数
const Point(this.x, this.y);
// 工厂构造函数
factory Point.origin() {
return const Point(0, 0);
}
// 重定向构造函数
Point.alongX(double x) : this(x, 0);
// 初始化列表
Point.fromJson(Map<String, dynamic> json)
: x = (json['x'] as num).toDouble(),
y = (json['y'] as num).toDouble();
@override
String toString() => 'Point($x, $y)';
}
// 使用
var p1 = const Point(1, 2);
var p2 = Point.origin();
var p3 = Point.alongX(5);
var p4 = Point.fromJson({'x': '3', 'y': '4'});

1.3 可空对象与空安全
dart
class Account {
String? name; // 可空属性
late String _password; // 延迟初始化
Account([this.name]);
void setPassword(String password) {
_password = password;
}
String? getPassword() {
return _password.isNotEmpty ? _password : null;
}
}
// 级联操作符
var account = Account()
..name = '张三'
..setPassword('123456');
// 空值处理
String? getName(Account? account) {
return account?.name ?? '未知';
}
1.4 操作符重载
dart
class Money {
final double amount;
final String currency;
const Money(this.amount, [this.currency = 'CNY']);
// 重载+操作符
Money operator +(Money other) {
if (currency != other.currency) {
throw ArgumentError('货币不同');
}
return Money(amount + other.amount, currency);
}
// 重载-操作符
Money operator -(double value) {
return Money(amount - value, currency);
}
@override
String toString() => '$amount $currency';
}
var m1 = Money(100);
var m2 = Money(50);
print(m1 + m2); // 150.0 CNY
print(m1 - 20); // 80.0 CNY
二、继承与多态
2.1 继承
dart
class Animal {
String name;
Animal(this.name);
void makeSound() {
print('$name发出声音');
}
void eat() {
print('$name在吃东西');
}
}
class Dog extends Animal {
String breed;
Dog(String name, this.breed) : super(name);
@override
void makeSound() {
print('$name汪汪叫');
}
void fetch() {
print('$name去捡球');
}
}
class Cat extends Animal {
Cat(String name) : super(name);
@override
void makeSound() {
print('$name喵喵叫');
}
}
// 使用
Animal dog = Dog('旺财', '金毛');
dog.makeSound(); // 旺财汪汪叫
dog.eat(); // 旺财在吃东西
Animal cat = Cat('咪咪');
cat.makeSound(); // 咪咪喵喵叫
// 多态
List<Animal> animals = [Dog('旺财', '金毛'), Cat('咪咪')];
for (var animal in animals) {
animal.makeSound(); // 根据实际类型调用
}

2.2 方法重写
dart
class Vehicle {
double speed;
Vehicle(this.speed);
void accelerate(double value) {
speed += value;
}
@override
String toString() => '速度:$speed km/h';
}
class Car extends Vehicle {
String brand;
Car(String brand, double speed) : brand = brand, super(speed);
@override
void accelerate(double value) {
super.accelerate(value);
print('$brand 加速到 $speed km/h');
}
@override
String toString() => '$brand ${super.toString()}';
}
// 使用
var car = Car('Tesla', 60);
car.accelerate(20);
print(car); // Tesla 速度:80.0 km/h
2.3 covariant协变
dart
class Animal {
void feed(Animal food) {
print('喂养动物');
}
}
class Dog extends Animal {
@override
void feed(covariant Dog food) {
// covariant允许缩小参数类型
print('喂狗吃${food.name}');
}
String get name => '狗狗';
}
三、抽象类与接口
3.1 抽象类
dart
// 抽象类不能实例化
abstract class Shape {
// 抽象方法没有实现
double area();
double perimeter();
// 普通方法可以有实现
void describe() {
print('面积:${area()},周长:${perimeter()}');
}
}
class Circle extends Shape {
final double radius;
Circle(this.radius);
@override
double area() => 3.14159 * radius * radius;
@override
double perimeter() => 2 * 3.14159 * radius;
}
class Rectangle extends Shape {
final double width;
final double height;
Rectangle(this.width, this.height);
@override
double area() => width * height;
@override
double perimeter() => 2 * (width + height);
}
// 使用
List<Shape> shapes = [Circle(5), Rectangle(4, 6)];
shapes.forEach((s) => s.describe());
3.2 接口
dart
// Dart每个类都隐式定义接口
class Drawable {
void draw() {
print('绘制图形');
}
}
// implements实现接口
class Circle implements Drawable {
@override
void draw() {
print('绘制圆形');
}
}
// 实现多个接口
class Drawable {
void draw() {}
}
class Resizable {
void resize(double factor) {}
}
class Image implements Drawable, Resizable {
@override
void draw() {
print('绘制图片');
}
@override
void resize(double factor) {
print('缩放图片:$factor倍');
}
}
3.3 抽象类与接口的区别
dart
// 抽象类:部分实现,用于继承
abstract class Animal {
String name;
Animal(this.name);
void eat(); // 抽象方法
void sleep() { // 具体方法
print('$name 睡觉');
}
}
// 接口:纯规范,用于实现
abstract class Flyable {
void fly();
void land();
}
class Bird extends Animal implements Flyable {
Bird(String name) : super(name);
@override
void eat() {
print('$name 吃虫子');
}
@override
void fly() {
print('$name 飞行');
}
@override
void land() {
print('$name 降落');
}
}
四、Mixins混入
4.1 Mixin基础
dart
// Mixin是没有构造函数的类
mixin Flying {
void fly() {
print('飞行');
}
}
mixin Swimming {
void swim() {
print('游泳');
}
}
// 使用with混入多个mixin
class Bird with Flying {
String name;
Bird(this.name);
void chirp() {
print('$name 叫');
}
}
class Duck with Flying, Swimming {
String name;
Duck(this.name);
void quack() {
print('$name 嘎嘎叫');
}
}
// 使用
var bird = Bird('麻雀');
bird.fly();
bird.chirp();
var duck = Duck('唐老鸭');
duck.fly();
duck.swim();
duck.quack();
4.2 Mixin约束
dart
// mixin可以约束使用的类
mixin Flying on Animal {
// 只能被Animal的子类使用
void fly() {
print('$name 飞行');
}
}
class Animal {
String name;
Animal(this.name);
}
class Bird extends Animal with Flying {
Bird(String name) : super(name);
}
// class Plane with Flying {} // 错误:Plane不是Animal的子类
4.3 Mixin方法覆盖
dart
mixin Logger {
void log(String message) {
print('[LOG] $message');
}
}
mixin TimestampLogger on Logger {
@override
void log(String message) {
final time = DateTime.now();
super.log('[$time] $message');
}
}
class Service with Logger, TimestampLogger {
void doSomething() {
log('执行操作');
}
}
var service = Service();
service.doSomething(); // [LOG] [2025-01-22 10:00:00.000] 执行操作
总结
面向对象编程是Dart的核心特性,掌握OOP能写出更好的代码。
核心要点:
- 类封装数据和行为,构造函数创建对象
- 继承实现代码复用,多态提高灵活性
- 抽象类定义模板,接口定义规范
- Mixin提供灵活的代码复用方式
- 合理使用OOP特性设计清晰的类层次
最佳实践:
- 优先使用组合而非继承
- 接口隔离,避免臃肿的接口
- Mixin用于横向功能复用
- 抽象类用于定义通用行为
- 保持类单一职责
面向对象编程需要不断实践才能掌握。
欢迎加入开源鸿蒙跨平台社区:开源鸿蒙跨平台开发者社区