# 1.5 面向对象

## 一、自定义数据类型

1. 通过`class`关键字来定义一个类型，`{}`内是类的具体内容；其中可以定义若干个属性，也就是**成员属性**
2. 举例：

   ```dart
   class Human {
     String name = '';
     double weight = 0;
     double height = 0;
   }
   ```
3. 通过构造函数来创建对象，也可以称之为实例化对象，也可以通过`对象.属性 =` 可以对属性进行赋值；通过`对象.属性`可以访问属性对应的数据
4. 案例

   ```dart
   void main() {
     Human toly = Human();
     toly.name = "捷特";
     toly.weight = 70;
     toly.height = 180;

     print(
         "Human: name{${toly.name},weight:${toly.weight}kg,height:${toly.height}cm}");
   }

   class Human {
     String name = '';
     double weight = 0;
     double height = 0;
   }

   ```

   > 结果：
   >
   > `Human: name{捷特,weight:70.0kg,height:180.0cm}`

## 二、构造函数

1. 构造函数本身也是一个函数，它的价值在于：实例化对象时，可以对属性进行初始化
2. 在实例化对象时，会触发函数体的逻辑，对属性进行赋值，这就是**通过构造函数初始化成员属性**。
3. 案例

   ```dart
   void main() {
     Human toly = Human("捷特", 70, 180);
     print(
         "Human: name{${toly.name},weight:${toly.weight}kg,height:${toly.height}cm}");
   }

   class Human {
     String name = '';
     double weight = 0;
     double height = 0;

     Human(String name, double weight, double height) {
       this.name = name;
       this.weight = weight;
       this.height = height;
     }
     
     // 简写方案
     Human(this.name, this.weight, this.height);
   }

   ```

   > 结果：
   >
   > `Human: name{捷特,weight:70.0kg,height:180.0cm}`

## 三、成员函数(方法)

1. 我们可以定义成员方法，访问成员属性，进行特定的处理。相当于通过函数给出一个公共的访问入口，任何该类对象都可以已通过特定的方法获取信息
2. 案例

   ```dart
   void main() {
     Human toly = Human("捷特", 70, 180);
     print(toly.info());
   }

   class Human {
     String name = '';
     double weight = 0;
     double height = 0;

     Human(this.name, this.weight, this.height);

     String info() {
       return "Human: name{${name},weight:${weight}kg,height:${height}cm}";
     }
   }

   ```

   > 结果：
   >
   > `Human: name{捷特,weight:70.0kg,height:180.0cm}`

## 四、类的继承

1. 它允许一个类（称为子类或派生类）继承另一个类（称为父类或基类）的属性和方法。通过继承，子类可以继承父类的特性，并且还可以添加自己的特定特性。
2. 关键字：`extends`
3. 语法：`super.属性`表示在入参中为父类中的成员赋值
4. 案例

   ```dart
   void main() {
     Student toly = Student("捷特", 70, 180, school: "家里蹲大学");
     print(toly.stuInfo());
   }

   class Human {
     String name = '';
     double weight = 0;
     double height = 0;

     Human(this.name, this.weight, this.height);

     String info() {
       return "Human: name{${name},weight:${weight}kg,height:${height}cm}";
     }
   }

   class Student extends Human {
     String school;

     Student(
       super.name,
       super.weight,
       super.height, {
       required this.school,
     });

     String stuInfo() {
       return "Human: name{${name},weight:${weight}kg,height:${height}cm,school:${school}}";
     }
   }
   ```

   > 结果：
   >
   > `Human: name{捷特,weight:70.0kg,height:180.0cm,school:家里蹲大学}`

## 五、子类覆写父类方法

1. 当子类中存在和父类同名的方法时，就称**子类覆写了父类的方法**，在对象调用方法的时候会优先调用子类方法，没有子类方法的时候，才会触发父类方法
2. 覆写的时候，一般需要增加`@override`注解，但是这是非强制的
3. 可以通过调用`super.`调用父类的方法
4. 案例

   ```dart
   void main() {
     Student toly = Student("捷特", 70, 180, school: "家里蹲大学");
     print(toly.info());
   }

   class Human {
     String name = '';
     double weight = 0;
     double height = 0;

     Human(this.name, this.weight, this.height);

     String info() {
       return "Human: name{${name},weight:${weight}kg,height:${height}cm}";
     }
   }

   class Student extends Human {
     String school;

     Student(
       super.name,
       super.weight,
       super.height, {
       required this.school,
     });

     @override
     String info() {
       return super.info() + ",school:${school}";
     }
   }
   ```

   > 结果：
   >
   > `Human: name{捷特,weight:70.0kg,height:180.0cm,school:家里蹲大学`
