也说面试的火爆是让我震惊的。既然标榜为一个有使命感的程序员,我觉得有责任再写一篇关于多态的文字。我无意再次挑起非技术的争议。所以关于也说面试的回复并不包含在本文中。本文是一篇纯技术文字,里面有任何谬误请不吝指出。我思考再三题目中保留了“再说面试”四个字,让整个事情有始有终,因为我说过要写一篇这样的文章。但是阅读的时候请抛开面试这个背景。
我的文章大多枯燥无味我推荐你阅读Allen Lee或者idior的文章,或者Google更多的文章(使用多态或者Polymorphism作为关键字)。
一、什么是多态?
多态是OO中最关键的特性之一(GOF语)。GOF给的定义是:The ability to substitute objects of matching interface for one another at runtime。即,在运行时刻接口匹配的对象能互换的能力。在Wikipedia上则表述为...,polymorphism lets you treat derived class members just like there parent class's members。即,多态使得你可以向对待父类的成员那样对待派生类的成员。不够直观?In practical terms, polymorphism means that if class B inherits from class A, it doesn't have to inherit everything about class A; it can do some of the things that class A does differently。即,如果class B继承自class A,它不必从class A中继承所有的东西;对于某些方法,class B可以采用与class A不同的做法和实现。
在Java和C#的语言机制中,多态表现为后绑定(或者叫动态绑定、晚期绑定),有两种形式:继承父类并重载父类中具有相同签名的方法(即overriding或者overwriting);实现抽象父类(或接口)中具有相同签名的方法。当你对由父类声明的对象调用该方法时,对应的子类中的方法就会被调用。顺便说一句overloading通常不被认为是多态机制。
在OO思想中多态隐藏具体实现,使得客户端在不了解具体实现而只了解其接口的情况下可以访问对象的方法,这使得抽象成为可能。
二、多态和抽象的关系
还是采用Wikipedia的说法吧:abstraction is a mechanism and practice to reduce and factor out details so that one can focus on a few concepts at a time。即,抽象是一种可以使你一次只关注一个事物几个概念的机制和实践。我觉得还是从反面去解释更为简单,抽象就是不具体,就可以抛开你所不关心的细节。
抽象可以使我们对对象进行更好的分类。想象一下,没有抽象,当你面对一个电灯泡的时候会多么的无奈:
- 它有重量,这一点和石头很相似;
- 它有体积,这一点和石头也很相似;
- 它能发光,这一点和太阳很相似;
- 它耗电,这一点和风扇很相似;
- 它可以开关,这一点和门很相似。
- ......
这一切特性都属于灯泡,所以灯泡不是石头、不是太阳、不是风扇也不是门。没有抽象,当你要打算为电灯泡写一个开关的时候,它也只能处理电灯泡对象,因为这个世界上(系统中)没有另一个东西具有电灯泡的所有特性。
有了抽象,世界将会怎样?
- 你说电灯泡是一个有重量的对象所以它是个Weighable(可称重的),那个用来给石头称重的系统也适用于电灯泡!
- 你说电灯泡是一个有体积的对象所以它是个Stereometriable(可以求积的),那个用来给石头算体积的系统居然也适用!
- 你说电灯泡是一个可以开关的对象所以它是个个Switchable(可开关的),那个用来开关门的系统也可以开关电灯泡吧!
......现在我们可以为电灯泡的各种特性分类了,从不同的角度看待电灯泡。
这个时候你就发现你的系统对于电灯泡的依赖越来越低了,哪一天电灯泡不发光了(还叫电灯泡:)),你的开关函数居然还是不用重写呢。抽象相对于具体类要稳定,所以依赖于抽象也比依赖于具体类要稳定。
并不是说没有多态就做不到抽象,只是没有多态抽象就很难做得如此优雅。语言机制中的多态为抽象处理了大部分你不希望关心的细节。
三、多态与耦合的关系
耦合的定义:The degree to which software components depend on each other。即软件构件之间相互依赖的程度。当系统耦合越强的时候,系统越僵化、越不容易维护、不容易重用,更糟糕的是耦合越强的系统越不稳定。理论上系统中所有的构件之间都是耦合的,只是耦合的程度不同,所以我们追求解耦合实际上是追求松耦合。这篇文章称松耦合是软件的终极目标,虽然有些过激但是是非常有道理的。
解耦合的方法通常包括抽象耦合和增加层。抽象耦合:既然必须依赖,依赖于抽象总比依赖于具体要松一些(比如Observer模式)。增加层的方法有很多,在OO的机制内可以以委托的方式将部分职能转移到专门的类中(比如将创建职能转移到工厂中),而这个专门的类是一个相对稳定的类;也可以加入一个层隔离与不希望关心的构件的关系(比如Facade模式)。
抽象耦合在上一节已经讲了,与多态有着密切的联系。增加层的方法主要的idea是委托,与多态的关系不大。
太晚了今天先写到这里吧,下面可能加入一些演示多态和耦合的关系的例子,还包括多态和常见的OOD原则的关系,以及可能还会有多态和设计模式的关系。
分享到:
相关推荐
Java ------ 多态作业
GA(particle swarm optimization-genetic algorithm)和SA-PSO算法在相同条件下进行了比较,结果表明SA-PSO算法具有更强的搜索能力,可以更快地发现全局最优解,能更好地为包含多态信息的测试路径生成测试数据。
C++:类和对象-多态-练习题目1(利用多态实现计算器)
**多态**是指同一种行为在不同的对象上表现出不同的形式。在Java中,多态分为编译时多态(静态多态)和运行时多态(动态多态)。编译时多态主要通过方法重载实现,即在同一个类中定义多个同名但参数列表不同的方法。...
Python工具箱.zip - 办公自动化、多态文件搜索、高级加密。Python工具箱.zip - 办公自动化、多态文件搜索、高级加密。Python工具箱.zip - 办公自动化、多态文件搜索、高级加密。Python工具箱.zip - 办公自动化、多态...
论文研究-考虑随机权重阈值的多态.pdf, 在权重阈值随机变化的条件下,现有多态系统可用度建模在实际工程应用中具有局限性.本文引入数量阈值并考虑权重阈值随机性,分析...
例如,动物是父类,狗和猫是子类,那么我们可以说一个动物对象可以代表一个狗或猫,即使在程序中我们只知道它是动物类型。 接口多态则是通过实现一个或多个接口来实现的。接口在Java中是一种定义行为的抽象类型,它...
Educoder题目:Java面向对象 - 封装、继承和多态的综合练习答案解析
第8章--virtual函数与多态
多态有两种主要形式:静态多态(编译时多态)和动态多态(运行时多态)。静态多态主要通过方法重载和运算符重载实现,即在编译期间确定调用哪个方法。而动态多态依赖于继承和虚函数(或抽象方法),使得子类可以重写...
JAVA基础-第4章继承与多态-练习题 本资源是关于JAVA基础的第四章继承与多态的练习题,涵盖了继承、多态、构造方法、方法覆盖、final类等知识点。本资源共有9道选择题,考察了程序员对JAVA语言的掌握程度。 在第1题...
Educoder题目:Java面向对象 - 封装、继承和多态答案解析
miR-143基因启动子区多态变异与中国人群宫颈癌高发病风险显著相关,王适之,金华,目的:筛选miR-143基因启动子区可能影响其表达的多态变异(SNPs),研究其与宫颈癌遗传易感性的关系。方法:以571例宫颈癌患者和657...
三十一、多态多态指的是一类事物有多种形态,比如动物有多种形态:猫、狗、猪31.1 多态性def talk(animal: Animal): # 统一接口定义不考
继承实现了代码的复用与维护,修饰符控制了类和成员的访问权限,多态使得程序更加灵活,而抽象类为子类提供了一个共同的模板和抽象方法实现的要求。理解和掌握这些知识点对于学习和应用Java面向对象编程至关重要。
本资源摘要信息将对 Java 基础知识点进行总结,涵盖继承、封装、多态等概念,并对面向对象的设计、数据库设计模式等进行讲解。 继承 继承是 Java 中的一种机制,允许一个类继承另一个类的属性和方法。继承的语法是...