Appearance
第8章:面向对象进阶
8.1 继承
继承是面向对象编程中的重要概念,它允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码复用。
基本语法
使用 extends 关键字实现继承:
dart
class ParentClass {
// 属性和方法
}
class ChildClass extends ParentClass {
// 额外的属性和方法
}子类继承父类的属性和方法
dart
class Animal {
String name;
int age;
Animal(this.name, this.age);
void eat() {
print('$name is eating');
}
void sleep() {
print('$name is sleeping');
}
}
class Dog extends Animal {
String breed;
Dog(String name, int age, this.breed) : super(name, age);
void bark() {
print('$name is barking');
}
}
void main() {
Dog dog = Dog('Buddy', 3, 'Golden Retriever');
dog.eat(); // 继承自父类
dog.sleep(); // 继承自父类
dog.bark(); // 子类自己的方法
}运行结果:
Buddy is eating
Buddy is sleeping
Buddy is barking方法重写
子类可以重写父类的方法,使用 @override 注解:
dart
class Animal {
String name;
Animal(this.name);
void makeSound() {
print('Animal makes a sound');
}
}
class Cat extends Animal {
Cat(String name) : super(name);
@override
void makeSound() {
print('$name meows');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
@override
void makeSound() {
print('$name barks');
}
}
void main() {
Animal animal = Animal('Generic Animal');
Cat cat = Cat('Whiskers');
Dog dog = Dog('Buddy');
animal.makeSound();
cat.makeSound();
dog.makeSound();
}运行结果:
Animal makes a sound
Whiskers meows
Buddy barkssuper 关键字
super 关键字用于调用父类的构造函数、属性和方法:
dart
class Parent {
String name;
Parent(this.name);
void greet() {
print('Hello from $name');
}
}
class Child extends Parent {
int age;
// 调用父类构造函数
Child(String name, this.age) : super(name);
@override
void greet() {
// 调用父类方法
super.greet();
print('I am $age years old');
}
}
void main() {
Child child = Child('John', 10);
child.greet();
}运行结果:
Hello from John
I am 10 years old8.2 封装
封装是面向对象编程的重要原则,它通过隐藏内部细节,提高代码的安全性和可维护性。
访问修饰符
Dart 中没有明确的访问修饰符,但有以下约定:
- public:默认,没有下划线前缀,可以在任何地方访问
- private:使用下划线
_前缀,只能在当前库中访问
dart
class Person {
// public 属性
String name;
// private 属性
int _age;
Person(this.name, this._age);
// 访问 private 属性的方法
int get age => _age;
void set age(int value) {
if (value >= 0) {
_age = value;
}
}
// private 方法
void _privateMethod() {
print('This is a private method');
}
// public 方法
void publicMethod() {
_privateMethod(); // 可以在类内部访问 private 方法
print('This is a public method');
}
}
void main() {
Person person = Person('John', 30);
// 访问 public 属性
print(person.name);
// 访问 private 属性(通过 getter)
print(person.age);
// 修改 private 属性(通过 setter)
person.age = 31;
print(person.age);
// 调用 public 方法
person.publicMethod();
// 不能直接访问 private 属性和方法
// print(person._age); // 错误
// person._privateMethod(); // 错误
}运行结果:
John
30
31
This is a private method
This is a public methodgetter 和 setter 方法
getter 和 setter 方法用于获取和修改私有属性:
dart
class Rectangle {
double _width;
double _height;
Rectangle(this._width, this._height);
// getter 方法
double get width => _width;
double get height => _height;
double get area => _width * _height;
// setter 方法
set width(double value) {
if (value > 0) {
_width = value;
}
}
set height(double value) {
if (value > 0) {
_height = value;
}
}
}
void main() {
Rectangle rect = Rectangle(10, 20);
print('Width: ${rect.width}');
print('Height: ${rect.height}');
print('Area: ${rect.area}');
// 修改属性
rect.width = 15;
rect.height = 25;
print('\nAfter modification:');
print('Width: ${rect.width}');
print('Height: ${rect.height}');
print('Area: ${rect.area}');
}运行结果:
Width: 10.0
Height: 20.0
Area: 200.0
After modification:
Width: 15.0
Height: 25.0
Area: 375.08.3 多态
多态是面向对象编程的核心概念,它允许不同的对象对同一个方法做出不同的响应。
多态的实现
多态通过子类重写父类方法,父类引用指向子类对象来实现:
dart
class Animal {
void makeSound() {
print('Animal makes a sound');
}
}
class Cat extends Animal {
@override
void makeSound() {
print('Cat meows');
}
}
class Dog extends Animal {
@override
void makeSound() {
print('Dog barks');
}
}
void main() {
// 父类引用指向子类对象
Animal animal1 = Cat();
Animal animal2 = Dog();
// 调用方法时,会根据实际对象类型调用相应的方法
animal1.makeSound();
animal2.makeSound();
}运行结果:
Cat meows
Dog barks多态的应用场景
多态可以简化代码,提高扩展性:
dart
class Shape {
void draw() {
print('Drawing a shape');
}
}
class Circle extends Shape {
@override
void draw() {
print('Drawing a circle');
}
}
class Rectangle extends Shape {
@override
void draw() {
print('Drawing a rectangle');
}
}
class Triangle extends Shape {
@override
void draw() {
print('Drawing a triangle');
}
}
// 统一处理不同类型的对象
void drawShape(Shape shape) {
shape.draw();
}
void main() {
List<Shape> shapes = [
Circle(),
Rectangle(),
Triangle()
];
// 遍历并绘制所有形状
for (var shape in shapes) {
drawShape(shape);
}
}运行结果:
Drawing a circle
Drawing a rectangle
Drawing a triangle8.4 抽象类与接口
抽象类
抽象类是一种不能实例化的类,用于定义规范:
dart
abstract class Animal {
// 抽象方法(没有实现)
void makeSound();
// 普通方法(有实现)
void eat() {
print('Eating');
}
}
class Cat extends Animal {
@override
void makeSound() {
print('Meow');
}
}
class Dog extends Animal {
@override
void makeSound() {
print('Woof');
}
}
void main() {
// 不能实例化抽象类
// Animal animal = Animal(); // 错误
Cat cat = Cat();
cat.makeSound();
cat.eat();
Dog dog = Dog();
dog.makeSound();
dog.eat();
}运行结果:
Meow
Eating
Woof
Eating接口
Dart 中没有专门的 interface 关键字,而是使用类或抽象类作为接口:
dart
// 定义接口
class Drawable {
void draw();
}
// 实现接口
class Circle implements Drawable {
@override
void draw() {
print('Drawing a circle');
}
}
class Rectangle implements Drawable {
@override
void draw() {
print('Drawing a rectangle');
}
}
void main() {
Drawable circle = Circle();
Drawable rectangle = Rectangle();
circle.draw();
rectangle.draw();
}运行结果:
Drawing a circle
Drawing a rectangle8.5 实操案例
用继承、封装、多态实现简单业务逻辑:
形状计算
dart
// 抽象类
abstract class Shape {
// 抽象方法
double calculateArea();
double calculatePerimeter();
// 普通方法
void printInfo() {
print('Area: ${calculateArea()}');
print('Perimeter: ${calculatePerimeter()}');
}
}
// 圆形类
class Circle extends Shape {
double _radius;
Circle(this._radius);
@override
double calculateArea() {
return 3.14 * _radius * _radius;
}
@override
double calculatePerimeter() {
return 2 * 3.14 * _radius;
}
}
// 矩形类
class Rectangle extends Shape {
double _width;
double _height;
Rectangle(this._width, this._height);
@override
double calculateArea() {
return _width * _height;
}
@override
double calculatePerimeter() {
return 2 * (_width + _height);
}
}
// 三角形类
class Triangle extends Shape {
double _a;
double _b;
double _c;
Triangle(this._a, this._b, this._c);
@override
double calculateArea() {
// 使用海伦公式计算面积
double s = (_a + _b + _c) / 2;
return sqrt(s * (s - _a) * (s - _b) * (s - _c));
}
@override
double calculatePerimeter() {
return _a + _b + _c;
}
}
void main() {
List<Shape> shapes = [
Circle(5),
Rectangle(4, 6),
Triangle(3, 4, 5)
];
for (int i = 0; i < shapes.length; i++) {
print('Shape ${i + 1}:');
shapes[i].printInfo();
print('');
}
}运行结果:
Shape 1:
Area: 78.5
Perimeter: 31.4
Shape 2:
Area: 24.0
Perimeter: 20.0
Shape 3:
Area: 6.0
Perimeter: 12.0员工管理系统
dart
// 员工抽象类
abstract class Employee {
String _name;
int _id;
double _salary;
Employee(this._name, this._id, this._salary);
// 抽象方法
double calculateBonus();
// getter 方法
String get name => _name;
int get id => _id;
double get salary => _salary;
// 普通方法
void displayInfo() {
print('ID: $_id');
print('Name: $_name');
print('Salary: $_salary');
print('Bonus: ${calculateBonus()}');
}
}
// 全职员工类
class FullTimeEmployee extends Employee {
FullTimeEmployee(String name, int id, double salary) : super(name, id, salary);
@override
double calculateBonus() {
return salary * 0.15; // 15% 奖金
}
}
// 兼职员工类
class PartTimeEmployee extends Employee {
int _hoursWorked;
PartTimeEmployee(String name, int id, double salary, this._hoursWorked) : super(name, id, salary);
@override
double calculateBonus() {
return salary * 0.05 + _hoursWorked * 10; // 5% 奖金 + 加班费
}
@override
void displayInfo() {
super.displayInfo();
print('Hours Worked: $_hoursWorked');
}
}
void main() {
List<Employee> employees = [
FullTimeEmployee('John', 101, 5000),
PartTimeEmployee('Alice', 102, 2000, 40),
FullTimeEmployee('Bob', 103, 6000)
];
for (var employee in employees) {
print('\nEmployee Info:');
employee.displayInfo();
}
}运行结果:
Employee Info:
ID: 101
Name: John
Salary: 5000.0
Bonus: 750.0
Employee Info:
ID: 102
Name: Alice
Salary: 2000.0
Bonus: 500.0
Hours Worked: 40
Employee Info:
ID: 103
Name: Bob
Salary: 6000.0
Bonus: 900.0