首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python中的协议 、鸭子类型 、 抽象基类 、混入类

本篇文章探讨一下python中的几个概念:协议 、鸭子类型 、 抽象基类 、混入类。 一、协议 在python中,协议是一个或一组方法。...二、鸭子类型(duck typing) 多态的一种形式,在这种形式中,对象的类型无关紧要,只要实现了特定的协议即可。...三、抽象基类 抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。 那么抽象基类这样实现的目的是什么呢? 假设我们在写一个关于动物的代码。...print(issubclass(Cat, Animal)) 输出: True 这种通过注册和抽象基类关联起来的类叫做虚拟子类,虚拟子类不会继承注册的抽象基类,而且任何时候都不会检查它是否符合抽象基类的接口...为了避免运行时错误,虚拟子类要实现所需的全部方法。 抽象基类并不常用,但是在阅读源码的时候可能会遇到,因此还是要了解一下。 四、混入类(mixin class) 混入类是为代码重用而生的。

1.9K20

创建子类对象时,父类构造函数中调用被子类重写的方法为什么调用的是子类的方法?

static void main(String[] args) { A a = new A(); B b = new B(); } } 问题:为什么创建A对象的时候父类会调用子类方法...但是:创建B对象父类会调用父类的方法? 答案: 当子类被加载到内存方法区后,会继续加载父类到内存中。...如果,子类重写了父类的方法,子类的方法引用会指向子类的方法,否则子类的方法引用会指向父类的方法引用。 如果子类重载了父类方法,则子类重载方法引用还指向子类方法。...如果子类方法没有重写也没有重载父类方法,则方法引用会指向父类方法。 当子类对象创建时,会先行调用父类的构造方法(构造方法也是方法),虚拟机会在子类方法区寻找该方法并运行。...其结果是当编译的时候,父类构造方法调用的方法的参数已经强制转换为符合父类方法的参数了。 上边代码在编译前已经转换为下面这个样子的了。

6.2K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    关于使用MethodHandle在子类中调用祖父类重写方法的探究

    关于使用MethodHandle在子类中调用祖父类重写方法的探究 注:这个例子原本出现在周志明先生的《深入理解Java虚拟机》--虚拟机字节码执行引擎章节,介于有读者朋友有疑问,这里基于Java代码层面解释一下...在普通的方法调用中,这个this参数是虚拟机自动处理的,表示的是当前实例对象,我们在方法中可以直接使用。...基于这个事实,我们这时可以直接在GrandFather的thinking方法中调用Son类独有的方法,使用反射或者直接类型强制转换为Son就行了。...这就要回到findSpecial方法中的第四个class类型的参数,即本例中使用的Father.class。...这个参数中指定的是方法接收者的类型,bindTo指定的接收者的类型必须要是这个类或子类,不然会出现ClassCastException异常。

    9.5K30

    一个简单的方法:截取子类名称中不包含基类后缀的部分

    基类是 MenuItem,子类是 WalterlvMenuItem、FooMenuItem。...在代码中,我们可能会为了能够一眼看清类之间的继承(从属)关系而在子类名称后缀中带上基类的名称。但是由于这种情况下的基类不参与实际的业务,所以对外(文件/网络)的名称通常不需要带上这个后缀。...本文提供一个简单的方法,让子类中基类的后缀删掉,只取得前面的那部分。 在这段代码中,我们至少需要获得两个传入的参数,一个是基类的名称,一个是子类的名称。...另外,我们还需要有一些约束,必须有一个类型是另外一个类型的子类。于是我们可能必须来使用泛型做这样的约束。.../// internal static class ClassNameUtils { /// /// 当某个类型的派生类都以基类

    23230

    当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系呢

    事情是这个样子的...... 对话中的截图如下: 看了阿Q的解释,你是否也和“马小跳”一样存在疑问呢?请往看 我们都知道在java中,只要是类型兼容,就可以将一种类型的对象分配给另一种类型的对象。...通过该方法,大家肯定知道它的参数类型为Box,但是大家思考一个问题:你认为Box 和Box类型的参数可以传入吗? 答案是否定的。...那么问题来了,当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系呢?例如如何让Box 和Box变得与Box有关呢?...小结:可以通过继承泛型类或者实现接口来对其进行子类型化。 搞懂了子类型化的问题,我们回到“如何在两个泛型类之间创建类似子类型的关系“的问题。...泛型类或者接口并不会仅仅因为它们的类型之间有关系而变得相关,如果要达到相关,我们可以使用通配符来创建泛型类或接口之间的关系。

    2.9K20

    【C++】继承 ⑥ ( 继承中的构造函数和析构函数 | 类型兼容性原则 | 父类指针 指向 子类对象 | 使用 子类对象 为 父类对象 进行初始化 )

    一、public 公有继承 - 示例分析 1、类型兼容性原则 类型兼容性原则 : C++ 的 " 类型兼容性原则 “ 又称为 ” 赋值兼容性原则 " ; 子类代替父类 : 需要 基类 ( 父类 ) 对象的...地方 , 都可以使用 " 公有继承 " 的 派生类 ( 子类 ) 对象 替代 , 该 派生类 ( 子类 ) 得到了 除 构造函数 和 析构函数 之外的 所有 成员变量 和 成员方法 ; 功能完整性 :..." 公有继承 " 的 派生类 ( 子类 ) 本质上 具有 基类 ( 父类 ) 的 完整功能 , 使用 基类 可以解决的问题 , 使用 公有继承派生类 都能解决 ; 特别注意 : " 保护继承 " 和..." 私有继承 " 的 派生类 , 是 不具有 基类 的 完整功能的 , 因为 最终继承 后的派生类 , 无法在 类外部调用 父类的 公有成员 和 保护成员 ; 2、类型兼容性原则应用场景 " 类型兼容性原则...子类对象 , 父类指针 值为 子类对象 在 堆内存 的地址 , 也就是 将 子类对象 地址 赋值给 父类类型指针 ; 引用 : 父类引用 引用 子类对象 , 将 子类对象 赋值给 父类类型的引用 ; 二

    30920

    Java 小白成长记 · 第 7 篇「区分重载和重写,轻松掌握 Java 多态」

    多态发生的三个必要条件 先看下面这段代码,首先,我们有一个基类 Shape,三个子类,并且都重写了基类的 draw 方法: class Shape { void draw() {} } class...这里需要注意的是,当使用多态方式调用方法时,编译器会首先检查父类中是否有该方法,如果没有,则编译错误;如果父类中有该方法,并且被子类重写,就会调用子类的这个方法;如果父类的方法没有被子类重写,就会调用父类的方法...如果在子类中定义了一个与超类签名相同的方法, 那么子类中的这个方法就覆盖/重写了超类中的这个相同签名的方法。...2)方法重载并非多态的必要条件,不过可以理解成「某个类的多态性的表现」。所谓方法重载,就是一个类中定义了多个方法名相同,但是参数的数量或者类型不同。...总结一下方法重载和重写: 方法重载 方法重写 方法名 相同 相同 参数列表 必须不同 必须相同 返回类型 可以不同 子类方法的返回类型可以是原父类方法返回类型的子类型 访问修饰符 可以不同 子类不能做更严格的限制

    57711

    Swift基础 继承

    当一个类从另一个类继承时,继承类被称为子类,它继承的类被称为其超类。继承是一种基本行为,可以将类与 Swift 中的其他类型区分开来。...访问超类方法、属性和下标 当您为子类提供方法、属性或下标覆盖时,有时使用现有的超类实现作为重写的一部分非常有用。例如,您可以细化该现有实现的行为,或将修改后的值存储在现有继承的变量中。...someIndex的重写下标可以从重写下标实现中访问与super[someIndex]相同的下标的超类版本。 压倒一切的方法 您可以重写继承的实例或类型方法,以便在子类中提供方法的定制或替代实现。...子类不知道继承属性的存储或计算性质——它只知道继承属性具有特定的名称和类型。您必须始终声明要重写的属性的名称和类型,以使编译器能够检查您的重写是否与具有相同名称和类型的超类属性匹配。...任何在子类中重写最终方法、属性或下标的尝试都将报告为编译时错误。您添加到扩展类的方法、属性或下标也可以在扩展的定义中标记为最终。

    11300

    十一、多态

    多态问题的引入背景 在面向对象编程中,多态的引入主要是为了解决以下问题: 提高代码的复用性:通过继承,子类可以继承父类的属性和方法,而多态则允许子类重写父类的方法,从而实现特定于子类的行为。...作用:继承为子类提供了重写基类方法的能力,是实现多态的基础。 虚函数 说明:在基类中,需要有一个或多个被声明为virtual的函数,这些函数被称为虚函数。子类可以重写这些虚函数,以提供特定的实现。...多态的意义 提高代码的复用性和可扩展性: 多态允许使用基类类型的指针或引用来引用派生类的对象,这样就可以通过基类指针或引用来调用派生类中的方法,而无需知道具体的派生类类型。...函数的重载、重写、重定义 函数重载 必须在同一个类中进行(作用域相同) 子类无法重载父类的函数,父类同名函数将被名称覆盖 重载是在编译期间根据参数类型和个数决定函数调用 函数重定义 发生于父类和子类之间...每个子类都可以重写基类中的show方法,以展示各自独特的属性(如培根克数、配料等)。

    10110

    封装、继承与多态究极详解(面试必问)

    // 调用基类方法 Dog dog; dog.speak(); // 调用子类重写的方法 dog.move(); // 调用继承的父类方法 dog.bark...内存布局 说明 A 类的成员 基类 A 中的成员数据存储在内存中 B 类的成员 子类 B 扩展的成员数据存储在内存中 C 类的成员 子类 C 扩展的成员数据存储在内存中 5....在OOP中,多态指的是同一个操作作用于不同类型的对象时,可以有不同的表现形式。最常见的多态形式是方法重写(overriding),即子类可以重写(覆盖)父类的方法。...虚函数是基类中声明为 virtual 的函数,子类可以重写这个函数。当通过基类指针或引用调用该函数时,程序会根据对象的实际类型(而不是指针或引用的类型)来决定调用哪个函数实现。 2.1....函数重载(Function Overloading) 在同一个类中,可以定义多个同名的函数,只要它们的参数类型或参数个数不同。编译器会根据函数调用时传递的参数来决定调用哪个版本的函数。

    12410

    可能是最好的设计模式入门教程——里氏替换原则

    里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。...例如有两个类,一个类为BaseClass,另一个是SubClass类,并且SubClass类是BaseClass类的子类,那么一个方法如果可以接受一个BaseClass类型的基类对象base的话,如:method1...里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。...在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象 感觉是这个意思吧,父类已经实现的方便,子类尽量不要去重写,子类可以去实现父类里没有实现的方法?...里氏替换原则要求子类避免重写父类方法,而多态的条件之一却是要求子类重写父类的方法。所以,我搞不懂里氏替换原则与继承,多态之间的关系。求大神解答,初学小弟跪拜。

    1.5K31

    Python面向对象

    ,将在父类中查找 在子类中可以重写超类的方法(包括构造函数),重写构造函数时,要确保在子类的构造函数中调用超类的构造函数,否则可能无法正确的初始化对象 Python中所有的方法实际上是virtual...抽象基类 抽象基类是不能(至少是不应该)实例化的类,其职责是定义子类应该实现的一组抽象方法。Python可通过引入ABC模块实现抽象基类,使用@abstractmethod装饰器将方法标记为抽象的。...如果派生出的类没有重写talk方法,那么派生出的类也是抽象的,不能实例化。 鸭子类型 “鸭子类型”的语言是这么推断的:一只鸟走起来像鸭子、游起泳来像鸭子、叫起来也像鸭子,那它就可以被当做鸭子。...也就是说,它不关注对象的类型,而是关注对象具有的行为(方法)。 例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。...任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名 鸭子类型的关注点在对象的行为,而不在对象的类型 ?

    78610

    计算机程序的思维逻辑 (15) - 初识继承和多态

    父类也叫基类,子类也叫派生类,父类子类是相对的,一个类B可能是类A的子类,是类C的父类。 之所以叫继承是因为,子类继承了父类的属性和行为,父类有的属性和行为,子类都有。...写类名是可以理解的,表示对象的类型,而写哈希值则是不得已的,因为Object类并不知道具体对象的属性,不知道怎么用文本描述,但又需要区分不同对象,只能是写一个哈希值。...但子类是知道自己的属性的,子类可以重写父类的方法,以反映自己的不同实现。所谓重写,就是定义和父类一样的方法,并重新实现。...需要说明的是,在addShape方法中,参数Shape shape,声明的类型是Shape,而实际的类型则分别是Circle,Line和ArrowLine。...创建对象的代码 (ShapeManager以外的代码)和操作对象的代码(ShapeManager本身的代码),经常不在一起,操作对象的代码往往只知道对象是某种父类型,也往往只需要知道它是某种父类型就可以了

    58290

    【Java 基础】:三大特征之多态

    方法重写 子类必须重写(Override)父类的方法。通过在子类中重新定义和实现父类的方法,可以根据子类的特点行为改变这个方法的行为,如猫和狗吃东西的独特行为。...想要理解方法重写,需要知道以下概念: 继承关系 重写方法是基于父类和子类之间的继承关系。子类继承了父类的方法,包括方法的名称、参数列表和返回类型。...区别点 重写 重载 定义位置 定义在父类和子类之间 定义在同一个类中 方法签名 重写方法具有相同的名称和方法签名 重载方法具有相同的名称,但方法签名(参数类型和个数)不同 继承关系 是在子类中对父类方法的重新定义和实现...) //程序在编译阶段只知道 p1 是 Person 类型 //程序在运行的时候才知道堆中实际的对象是 Student 类型 Person p1 = new Student();...* */ 总的来说:重载是在同一个类中根据参数列表的不同定义多个具有相同名称但参数不同的方法,而重写是子类重新定义和实现了从父类继承的方法。

    11010

    Java中

    super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object; 上界类型安全的考虑,我们可以加入Father对象或者其任何子类(如Son)对象,但由于编译器并不知道List的内容究竟是Father的哪个超类,因此不允许加入特定的任何超类(如Human)。...而当我们读取的时候,编译器在不知道是什么类型的情况下只能返回Object对象,因为Object是任何Java类的最终祖先类。但这样的话,元素的类型信息就全部丢失了。...2、super 可用于参数类型限定,不能用于返回类型限定(换句话说:? supper xxx 只能用于方法传参,因为jdk能够确定传入为xxx的子类,返回只能用Object类接收)。 3、?...既不能用于方法参数传入,也不能用于方法返回。 带有super超类型限定的通配符可以向泛型对象中写入,带有extends子类型限定的通配符可以向泛型对象读取。

    1K30

    Java中<? extends T>和<? super T>的理解

    super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object; 上界类型安全的考虑,我们可以加入Father对象或者其任何子类(如Son)对象,但由于编译器并不知道List的内容究竟是Father的哪个超类,因此不允许加入特定的任何超类(如Human)。...而当我们读取的时候,编译器在不知道是什么类型的情况下只能返回Object对象,因为Object是任何Java类的最终祖先类。但这样的话,元素的类型信息就全部丢失了。...2、super 可用于参数类型限定,不能用于返回类型限定(换句话说:? supper xxx 只能用于方法传参,因为jdk能够确定传入为xxx的子类,返回只能用Object类接收)。 3、?...既不能用于方法参数传入,也不能用于方法返回。 带有super超类型限定的通配符可以向泛型对象中写入,带有extends子类型限定的通配符可以向泛型对象读取。

    1.2K10

    Kotlin入门(14)继承的那些事儿

    博文《Kotlin入门(13)类成员的众生相》在演示类成员时多次重写了WildAnimal类,这下你兴冲冲地准备按照MainActivity的继承方式,从WildAnimal派生出一个子类Tiger,写好构造函数的两个输入参数...只有头戴open帽子的类,才允许作为基类派生出子类来;而头戴open帽子的函数,表示它允许在子类中进行重写。...抽象方法没有具体的函数体,故而外部无法直接声明抽象类的实例;只有在子类继承之时重写抽象方法,该子类方可正常声明对象实例。...根据上述的抽象类方案,定义好的Chicken类代码示例如下: //子类的构造函数,原来的输入参数不用加var和val,新增的输入参数必须加var或者val。...于是乎,通过接口定义几个抽象方法,然后在实现该接口的具体类中重写这几个方法,从而间接实现C++多重继承的功能。

    1.6K50

    C#中虚方法(virtual)详解

    七.虚方法的作用: 一.虚方法的定义: 当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法,虚方法是使用关键字virtual声明的,虚方法可以在不同的继承类中有不同的实现,即为基类中定义的允许在派生类中重写的方法...; } } 三.虚方法的调用: 调用上,使用子类构造的对象调用虚方法,就会调用子类的方法,使用父类构造的对象,就会调用父类的方法;(在规则 4 中有举例说明) 1.在基类中声明的虚方法一般在派生类中对其进行调用...子类继承虚拟类可以实现虚拟方法也可以不实现虚拟方法; 如下代码所示,在调用虚方法时,对虚方法进行了重写,这样代码执行下来的就是子类的方法而不是父类的虚方法::: class Person { public...,在派生类中可以对其方法进行调用,而且可以通过重写来改变其中实现的功能来实现自己的一些功能,而不是虚方法时,必须重新声明方法然后再进行自己想要的功能进行编写然后再进行调用,但是虚方法只需要在派生类中对其进行调用...而在基类调用时,并不需要知道派生类是怎么样实现的。因为不同的派生类可能实现的方式不一样。

    69840
    领券