flutter 中最详细的继承,多态,接口讲解

news2024/11/16 23:52:27

flutter 中最详细的继承,多态,接口讲解

  • 前言
  • 一、继承(Extends)
  • 二、混合 mixins(with)
    • 2.1、最简单的mixin
    • 2.2、on 关键字,基于某个类型的mixin
    • 2.3、多个mixin
    • 2.4、mixin 怎么实现多继承
  • 三、接口的实现(implement)
  • 总结


前言

众所周知,dart 是一门单继承的语言,但是我们在日常开发中,会遇到各种各样的问题,比如,我们需要在dart 中实现多继承,那么改怎么办呢?本篇文章,我将和大家聊聊关于dart 中的继承,接口,混合的相关知识。

类型解决什么问题使用场景限制
extends子类继承子类继承父类只能继承一个父类,会继承父类的可见的属性和方法,不能继承构造函数。
Mixin(with)实现类似多继承不能通过多继承,获取一个类的实例不能有构造方法,可以有实例变量
Extension(on)使用 on 将mixin 限制为某个特定的类在无法修改被扩展类源码的情况下使用不能有构造方法和实例变量
Implement声明和实现的接口,实现解耦dart 不支持多继承,但是可以实现多接口

一、继承(Extends)

如何使用extends 关键字来继承父类

  • 子类会继承父类里面可见的属性和方法,但是不会继承构造函数
  • 子类能复写父类的getter 和 setter 方法
  • 子类重写超类的方法,要用@override
  • 子类调用超类的方法,要用super
  • 子类可以继承父类的非私有变量 (在dart 中,所有的变量和方法,默认都是公有的,我们可以使用 _ 来定义私有)

经过上面的解释,我们先来创建一个 person 的类,在类中定义人类的基本属性,私有的思想,基本的构造函数,和基本的运算

class Person {
  String? name;
  int? age;

  //  人类的思想是私有的,使用_thought 对子类不可见
  String? _thought;

  // 构造函数
  Person(this.name, this.age);

  // 计算这个人类是否成年
  bool get isAdult => (age ?? 0) >= 18;

  void run() {
    print("运行 person 类了");
  }
}

接下来我们再来定义一个学生 student 类,学生类会继承 person 类,并重写 和 调用 person 的方法

class Student extends Person {
  // 子类的构造函数,并使用super 调用了超类的方法, name 必传,age 可以为空, {int? age} 可选的意思
  Student(String name, {int? age}) : super(name, age);

  // 重写父类的方法
  
  // TODO: implement isAdult
  bool get isAdult => (age ?? 0) > 20;

  
  void run() {
    // TODO: implement run
    
    // super.run(); 如果把这里注释掉,就无法调用到超类的run() 方法了。
    super.run();

    print("运行 student 类了");
  }

  //  子类自己的方法
  void studentRun() {
    print("运行 studentRun 类了");
  }
}

接下我们使用main 方法,来验证上面的写的内容

void main() {
//   调用学生自己的方法, 传入姓名 和 年龄
  Student student = Student("tiger");

  //访问父类属性,并赋值
  student.age = 18;

  //  父类中,我们大于等于18岁是成人,但是在student 中,我们重写了父类的Adult ,设置成了20, 因此下面输出为 false
  print(student.isAdult);

  // 调用父类的方法
  student.run();
}

运行上面的代码,我们可以得到下图中的输出内容:

image-20221117111853276

接下来我们改造一下main 中的代码,一起来学习一下,继承中是如何使用多态的

void main() {
  // 继承中多态的使用,这里 age: 18 传了可选参数age
  Person person = Student("tiger", age: 18);

  // 调用超类的方法  需要注意的是,这里无法调用student 子类的方法,因为使用多态生成的对象是person, person 中没有student 的方法,如studentRun() 方法
  person.run();

  // 使用 is 的意思就是,将person 转化成 student 的对象,这样就可以访问子类的方法了。
  if (person is Student) {
    person.studentRun();
  }
}

代码运行结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yo1D43QX-1668667242626)(https://s2.loli.net/2022/11/17/EBmQMpI9v5dAS6u.png)]

到这里,dart 中的继承我们就讲完了,需要注意的点就是,在继承中多态的使用。

二、混合 mixins(with)

mixins 的意思就是混入的意思,就是在类中,混入其它的功能,说白了就是现有类的基础上,引入一些新的变量,下面我们一起来看一下它的特点。

  • 作为mixins 的类只能继承自object,不能继承其他的类。
  • 作为mixins 的类不能有构造函数。
  • 一个类可以mixins 多个mixin 类。
  • mixins 不是继承,也不是接口,而是一种全新的特性。

2.1、最简单的mixin

下面我们先来写一个最简单的mixin

// mixin 本身可以是抽象的,可以定义各种方法和属性,等待后续类去实现
mixin TextMixin {
//  定义属性
  var mixinValue = 2;

//  抽象方法
  void mixinTest01();

  void mixinTest02() {
    print("mixinTest02 的输出");
  }
}

class MixinModel with TextMixin{
  
  void mixinTest01() {
    // 该函数mixin 定义未实现,混入对象,必须要实现
    print("mixinTest01 需要实现此方法: ${mixinValue}");
  }

}

void main(){
  MixinModel model = MixinModel();
  model.mixinTest01();
  model.mixinTest02();

  print("mixinValue 调用的输出: ${model.mixinValue}");
}

运行上面的代码:
在这里插入图片描述

从上面的代码及输出中,我们可以得出:mixin 本身可以是抽象的,可以定义各种的方法和属性,等待后续的类去实现

2.2、on 关键字,基于某个类型的mixin

当使用on 关键字(限定类型),则表示该mixin 只能在那个类的子类中使用,这就代表了mixin 中可以调用那个类的方法和属性,请看源码。

class BaseMixin {
  void method() {
    print("method 的输出");
  }
}

mixin TextMixin1 on BaseMixin {
  void test1() {
    print("test1");
  }

  int testValue = 2;

  void test2() {
    method();
  }

  void test3();
}

class Test extends BaseMixin with TextMixin1 {
  
  void test3() {
    // TODO: implement test3

    print("需要实现的 test3");
  }

}

void main() {
  Test test = Test();
  test.test1();
  test.test2();
  test.test3();

  print(test.testValue);
}

运行上面代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YMGcIr29-1668667242628)(https://s2.loli.net/2022/11/17/nhpLPqBOKix7SHu.png)]

2.3、多个mixin

前面我们学习了简单的mixin,mixin 的限定on 关键字,现在我们来看一下,多个mixin 是怎么实现的。

mixin TextMixin1 {
//  定义属性
  var mixinValue = 1;

//  抽象方法
  void mixinTest01();

  void mixinTest02() {
    print(" TextMixin1 中 mixinTest02  的输出");
  }
}

mixin TextMixin2 {
//  定义属性
  var mixinValue = 2;

  void mixinTest03() {
    print("TextMixin2 中 mixinTest03 的输出");
  }
}

class Test with TextMixin1, TextMixin2 {
  
  void mixinTest01() {
    // TODO: implement mixinTest01

    print("TextMixin1 中的抽象方法 mixinTest01 的实现");
  }
}

void main() {
  Test test = Test();
  test.mixinTest01();
  test.mixinTest02();
  test.mixinTest03();
  print(test.mixinValue);
}

运行上面的代码,输出结果如下图

在这里插入图片描述

从上面的代码及运行结果中,我们会发现,如果多个mixin 存在冲突性问题 (如:都有mixinValue 属性),后面的会覆盖前面的,没有冲突的,则都会保留,所以会存在后面的mixin 会修改掉前面的mixin 的一部分逻辑代码,不需要直接继承,就可以直接实现覆盖,避免了更复杂的多继承关系。

2.4、mixin 怎么实现多继承

dart 是单继承的语言,但是有些时候,我们也需要实现多继承的关系,既然mixin 是dart 语言中的一种新特性,那么我们该怎么使用mixin 来实现多继承的关系呢?这里将揭晓答案,请看代码

class BaseMixin {
  void init() {
    print("BaseMixin init");
  }

  BaseMixin() {
    init();
  }
}

mixin TextMixin1 on BaseMixin {
  void init() {
    print("TextMixin1 init start");
    super.init();
    print("TextMixin1 init end");
  }
}

mixin TextMixin2 on BaseMixin {
  void init() {
    print("TextMixin2 init start");
    super.init();
    print("TextMixin2 init end");
  }
}

class Test extends BaseMixin with TextMixin1, TextMixin2 {
  
  void init() {
    print("Test init start");
    super.init();
    print("Test init end");
  }
}

void main() {
  Test();
}

代码运行,执行结果如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X7sVQYH5-1668667242629)(/Users/tiger/Library/Application Support/typora-user-images/image-20221117135958044.png)]

从上面执行结果输出的log 打印顺序,是不是发现,我们已经解决了dart 中没有多继承关系的问题呢?

三、接口的实现(implement)

接口的实现,说白了就是定义一个抽象类,抽象类中仅仅定义方法,没有具体的实现,子类通过implement 的方法,在子类中进行实现具体的方法。

下面先来看一段代码

abstract class Run {
  var runValue;

  void runing() {
    print("runing");
  }
}

abstract class Eat {
  void eat();
}

class Person implements Run, Eat {
  
  var runValue = 100;

  
  void eat() {
    // TODO: implement eat
    print("Person 吃了 ${runValue} 个萝卜");
  }

  
  void runing() {
    // TODO: implement runing
    print("Person 跑了 ${runValue} 公里");
  }
}

class Tiger extends Run with Eat {
  // 抽象类中实现的方法
  // 继承抽象类可以不用实现(子类继承父类方法,可以选择是否重新)
  
  void runing() {
    // 继承抽象类,可以调用super
    super.runing();
    print("Tiger runing");
  }

  // eat 抽象类中需要实现的方法
  
  void eat() {
    // TODO: implement eat

    print("Tiger eat");
  }
}

void main() {
  Person person = Person();
  person.runing();
  person.eat();

  Tiger tiger = Tiger();
  tiger.runing();
  tiger.eat();
}

代码运行结果如下

在这里插入图片描述

从上面的代码和执行结果,我们可以看出,implement 与 extends 最大的不同就是运行后面接上多个普通或者抽象类,当我们使用 B implement A 修饰时,那么A 中的所有的属性和方法都要在B 中去实现,无论它原来是抽象方法还是普通方法。

总结

Mixin:定义了组块

Mixin on:限定了使用组块的宿主必须要继承与某个特定的类,在mixin 中可以访问到该特定类的成员和方法。

with负责组合组块,而with 后面跟的类并不一定都是mixin的,abstract class 和普通的类都可以。

extends with 修饰符会覆盖同名的方法,with 中 后一个覆盖前面的一个。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/12017.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常见简单的排序算法汇总

作者:~小明学编程 文章专栏:Java数据结构 格言:目之所及皆为回忆,心之所想皆为过往 目录 插入排序 原理 代码实现 算法性能分析 希尔排序 引入 原理 代码 算法分析 选择排序 原理 代码 堆排序 原理 代码 算法分析…

pythonUI自动化测试selenium安装使用

pythonUI自动化测试selenium安装使用一、selenium二、安装1. selenium其实虽然称之为工具,但是实际是python中一个库2.安装浏览器3.下载浏览器驱动三、元素定位1.常见的元素定位方式2.打开浏览器3.设置最大行4.设置隐式等待5.打开网页6.点击 登录 按钮7.设置等待8.用…

【javaEE】网络编程套接字

To u&me: 努力经营当下,直至未来明朗 文章目录前言一、网络编程(没时间可以跳过)一)网络编程了解二)相关基本概念二、Socket套接字三、数据报套接字通信(UDP)写一个最简单的UDP版本的客户端…

[附源码]java毕业设计科院垃圾分类系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

高级UI-Canvas(变换技巧,状态保存)

前言 在前面我们把Paint关于UI颜色样式的处理进行了学习, 其实真正高级部分就是三个点,渲染,滤镜,图形组合,而我们图形绘制比较重要的另一个对象Canvas也是需要我们去重点掌握的,那么这次课咱们来进行Canv…

数组与指针实验

指针与数组实验 先简单看一下以下c代码 #include <stdio.h> #include <stdlib.h> int main() {char array[10];array[0] 0x56;array[1] 0x78;array[9] 0x12;char *p (char *)malloc(10);p[0] 0x34;p[1] 0x12;printf("%p\n%p\n%p\n%p\n", array, …

[附源码]Python计算机毕业设计 家乡旅游文化推广网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【微信小程序】.js文件的代码结构与Page页面的生命周期

&#x1f3c6;今日学习目标&#xff1a;第十期——.js文件的代码结构与page页面的生命周期 &#x1f603;创作者&#xff1a;颜颜yan_ ✨个人主页&#xff1a;颜颜yan_的个人主页 ⏰预计时间&#xff1a;25分钟 &#x1f389;专栏系列&#xff1a;我的第一个微信小程序 文章目录…

尚医通 (二十二) --------- MongoDB 简介

目录一、NoSQL 简介二、什么是 MongoDB ?三、MongoDB 特点四、安装 MongoDB1. 数据库2. 文档3. 集合4. 适用场景五、MongoDB 概念解析一、NoSQL 简介 NoSQL (NoSQL Not Only SQL)&#xff0c;意即反 SQL 运动&#xff0c;指的是非关系型的数据库&#xff0c;是一项全新的数据…

使用SRM系统有哪些供应商管理优势?

SRM系统就是我们常说的供应商关系管理&#xff0c;它主要是用来改善与供应链上游供应商的关系&#xff0c;改善企业与供应商的关系的新型管理机制&#xff0c;使双方关系更加紧密&#xff0c;从而实现供应双赢。相信对SRM供应商关系管理系统有了解的朋友们并不陌生&#xff0c;…

[力扣] 剑指 Offer 第二天 - 复杂链表的复制

这里写目录标题题目来源题目描述示例示例 1示例 2示例 3示例 4题目解析算法 1代码实现执行结果复杂度分析算法 2代码实现执行结果复杂度分析总结耐心和持久胜过激烈和狂热。 题目来源 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode…

鲁棒局部均值分解 (RLMD)(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

如何在Ubuntu 22.04使用wine安装windows版本微信

继上篇《如何在 Ubuntu 22.04 上安装 最新版本Wine》成功安装wine。使用以下命令安装&#xff1a; $ sudo dpkg --add-architecture i386 && sudo wget -qO - https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - && sudo apt-add-repository…

从零开始学前端:json对象,对象的序列化和反序列化 --- 今天你学习了吗?(JS:Day16)

从零开始学前端&#xff1a;程序猿小白也可以完全掌握&#xff01;—今天你学习了吗&#xff1f;&#xff08;JS&#xff09; 复习&#xff1a;从零开始学前端&#xff1a;购物车和鲜花价格排序 — 今天你学习了吗&#xff1f;&#xff08;JS&#xff1a;Day15&#xff09; 文…

JVM基础

JVM简介 JVM是java虚拟机简称&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际计算机上仿真模拟各种计算机功能来实现的。也正式因为有了它&#xff0c;java才具有了跨平台特性&#xff0c;”一次编译&#xff0c;到处运…

隐私计算行业应用情况和标准化现状

开放隐私计算 2022-11-16 19:17 发表于浙江 开放隐私计算 开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神&#xff0c;专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播&#xff0c;愿成为中国 “隐私计算最后一公里的…

如何利用快解析实现个人私有云

个人云盘曾火爆一时&#xff0c;原因有二&#xff0c;一是国内可选择的网盘越来越少&#xff0c;自建网盘无疑是一个不错的选项&#xff0c;毕竟网盘是数据存在别人那&#xff0c;始终让人心里不安&#xff0c;如同车辆一样&#xff0c;云盘就是公交车&#xff0c;私有云盘就是…

Matlab:在文本和值之间转换datetimeduration

Matlab&#xff1a;在文本和值之间转换datetimeduration将值转换为文本datetimeduration将数组转换为字符串数组指定输出文本的格式指定输出文本的区域设置将文本转换为值datetime解释输入文本的格式将文本转换为值duration解释输入文本的格式从文件中读取日期和时间此示例演示…

面试经常问的Linux进程到底是什么呢?1W字从0到1详解进程的所有细节!

目录 1.冯诺伊曼体系 2.操作系统 3.进程 4.进程的三种状态 4.1概念 4.2Linux中不同进程状态 5.进程的优先级 6.进程的几个其它概念 7.进程的切换 8.环境变量 8.1环境变量的概念 8.2常见的环境变量 8.3和环境变量相关的命令 8.4查看环境变量的方法 8.5通过代码获取环境变量的方式…

微信小程序 webview组件内嵌H5二维码识别

结果 支持公众号二维码支持小程序码支持个人名片支持群聊不支持页面二维码 做法 点击图片触发previewImage预览&#xff0c;长按识别 <script type"text/javascript" src"https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>wx.p…