在 Dart 中,类是一种用于创建对象的蓝图。通过定义类,你可以创建具有相同属性和行为的对象集合。本章将详细介绍如何声明和使用 Dart 中的类。
类的基本结构
定义一个类
要定义一个类,可以使用 class 关键字。下面是一个简单的类定义示例:
// www.javascriptcn.com code example
class Person {
// 属性
String name;
int age;
// 构造函数
Person(this.name, this.age);
// 方法
void introduce() {
print('我的名字是 $name,今年 $age 岁。');
}
}在这个例子中,我们定义了一个名为 Person 的类,它有两个属性:name 和 age。此外,我们还定义了一个构造函数 Person 和一个方法 introduce。
访问修饰符
Dart 没有像 Java 或 C++ 那样的显式访问修饰符(如 public, private, protected)。但是,Dart 提供了一种通过下划线 _ 来模拟私有属性和方法的方式。
// www.javascriptcn.com code example
class Person {
String _name; // 私有属性
int _age;
Person(this._name, this._age);
void _secretFunction() {
print('这是私有方法');
}
void publicMethod() {
print('这是公有方法');
}
}
void main() {
var person = Person('张三', 30);
// print(person._name); // 错误:无法从外部访问私有属性
person.publicMethod(); // 正确
// person._secretFunction(); // 错误:无法从外部访问私有方法
}默认构造函数
如果你不定义任何构造函数,Dart 会自动为你提供一个默认构造函数。
// www.javascriptcn.com code example
class Person {
String name;
int age;
// 如果没有定义构造函数,这里会有一个默认构造函数
}
void main() {
var person = Person();
person.name = '李四';
person.age = 25;
}命名构造函数
除了默认构造函数外,你还可以定义命名构造函数,这使得创建类的实例更加灵活。
// www.javascriptcn.com code example
class Person {
String name;
int age;
Person(this.name, this.age);
// 命名构造函数
Person.withAge(this.age) : name = '匿名'; // 可以调用其他构造函数
}
void main() {
var person1 = Person('王五', 40);
var person2 = Person.withAge(50);
print(person1.name); // 输出: 王五
print(person2.name); // 输出: 匿名
}工厂构造函数
工厂构造函数允许你在运行时决定返回的对象类型,或者返回缓存的对象实例。
// www.javascriptcn.com code example
class Person {
String name;
int age;
Person(this.name, this.age);
factory Person.withName(String name) {
return Person(name, 0);
}
factory Person.fromCache(String name) {
// 假设这里有一些缓存逻辑
return Person(name, 30);
}
}
void main() {
var person1 = Person.withName('赵六');
var person2 = Person.fromCache('钱七');
print(person1.name); // 输出: 赵六
print(person1.age); // 输出: 0
print(person2.name); // 输出: 钱七
print(person2.age); // 输出: 30
}初始化列表
初始化列表允许你在构造函数体之前执行一些初始化操作,例如调用超类的构造函数或初始化常量字段。
// www.javascriptcn.com code example
class Person {
final String name;
int age;
// 使用初始化列表来初始化 final 字段
Person(this.name, this.age) : assert(age >= 0);
void sayHello() {
print('你好,我是 $name,今年 $age 岁。');
}
}
void main() {
var person = Person('孙八', 28);
person.sayHello(); // 输出: 你好,我是 孙八,今年 28 岁。
}静态成员
静态成员属于类而不是类的实例。它们可以通过类名直接访问,而无需创建类的实例。
// www.javascriptcn.com code example
class Person {
static String species = '人类';
Person(this.name, this.age);
String name;
int age;
void introduce() {
print('我是 ${this.name},属于 ${Person.species}');
}
}
void main() {
var person = Person('周九', 35);
person.introduce(); // 输出: 我是 周九,属于 人类
print(Person.species); // 输出: 人类
}抽象类
抽象类不能被实例化。它们通常用于定义一组子类应该实现的方法。
// www.javascriptcn.com code example
abstract class Animal {
void makeSound();
}
class Dog implements Animal {
@override
void makeSound() {
print('汪汪!');
}
}
void main() {
var dog = Dog();
dog.makeSound(); // 输出: 汪汪!
// var animal = Animal(); // 错误:无法实例化抽象类
}接口
Dart 不直接支持接口,但你可以通过抽象类或使用 mixin 来实现类似的功能。
// www.javascriptcn.com code example
abstract class Movable {
void move();
}
class Car implements Movable {
@override
void move() {
print('汽车移动了。');
}
}
void main() {
var car = Car();
car.move(); // 输出: 汽车移动了。
}继承
Dart 支持单继承,这意味着每个类只能有一个父类。
// www.javascriptcn.com code example
class Animal {
void eat() {
print('动物吃东西。');
}
}
class Dog extends Animal {
void bark() {
print('狗叫。');
}
}
void main() {
var dog = Dog();
dog.eat(); // 输出: 动物吃东西。
dog.bark(); // 输出: 狗叫。
}覆写方法
子类可以覆写超类中的方法。
// www.javascriptcn.com code example
class Animal {
void makeSound() {
print('动物发出声音。');
}
}
class Dog extends Animal {
@override
void makeSound() {
print('狗汪汪叫。');
}
}
void main() {
var dog = Dog();
dog.makeSound(); // 输出: 狗汪汪叫。
}调用超类方法
有时需要调用超类的方法。你可以使用 super 关键字来实现这一点。
// www.javascriptcn.com code example
class Animal {
void makeSound() {
print('动物发出声音。');
}
}
class Dog extends Animal {
@override
void makeSound() {
super.makeSound(); // 调用超类的 makeSound 方法
print('狗汪汪叫。');
}
}
void main() {
var dog = Dog();
dog.makeSound(); // 输出: 动物发出声音。 狗汪汪叫。
}常量构造函数
如果你想创建不可变对象,可以使用常量构造函数。
// www.javascriptcn.com code example
class Person {
final String name;
final int age;
const Person(this.name, this.age);
@override
String toString() => 'Person(name: $name, age: $age)';
}
void main() {
const person = Person('吴十', 40);
print(person); // 输出: Person(name: 吴十, age: 40)
}泛型类
泛型类允许你定义可以在多种数据类型之间重用的类。
// www.javascriptcn.com code example
class Box<T> {
T item;
Box(this.item);
T getItem() => item;
}
void main() {
var stringBox = Box<String>('Hello');
print(stringBox.getItem()); // 输出: Hello
var intBox = Box<int>(42);
print(intBox.getItem()); // 输出: 42
}使用泛型类
你可以使用泛型类来处理不同类型的数据,并在运行时确定类型。
// www.javascriptcn.com code example
class Pair<T> {
T first;
T second;
Pair(this.first, this.second);
}
void main() {
var stringPair = Pair<String>('Apple', 'Banana');
print('${stringPair.first}, ${stringPair.second}'); // 输出: Apple, Banana
var intPair = Pair<int>(1, 2);
print('${intPair.first}, ${intPair.second}'); // 输出: 1, 2
}组合类
组合是一种设计模式,通过组合现有类来构建新的功能。
// www.javascriptcn.com code example
class Engine {
void start() {
print('发动机启动。');
}
}
class Car {
Engine engine;
Car(this.engine);
void startEngine() {
engine.start();
}
}
void main() {
var car = Car(Engine());
car.startEngine(); // 输出: 发动机启动。
}以上内容详细介绍了 Dart 中类的声明及其各种特性。希望这些信息对你理解和使用 Dart 类有所帮助。