面向对象 子类为什么可以改变父类的功能?怎么改变?

要想了解这个问题怎么回答,我认为首先我们应该了解下Java中的一个重要的语法:

首先,一个Java程序的执行要经过编译和执行(解释)这两个步骤,同时Java又是面向对象的编程语言。当子类和父类存在同一个方法,子类重写了父类的方法,程序在运行时调用方法是调用父类的方法还是子类的重写方法呢,这应该是我们在初学Java时遇到的问题。这里首先我们将确定这种调用何种方法实现或者变量的操作叫做绑定。

在Java中存在两种绑定方式,一种为静态绑定,又称作早期绑定。另一种就是动态绑定,亦称为后期绑定。

1.静态绑定发生在编译时期,动态绑定发生在运行时
2.使用private或static或final修饰的变量或者方法,使用静态绑定。而虚方法(可以被子类重写的方法)则会根据运行时的对象进行动态绑定。
3.静态绑定使用类信息来完成,而动态绑定则需要使用对象信息来完成。
4.重载(Overload)的方法使用静态绑定完成,而重写(Override)的方法则使用动态绑定完成。

这里展示一个重载方法的示例。

在上面的代码中,call方法存在两个重载的实现,一个是接收Object类型的对象作为参数,另一个则是接收String类型的对象作为参数。str是一个String对象,所有接收String类型参数的call方法会被调用。而这里的绑定就是在编译时期根据参数类型进行的静态绑定。

光看表象无法证明是进行了静态绑定,使用javap -C 编译一下即可验证。

上面的代码,Caller中有一个call方法的实现,SubCaller继承Caller,并且重写了call方法的实现。我们声明了一个Caller类型的变量callerSub,但是这个变量指向的时一个SubCaller的对象。根据结果可以看出,其调用了SubCaller的call方法实现,而非Caller的call方法。这一结果的产生的原因是因为在运行时发生了动态绑定,在绑定过程中需要确定调用哪个版本的call方法实现。

使用javap不能直接验证动态绑定,然后如果证明没有进行静态绑定,那么就说明进行了动态绑定。

下面的例子有点{{BANNED}}哈,Caller类中存在call方法的两种重载,更复杂的是SubCaller集成Caller并且重写了这两个方法。其实这种情况是上面两种情况的复合情况。

下面的代码首先会发生静态绑定,确定调用参数为String对象的call方法,然后在运行时进行动态绑定确定执行子类还是父类的call实现。

由于上面已经介绍,这里只贴一下反编译结果啦


其实理论上,某些方法的绑定也可以由静态绑定实现。比如:


比如这里callerSub持有subCaller的对象并且callerSub变量为final,立即执行了call方法,编译器理论上通过足够的分析代码,是可以知道应该调用SubCaller的call方法。

然后我们再次假设这个框架1.1版本中BaseCaller不重写SuperCaller的call方法,那么上面的假设可以静态绑定的call实现在1.1版本就会出现问题,因为在1.1版本上super.call应该是使用SuperCall的call方法实现,而非假设使用静态绑定确定的BaseCaller的call方法实现。

所以,有些实际可以静态绑定的,考虑到安全和一致性,就索性都进行了动态绑定。

由于动态绑定需要在运行时确定执行哪个版本的方法实现或者变量,比起静态绑定起来要耗时。

所以在不影响整体设计,我们可以考虑将方法或者变量使用private,static或者final进行修饰。

综上所述:  理解了动态绑定和静态绑定后,回头我们在来看我们的问题

Java中子类重写了父类的某个方法后,父类中还可以调用自己被重写的那个方法吗?

答案是: 如果父类声明指向自己子类的实例对象,那么可以通过父类声明调用子类重写的那个方法, 如果父类声明指向的是父类本身那么可以调用父类实例中的方法。

ok! 我们说了太长了,我们就到这里,希望能够对你有所帮助!

}

前几天,在茫茫的互联网海洋中寻寻觅觅,把收藏的800道Java经典面试题都发出来,有小伙伴私聊我要答案。所以感觉没有答案的面试题是没有灵魂的,于是今天先整理基础篇的前80道答案出来哈~

所有的Java面试题已经上传github,答案也上传了一部分~

Comparable & Comparator 都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

switch可以支持字符串判断条件

78. 同步和异步有什么区别?

同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。

异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。

同步,就是实时处理(如打电话)

异步,就是分时处理(如收发短信)

参考这篇文章~ 同步和异步的区别

79. 实际开发中,Java一般使用什么数据类型来代表价格?

可以看这篇文章,写得非常好

int数据类型占4个字节 32位,跟JVM位数没关系的

}

发布时间: 17:23:49 来源:亿速云 阅读:116 作者:iii 栏目:

本文小编为大家详细介绍“Python面向对象,超类和抽象的概念是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python面向对象,超类和抽象的概念是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

在面向对象编程中,术语对象大致意味着一系列数据 (属性) 以及一套访问和操作这些数据的方法。

封装讲究结构复用,逻辑内敛,以固定接口对外提供服务。其遵循单一职责,规定每个类型仅有一个引发变化的原因。单一封装的核心是解耦和内聚,这让设计更简单,清晰,代码更易测试和冻结,避免了不确定性。

继承在遵循原有设计和不改变既有代码的前提下,添加新功能,或改进算法。其对应开闭原则,对修改封闭,对扩展开放。

多态特性遵循里氏替换原则,所有继承子类应该能直接用于引用父类的场合。

我们习惯于将复杂类型的公用部分剥离出来,形成稳固的抽象类。其他引发变化的相似因素则被分离成多个子类,以确保单一职责得到遵守,并能相互替换。

我们习惯于将复杂类型的公用部分剥离出来,形成稳固的抽象类。其他引发变化的相似因素则被分离成多个子类,以确保单一职责得到遵守,并能相互替换。

场景:先将整体框架抽象成基类,然后每个子类仅保留单一分支逻辑。

当我们需要编写 Dog 和 Cat 类时,就可以直接从 Animal 类继承:

继承的好处一:子类获得了父类的全部功能,扩展子类自己的功能

当子类的 run() 覆盖了父类的 run() 时候,运行时总是会调用子类的 run() 。这样,我们就获得了继承的另一个好处:多态。

判断一个变量是否是某个类型可以用 isinstance() 判断:

所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行:

要指定超类,可在 class 语句中的类名后加上超类名,并将其用圆括号括起。

Filter 是一个过滤序列的通用类。实际上,它不会过滤掉任何东西。

请注意 SPAMFilter 类的定义中有两个要点。

  • 以提供新定义的方式重写了 Filter 类中方法 init 的定义。

  • 直接从 Filter 类继承了方法 filter 的定义,因此无需重新编写其定义。

第二点说明了继承很有用的原因:可以创建大量不同的过滤器类,它们都从 Filter 类派生而来,并且都使用已编写好的方法 filter。

你可以用复数形式的 __ bases __ 来获悉类的基类,而基类可能有多个。为说明如何继承多个类,下面来创建几个类。

这被称为多重继承,是一个功能强大的工具。然而,除非万不得已,否则应避免使用多重继承,因为在有些情况下,它可能带来意外的 “并发症”。 

使用多重继承时,有一点务必注意:如果多个超类以不同的方式实现了同一个方法 (即有多个同名方法),必须在class 语句中小心排列这些超类,因为位于前面的类的方法将覆盖位于后面的类的方法。

因此,在前面的示例中,如果 Calculator 类包含方法 talk,那么这个方法将覆盖 Talker 类的方法 talk (导致它不可访问)。

将导致 Talker 的方法 talk 是可以访问的。多个超类的超类相同时,查找特定方法或属性时访问超类的顺序称为方法解析顺序 (MRO),它使用的算法非常复杂。

一般而言,抽象类是不能实例化的类,其职责是定义子类应实 现的一组抽象方法。

这里的要点是你使用 @abstractmethod 来将方法标记为抽象的 —— 在子类中必须实现的方法。

抽象类(即包含抽象方法的类)最重要的特征是不能实例化。

由于没有重写方法 talk,因此这个类也是抽象的,不能实例化。如果你试图这样做,将出现类似于前面的错误消息。然而,你可重新编写这个类,使其实现要求的方法。

现在实例化它没有任何问题。这是抽象基类的主要用途,而且只有在这种情形下使用 isinstance 才是妥当的:如果先检查给定的实例确实是 Talker 对象,就能相信这个实例在需要的情况下有方法 talk。

读到这里,这篇“Python面向对象,超类和抽象的概念是什么”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。

}

我要回帖

更多关于 父类 子类 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信