重载、继承(及多态)
来源:互联网 发布:软件测试 课程介绍 编辑:程序博客网 时间:2024/06/15 15:59
链接:https://www.zhihu.com/question/52767718/answer/143989505
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
引用@invalid s
在这个问题面向对象编程的弊端是什么? - 计算机科学 - 知乎
下面的一段回答:
封装:封装的意义,在于明确标识出允许外部使用的所有成员函数和数据项,或者叫接口。
有了封装,就可以明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者;而外部调用者也可以知道自己不可以碰哪里。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。
继承+多态:继承和多态必须一起说。一旦割裂,就说明理解上已经误入歧途了。
先说继承:继承同时具有两种含义:其一是继承基类的方法,并做出自己的改变和/或扩展——号称解决了代码重用问题;其二是声明某个子类兼容于某基类(或者说,接口上完全兼容于基类),外部调用者可无需关注其差别(内部机制会自动把请求派发[dispatch]到合适的逻辑)。
再说多态:基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同。
很显然,多态实际上是依附于继承的两种含义的:“改变”和“扩展”本身就意味着必须有机制去自动选用你改变/扩展过的版本,故无多态,则两种含义就不可能实现。
所以,多态实质上是继承的实现细节;那么让多态与封装、继承这两个概念并列,显然是不符合逻辑的。不假思索的就把它们当作可并列概念使用的人,显然是从一开始就被误导了——正是这种误导,使得大多数人把注意力过多集中在多态这个战术层面的问题上,甚至达到近乎恶意利用的程度;同时却忽略了战略层面的问题,这就致使软件很容易被他们设计成一滩稀屎(后面会详细谈论这个)。
先说封装,封装的目的就是“互不影响”,模块的设计者可以随便修改模块里面的实现而不影响调用者,调用者也能知道自己能碰哪些东西,只要遵守这个协议,自己的代码就不会因为模块内部的实现变化而跟着完蛋。题主说“封装就是模板设计出来就是固定死的,不能改变,弄成三角形不行,你把中国人民银行印在右上角不行,印上美国人民银行也不行,印上你爸头像更不行。”说对了一部分,还有另一个部分是,假如有一天印钱的人真打算把“中国人民银行”改成“美国人民银行”了,也不会影响用它的人。
再说继承和多态,就像上面引用内容所说的,我在任何时候都反对把这两个概念拆开来看,这两个事情合起来才是和“封装”等价的。一般来讲,我们用继承和多态,只有在你希望某一个函数的行为不同的时候才需要。像5元,10元,20元RMB这个例子的话,只要你在成员里面搞一个value就好了,所以严格来说不能算是多态。除非这些纸币对于一个同样的方法各自独特的行为(即虚函数的作用),那么多态才是有价值的。
如果真写成代码,可能是这样的:
abstract class Money{ private final string bankName = "中国人民银行"; public string getBankName(){return bankName;} public abstract int value();} class NoteFiveYuan extends Money{ public int value(){return 5;}}class NoteTenYuen extends Money{ public int value(){return 10;}}static int main(){ ArrayList<Money> wallet = new ArrayList<>(); wallet.Add(new NoteFiveYuan()); wallet.Add(new NoteTenYuan()); for(Money money : wallet) { println(money.getBankName()); println(money.value()); }}
如果Money的设计者把“中国人民银行”改成了“美国人民银行”,你会发现其他地方完全不需要修改,这就是封装的好处;尤其是如果getBankName里面有一些复杂操作的话,好处会更明显。
如果没有继承和多态,你就做不到把两个类的实例全扔到同一个wallet里面,并且在面对每一个Money的时候,你还必须得去手动判断他到底是哪种Money。现在有了继承和多态,只要你采用覆盖虚函数的方法,根本不用操心。更关键的是,如果以后还有30元的货币类,只要也继承Money并重写value,那么主函数里面数钱的那一段根本就不用动。
- 重载、继承(及多态)
- 继承重载重写多态
- 重载与重写,继承与多态
- 重载与多态,接口与继承
- 封装继承多态,方法重载覆盖
- 封装继承多态_继承重写重载
- EasyJS 教程四 - 实现继承及重载
- 继承类的重载函数及覆盖
- 【C/C++学院】(10)重载与重写/多态的深入/多继承接口
- C/C++一些知识4(重载与多态、虚继承)
- Java基础温习 (6)重载,重写以及继承,多态的区别
- C++中的重载运算符、继承、封装、多态讲解(进阶篇)
- 重载,继承,重写和多态的区别:(个人感觉讲述的很通俗易懂)
- C#面向对象(OOP)入门—第一天—多态和继承(方法重载)
- 重载,继承,重写和多态的区
- 重载,继承,重写和多态的区别
- 重载,继承,重写和多态的区别
- 重载,继承,重写和多态的区别
- eclipse遇到The requested resource is not available.
- 数据库分析01
- Android百度地图点聚合开发
- [Linux/Ubuntu] vi/vim 使用方法讲解
- hdu 6000 Wash(优先队列)
- 重载、继承(及多态)
- iOS黑魔法-Method Swizzling
- Optional int parameter 'id' is present but cannot be translated into a null value due to being decla
- mina----API
- EasyUI使用
- Easy Climb UVA
- C#(Csharp)+OpenCL+CLBLAS库,实现GPU高性能计算。
- 字符串处理函数
- Eclipse去掉空格,";""="键自动补全第一行