一.背景说明
关于重载(Overload)和重写(Override),在实际开发中使用非常频繁,涉及到的背景知识并不难。
但它们是面向对象中非常典型的应用——体现了面向对象的多态性。
二.重载
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。(因此,返回类型不可以作为区分方法是否重载的依据)
最常用的地方就是构造器的重载,比如在ThreadPoolExecutor线程池的实现类中,可看到如下的重载方法。
注意:除构造器以外,编译器禁止在其他任何地方中调用构造器。
再举一个编程中的例子,对于同一个方法math();
小结1:
简单说,就是同样的一个方法能够根据输入数据的不同,做出不同的处理,即方法的重载。体现了一个类中的多态性,多态表现在参数列表的不同。
三.重写
重写是发生在类的继承关系,或者类的实现关系中的。
重写后的方法和原方法需要保持完全相同的返回值类型、方法名、参数个数以及参数类型,简单来说,就是子类重写的方法必须和父类保持完全一致,而方法体重新编写。
<1>.继承
我们举一个简单的例子说明:
在这个案例中,Animal是一个属于动物的类,它定义了一个方法move()。表示动物的具有的行为。
而动物只是一个广泛的类,具体到某种动物时,行为方式是不同的,因此定义了Bird和Dog,分别继承了Animal这个类,并且重写了move()方法,分别实现这两种动物的行为方式。
小结2:
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
重写体现了类与类之间的多态性。
注意:
1.在类继承关系中,父类的非抽象方法,子类是不强制要求重写的。在实际应用中,如果重写了父类的方法,并且实例对象的引用指向的是子类时,JVM会自动调用子类重写的方法,此时,父类的方法完全被屏蔽了。
父类引用指向子类实现Dog(),此时调用dog.move()方法,只会调用到Dog类中的move()方法。如果Dog子类没有重写move()方法,则会调用父类Animal的move()方法。
2. Super关键字
当需要在子类中调用父类的被重写方法时,要使用 super 关键字。
<2>.实现
接口可以看作一种特殊的类,由于接口只是一种行为规范,本身不提供实现,因此实现接口的子类,都“必须”要重写父类的方法,这个和类继承是有区别的。
基于接口实现的重写,在实际应用中,使用非常频繁,以线程实现为例:
Runnable是一个接口,它定义了线程的执行方法,其中有一个抽象方法run()代码如下:
Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方 法就是通过Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线 程,并执行 run()方法。
小结3:
接口中未实现的方法都是抽象的,子类必须要重写。
四.总结
多态性是面向对象编程的一种特性,和方法无关。
方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
优点:
重写多态性起作用,对调用被重载过的方法可以大大减少代码的输入量,同一个方法名只要往里面传递不同的参数就可以拥有不同的功能或返回值。
用好重写和重载可以设计一个结构清晰而简洁的类,可以说重写和重载在编写代码过程中的作用非同一般.
注:本文重点说明的是面向对象中多态性的应用,并没有详细说明具体使用规则。在实际开发中,重载与重写还有许多细节需要注意。