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. 总结
- 封装:通过私有属性和公共方法提供数据访问接口,确保数据的安全性。
- 继承:通过继承父类,避免重复代码,且可以扩展新的功能。
- 多态:通过方法重写和接口实现,使得不同的对象可以在运行时表现出不同的行为,提高系统的灵活性和可扩展性。