以一个方法为例谈Java的多态

引子

跟着马士兵老师的Java教学视频自学时,在常用类一章讲到String类里的一个方法:

java.lang.String
public static String valueOf(Object obj)

该方法返回Objcet参数的字符串表示,并体现了多态的应用。

多态的定义

在执行期间而非编译期间判断引用对象的实际类型,根据其实际类型调用其相应方法。

既然编译器在编译期间不知道哪些代码会被执行,程序是如何正确执行相应代码的呢?

为解决这个问题,面向对象程序设计语言使用了后期绑定概念。Java使用一小段特殊代码来替代绝对地址调用。这段代码使用在对象中存储的信息来计算方法体的地址,这样,根据这样一小段代码的内容,每一个对象都可以具有不同的行为表现。

—— Thinking in Java

多态的使用条件

多态在Java里运用非常广泛,是Java得以流行的关键因素。
再看方法:

public static String valueOf(Object obj)

方法里的形参类型是Object,Object类是Java所有类的父类,所有类从Object*继承。当我们传入的参数是是Object的子类时,该方法能自动识别,调用子类相应的方法,此时也被叫做向上转型(upcasting)*:把子类看做父类的过程。也被叫做父类引用指向子类对象。

在此例中,调用的是Object类和其子类的toString()方法。任何子类都会从Object类继承toString()方法,并重写方法。因为Object类里的toString()方法返回值太不友好,返回的是对象名加@符号加对象的整型无符号16进制哈希码,也就是这个东西:

 getClass().getName() + '@' + Integer.toHexString(hashCode())

所以子类通常会把这方法重写地更清晰明了(informative)。

该方法相当于引用obj调用子类相应的toString()方法,然后返回一个字符串。

综上可看出多态的使用需要满足三个条件:

  • 继承
  • 向上转型
  • 重写父类方法

多态的好处

上面粗略地谈了多态的定义和实现条件,那么使用多态到底能给程序设计带来什么好处呢?

最大的好处消除了类型之前的连接关系(coupling)。

试想有B、C、D三个类从类A继承,每个类需要一个从大写字母变为小写字母的方法,我们当然可以定义三个除了传入的类型参数不同而名字相同的方法(方法重载)。这样虽然麻烦但是直观,但如果此时实际需求变了(需求肯定会变的),需要再加入E、F、G类呢?按照直接的方法我们需要再重载三个方法。但是,在编程的世界里唯一不变的是变化,如果需求改变了还需要再加入HIJK…类呢?难道我们仍要继续做这种无聊的事吗?

此时只需要一个使用多态特性的方法即可:

public static void lowerToUpper(fatherClass fc) {

//代码块

}

该方法在执行期间会根据传入的对象的实际类型,根据实际类型对象中存储的信息计算方法的具体地址,调用实际类型的方法,而不是父类对象的方法。这样,只需一个方法就可代替一堆方法。

简单明了,省时省力,还可避免忘记重载某个方法编译器不会返回任何错误信息的失误。

PS:为了写这篇文章,除了学习马老师的视频所得还看了一点《Thinking in Java》里对多态的解释。不得不说,这本书的水平之高不愧经典之名。内容虽多,但很多内容即可巩固知识又可开阔眼界发散思维,是一本常看常新之书。

这是我的第一篇技术文章,虽已尽力书写,但作为新手还远未入Java之门,写起来十分费力。只求keep coding,提升水平,用写技术文章的方式总结反思。

你可能感兴趣的:(Java相关,java,多态)