之前,都没有系统化的了解什么是多态,看了书后也没有透彻的理解。在网上找到一篇云中志的---bolg,写的非常好,根据https://www.cnblogs.com/caoleiCoding/p/8974568.html和自己书上的内容在进行总结。
多态(也称作动态绑定,后期绑定或者运行时绑定)
在面向对象的程序语言设计中,多态是继数据抽象和继承之后的第三种基本特征。
多态通过分离做什么和怎么做?一是将接口和实现分离,二是可以改善代码的组织结构和可读性。
多态方法的调用允许一种类型表现出与其他相似类型之间的区别,只要他们是同一个基类导出。虽然他们的方法都是同一个基类导出,但可以根据不同的方法行为表示出来。
多态的要求
- 多态的方法是多态的,(多态与熟悉无关)
- 多态有三个必要的条件:继承,重写,父类引用子类对象
- 父类引用指向子类对象后,该父类调用子类重写的方法
public class TestPolm {
public static void main(String[] args) {
Animal a = new Animal();
animalCry(a);
Dog dog = new Dog();
dog.shut();
Cat cat = new Cat();
cat.shut();
Animal cat2 = new Cat(); //向上转型
animalCry(cat2);//父类调用子类的方法
}
static void animalCry(Animal a){
a.shut();
}
}
class Animal{
public void shut(){
System.out.println("叫了一下!");
}
}
class Dog extends Animal{//继承条件满足
public void shut(){//方法重写条件满足
System.out.println("汪汪汪");
}
}
class Cat extends Animal{//继承条件满足
public void shut(){//方法重写条件满足
System.out.println("喵喵喵");
}
}
/**运行结果:
* 叫了一下!
* 汪汪汪
* 喵喵喵
* 喵喵喵
*/
父类的普通方法可以继承和重写,但是如果有static方法和final方法(private方法属于final方法)就没法多态,因为这两种方法只可以继承但是不能重写。可以看如下代码
public class StaticTest
{
public static void main(String[] args)
{
M m = new N();
m.output(); //输出M
N n = new N();
n.output(); //输出N
}
}
class M
{
public static void output()
{
System.out.println("M");
}
}
class N extends M
{
public static void output()
{
System.out.println("N");
}
}
可以看出含有静态方法通过向上转型,输出的还是父类的值,也证明静态方法可以继承,但是没法重写所以也不存在多态的说法。
向上转型
我们把某个对象的引用是为对其基类新的引用做法称作为---向上转型。其中最经典的例子就是书中关于图形的继承
简单的可以写成
Shape s = new Circle();
public class Test
{
public static void main(String[] args)
{
Cup aCup = new BrokenCup();//向上转型
aCup.addWater(10); // method binding
}
}
class Cup
{
public void addWater(int w)
{
this.water = this.water + w;
}
public void drinkWater(int w)
{
this.water = this.water - w;
}
private int water = 0;
}
class BrokenCup extends Cup
{
public void addWater(int w)
{
System.out.println("shit, broken cup");
}
public void drinkWater(int w)
{
System.out.println("om...num..., no water inside");
}
}
通过上述代码,我们可以看出尽管aCup是Cup的类型引用,但它实际的调用方法是BrokenCup的addWater()方法,通过了向上转型,从父类引用了子类对象,最终输出了正确的方法这就是多态。