什么是多态 -- 转

也说面试的火爆是让我震惊的。既然标榜为一个有使命感的程序员,我觉得有责任再写一篇关于多态的文字。我无意再次挑起非技术的争议。所以关于也说面试的回复并不包含在本文中。本文是一篇纯技术文字,里面有任何谬误请不吝指出。我思考再三题目中保留了“再说面试”四个字,让整个事情有始有终,因为我说过要写一篇这样的文章。但是阅读的时候请抛开面试这个背景。

我的文章大多枯燥无味我推荐你阅读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模式)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多态是指同一行为具有多个不同的表现形式。在Java中,多态可以通过向上型和向下型来实现。向上型是指将子类类型换为父类类型,这个过程是默认的,可以通过父类类型的变量引用子类类型的对象。例如,Animal a = new Cat(); 这里Cat是Animal的子类,通过向上型,将Cat类型的对象赋值给Animal类型的变量a。这样,a可以调用Animal类的方法和属性,但无法调用Cat类特有的方法和属性。这是因为变量a被限定为Animal类型,只能访问Animal类中定义的方法和属性。这就是多态的向上型。 而向下型是指将父类类型换为子类类型的换过程,这个过程是强制的。在向上型后,如果需要使用子类特有的方法和属性,就需要进行向下型。向下型的语法是将父类类型的变量强制换为子类类型的变量。例如,Cat c = (Cat) a; 这里将Animal类型的变量a强制换为Cat类型的变量c。这样,变量c就可以调用Cat类特有的方法和属性,但需要注意的是,只有在向上型之后,才能进行向下型,否则会出现编译错误或运行时错误。这就是多态的向下型。所以,多态通过向上型和向下型实现了同一行为具有多个不同的表现形式的特性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [多态、向上型、向下型](https://blog.csdn.net/Iam_am_lbj/article/details/122458965)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值