一、多态的介绍
关于多态,我觉得Thinking inJava开篇那句话讲的很到位——多态通过分离做什么和怎么做,从另一个角度将接口和实现分离开。乍一看确有些抽象,多态是分离做什么和怎么做?我们先来看一个例子,然后再去解释。
我们定义一个类Animal,里面存放一个方法为吃东西
Class Animal{
public void eat() {
System.out.println("我是动物,我要吃东西");
}
}
/**定义猫狗继承Animal并重写吃东西方法*/
Class Dog extends Animal{
public void eat() {
System.out.println("我是狗,要吃肉");
}
}
Class Cat extends Animal{
public void eat() {
System.out.println("我是猫,要吃鱼");
}
}
// 定义主人 有一个投食方法
class Master {
// 给动物喂食物,如果没有多态,他要写给猫喂食和给狗喂食两个方法
// 有了多态,以后即使再来好多动物,用这一个函数就可以了
public void feed(Animal an) {
an.eat();
}
}
/**写一个main来调用上面定义的类*/
public static void main(String args[]) {
Master master = new Master();
master.feed(new Dog());
master.feed(new Cat());
}
输出:我是狗,要吃肉
我是猫,要吃鱼
在上面的例子里,我们调用了Animal的吃东西方法,传入了猫狗,但是实际调用的时候是猫狗对象的吃东西方法,所以这个时候,再就着这个例子看开头那句话,多态通过分离做什么和怎么做,从另一个角度讲接口和实现分离开。Animal这个基类的吃东西方法就是要做什么,然后导出类(Cat&Dog)的吃东西方法就是怎么做,即使继续新增什么仓鼠或者其他什么,也只是新增一个类使其继承Animal并重写导出类的eat方法即可。那么说了这么多,Java是怎么实现多态这么神奇的功能的呢。继续往下看。
在讲多态之前,几个概念需要先了解一下:向上转型、动态绑定。
向上转型:对象既可以作为自己的类型使用,也可以作为它的基类使用。而这种将对象的引用视为对其基类的引用的做法叫做向上转型。至于向上这个方向,是因为继承图里,基类在导出类的上方。
动态绑定:将一个方法调用同方法主体关联叫做绑定。如果是在程序运行前,通过编译器和程序实现的,就叫前期绑定,而到运行时,根据对象的类型进行绑定的,是后期绑定。
说明了上面两个概念后,我们就可以说使用多态的前提了:
Java实现多态有三个必要条件:继承、重写、向上转型。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
简单来说就是父类的方法是做什么,子类重写的方法是怎么做,然后通过向上转型来完成调用。
需要注意:
1.static和final方法都不能后期绑定。因此向上转型无法实现,所以只有普通的方法才可以使用多态。
2.如果基类的构造器中有调用基类的方法,且该方法在导出类中已经重写,在初始化基类的时候实际调用的是导出类的方法。
3.向上转型的话,导出类特有的方法不能通过基类来调用,这部分只能通过组合来实现。
二、多态的使用说明
多态可以使用以下几种方式实现:继承、接口、抽象类。关于继承实现,我们在上面用了一个比较详细的例子说明了,而接口&继承也基本相似。下面简单说明下:
1.继承实现多态
Class Animal {}
Class Cat Extends Animal{ }
//类的多态使用
method(new Cat())
2.抽象类多态定义的格式
abstract class Animal{
public abstract void method();
}
class Cat Extends Animal{
@Override
public void method(){
System.out.println(“重写父类抽象方法”);
}
}
3.接口多态定义的格式
interface Animal{
public abstract void method();
}
Class Cat implement Animal{
@Override
public void method(){
Syste.out.println("重写接口抽象方法")
}
}
至此,面向对象的三个基本特性就回顾完了,当然,这是立足于当前的知识点写的东西,后面有新的知识摄入的时候,还会继续补全。也希望各位能够不吝赐教,指出不足之处。总的来说,就是封装通过合并特征和行为来创建新的数据类型,实现隐藏则通过将细节私有化将接口和实现分离开来。继承允许将对象视为自己本身的类型或者其基类来处理,这样同一份代码可以无差别的运行在不同类型上了,而多态的作用则是消除类型间的耦合关系,多态方法调用允许一种类型表现出与其它相似类型的区别,只要他们都是从同一基类上倒出来的,这种区别是根据方法行为的不同而表示出来的。

2478

被折叠的 条评论
为什么被折叠?



