• Flutter循序渐进==>封装、继承、多态、抽象类以及属性修改


    导言

    新学一门编程语言,最难以理解的莫过于类了。如果类没用,也就算了,它偏偏很有用,我们必须得掌握,不然怎么好意思说自己会面向对象编程呢?

    抽象类(Abstract Class)在面向对象编程中扮演着非常重要的角色,主要用于定义一个或多个抽象方法的模板,供子类继承并实现这些抽象方法。抽象类不能被实例化,它的主要用途包括:

    1. 定义接口规范:抽象类可以包含抽象方法(没有具体实现的方法),这些方法只有声明没有具体的实现。子类继承抽象类时必须实现这些抽象方法,这样就强制要求子类遵循一定的规范,实现了功能的统一和接口的一致性。

    2. 提供默认实现:虽然抽象类的主要目的是定义接口,但它也可以提供一些具体实现的方法。这样,子类可以继承这些方法而无需重新实现,既提供了灵活性也保证了代码的重用。

    3. 设计模式与架构:在软件设计模式和架构中,抽象类经常用于定义框架或基础结构,而具体的实现细节留给子类完成。这有助于分离关注点,提高代码的模块化和可维护性。

    4. 提升代码的可扩展性:通过定义抽象类和抽象方法,可以轻松地增加新的子类来扩展功能,而无需修改现有的抽象类或其它已有的子类,符合开闭原则(Open-Closed Principle)。

    把类搞的低小下,让从没编过程的都能听懂

    封装

    封装挺好,不用知道里面的复杂,直接拿起来就用。大自然就是很会封装的,每个人都封装得很好。在这里封装主要是把数据封装到一个类里面。如果是私有,就在前面_,这是Dart的搞法。

    继承

    子类继承了父类所有的特征,父传子,甲天下!

    多态

    子类可以青出于蓝胜于蓝,搞自己的,表现就是@override,覆盖父类的方法!

    class General {
      //name和company可以叫字段、变量或者属性,都是一回事,不知道谁搞那么复杂?
      String _name = '';
      String _company = '';
    
      //构造函数,用来初始化变量,这是类General的构造函数,用于初始化新创建的General对象的属性。
      // 构造函数的参数与类的属性名称相同,因此使用了Dart的快捷语法(被称为“命名参数构造”)。
      // 当你创建类的实例时,传递给构造函数的参数值会自动赋给相应的属性。
      //老粗说法:就是调用类(实例化)的参数,给这个构造函数,构造函数传递给类的属性,是类和外界通信的桥梁.
    
      //试图限制General类的name属性不能被设置为"吕布",但是实际上在创建General类实例时,直接传递
      // 了'吕布'作为name参数,这一步绕过了setter方法的检查。这是因为构造函数直接访问了 _name 字
      // 段,而不是通过setter方法设置。所以,尽管在setter方法中设置了限制条件,但在构造函数中
      // 直接赋值时并没有执行这个限制检查。
    
      // 在构造函数中使用setter方法来确保name的值不被设置为"吕布"
      General(String name, String company) {
        this.name = name; // 这里间接调用了setter方法,进行值的设置及检查
        this._company = company;
      }
    
      // Getter for name 把_name的值用getter薅过来
      String get name => _name;
    
      // Setter for name with validation,开始修改,根据传进来的参数来搞事。
      set name(String value) {
        if (value != '吕布') {
          _name = value;
        } else{
          _name = '三姓家奴';
        }
        // 注意:如果传入的是"吕布",这里不做任何操作,相当于拒绝了该设置。
      }
    
      String get company => _company;
      // 注意:没有提到对_company的设置逻辑,所以我保留了直接的getter,没有setter。
    
      //方法就是类里面的函数,用来搞动作
      void selfIntro(){
        print('大家好,我是$_name,我来自$_company!');
      }
    }
    
    //搞个小类,前面已经有将军了,就没必要重新搞了,搞个刘备的将军,继承将军类
    //定义了一个名为liubeiGeneral的新类,它通过extends General继承自General类。
    // 这意味着liubeiGeneral类将拥有General类的所有属性和方法,并可以在此基础上扩展或修改。
    class liubeiGeneral extends General{
      //liubeiGeneral类的构造函数通过使用super关键字调用父类General的构造函数。
      // 这里super.name和super.company分别指代父类构造函数中对应的参数,
      // 这样可以确保子类实例化时也能初始化父类的属性。这是一种简化的构造函数声明方式
      // ,用于直接委托给超类构造函数处理参数。
      liubeiGeneral(super.name, super.company);
    //在子类liubeiGeneral中,新增了一个名为han的方法,用于打印一条关于效忠汉室的信息。
    // 这个方法是liubeiGeneral类特有的,不在其父类General中。
      void han() {
        print('我们都是为汉室效忠!');
      }
      //我不喜欢老的开场白,自己写一个覆盖原来的
      @override
      void selfIntro(){
        print('我是$_name,我为$_company代言!');
      }
    }
    
    //抽象类
    abstract class HanGeneral {
      void fight();
    }
    //把抽象类写详细,抽象类是老领导,搞战略,子类是马仔,去跑腿执行
    class ShuGeneral extends HanGeneral {
      @override
      void fight(){
        print('我们誓死捍卫汉室!');
      }
    }
    
    void main(){
      //类打个括号就是实例化,并把参数传递给构造函数,name为'赵云',company为'刘备集团'。
      General ZhaoYun = General('吕布', '刘备集团');
      //调用Zhaoyun实例(就是具体的赵云人)的selfIntro方法,就打印出
      //大家好,我是赵云,我来自刘备集团!
      ZhaoYun.selfIntro();
    
      liubeiGeneral Guanyu = liubeiGeneral('吕布', '刘备集团');
      Guanyu.selfIntro();
      Guanyu.han();
      ShuGeneral().fight();
    }
    
    

    代码

    1. class General {
    2. //name和company可以叫字段、变量或者属性,都是一回事,不知道谁搞那么复杂?
    3. String _name = '';
    4. String _company = '';
    5. //构造函数,用来初始化变量,这是类General的构造函数,用于初始化新创建的General对象的属性。
    6. // 构造函数的参数与类的属性名称相同,因此使用了Dart的快捷语法(被称为“命名参数构造”)。
    7. // 当你创建类的实例时,传递给构造函数的参数值会自动赋给相应的属性。
    8. //老粗说法:就是调用类(实例化)的参数,给这个构造函数,构造函数传递给类的属性,是类和外界通信
    9. //的桥梁.
    10. //试图限制General类的name属性不能被设置为"吕布",但是实际上在创建General类实例时,直接传递
    11. // 了'吕布'作为name参数,这一步绕过了setter方法的检查。这是因为构造函数直接访问了 _name 字
    12. // 段,而不是通过setter方法设置。所以,尽管在setter方法中设置了限制条件,但在构造函数中
    13. // 直接赋值时并没有执行这个限制检查。
    14. // 在构造函数中使用setter方法来确保name的值不被设置为"吕布"
    15. General(String name, String company) {
    16. this._name = name; // 这里间接调用了setter方法,进行值的设置及检查
    17. this._company = company;
    18. }
    19. // Getter for name 把_name的值用getter薅过来
    20. String get name => _name;
    21. // Setter for name with validation,开始修改,根据传进来的参数来搞事。
    22. set name(String value) {
    23. if (value != '吕布') {
    24. _name = value;
    25. } else{
    26. _name = '三姓家奴';
    27. }
    28. // 注意:如果传入的是"吕布",这里不做任何操作,相当于拒绝了该设置。
    29. }
    30. String get company => _company;
    31. // 注意:没有提到对_company的设置逻辑,所以我保留了直接的getter,没有setter。
    32. //方法就是类里面的函数,用来搞动作
    33. void selfIntro(){
    34. print('大家好,我是$_name,我来自$_company!');
    35. }
    36. }
    37. //搞个小类,前面已经有将军了,就没必要重新搞了,搞个刘备的将军,继承将军类
    38. //定义了一个名为liubeiGeneral的新类,它通过extends General继承自General类。
    39. // 这意味着liubeiGeneral类将拥有General类的所有属性和方法,并可以在此基础上扩展或修改。
    40. class liubeiGeneral extends General{
    41. //liubeiGeneral类的构造函数通过使用super关键字调用父类General的构造函数。
    42. // 这里super.name和super.company分别指代父类构造函数中对应的参数,
    43. // 这样可以确保子类实例化时也能初始化父类的属性。这是一种简化的构造函数声明方式
    44. // ,用于直接委托给超类构造函数处理参数。
    45. liubeiGeneral(super.name, super.company);
    46. //在子类liubeiGeneral中,新增了一个名为han的方法,用于打印一条关于效忠汉室的信息。
    47. // 这个方法是liubeiGeneral类特有的,不在其父类General中。
    48. void han() {
    49. print('我们都是为汉室效忠!');
    50. }
    51. //我不喜欢老的开场白,自己写一个覆盖原来的
    52. @override
    53. void selfIntro(){
    54. print('我是$_name,我为$_company代言!');
    55. }
    56. }
    57. //抽象类
    58. abstract class HanGeneral {
    59. void fight();
    60. }
    61. class ShuGeneral extends HanGeneral {
    62. @override
    63. void fight(){
    64. print('我们誓死捍卫汉室!');
    65. }
    66. }
    67. void main(){
    68. //类打个括号就是实例化,并把参数传递给构造函数,name为'赵云',company为'刘备集团'。
    69. General ZhaoYun = General('吕布', '刘备集团');
    70. //调用Zhaoyun实例(就是具体的赵云人)的selfIntro方法,就打印出
    71. //大家好,我是赵云,我来自刘备集团!
    72. ZhaoYun.selfIntro();
    73. liubeiGeneral Guanyu = liubeiGeneral('吕布', '刘备集团');
    74. Guanyu.selfIntro();
    75. Guanyu.han();
    76. ShuGeneral().fight();
    77. }

    运行结果

  • 相关阅读:
    MySQL建表操作和用户权限
    如今的入职背调到底有多刺激?
    Java实现图片上传功能(前后端:vue+springBoot)
    Node.js浅学
    【性能测试】服务器优化
    aigc使用意愿调查
    MySQL 连接报错,致命错误怎么解决呢?
    YOLOv8-Seg改进:位置信息的轴线压缩增强注意力Sea_Attention| ICLR2023 SeaFormer,轻量级语义分割算法,复旦大学和腾讯
    开发工具系列IDEA:配置注释自动生成
    Android使用Jetpack WindowManager来开发可折叠设备的探索
  • 原文地址:https://blog.csdn.net/simazhao/article/details/139930991