多态是指一个程序中同名的不同方法共存的情况。在Java中,常见的有三种多态形式:方法重载实现的多态;方法覆盖实现的多态;引用类型变量实现的多态。这里主要讲引用类型实现的多态。
例:动物中的猫狗:
猫这个对象对应的类型是猫类型,即 猫 x=new 猫();
同时猫也是动物中的一种,也可以把猫称为动物,即 动物 y=new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
因此,多态的核心思想:父类型引用指向子类对象。
多态在程序中的体现:父类或者接口的引用指向或者接收自己的子类对象。
好处和作用:多态的存在提高了程序的可扩展性和后期可维护性。
多态的前提:需要存在继承或者实现关系;要有覆盖操作。
多态的特点:
成员函数:编译时,要查看**引用变量所属的类中**是否有所调用的成员。
运行时,要查看***对象所属的类中***是否有所调用的成员。
成员变量:只看引用变量所属的类。
通俗地可理解为:成员变量是资产,成员方法是行为,是瞬时的,所以方法是可以覆盖的,而属性的值各是各的。(类中的方法可以覆盖,成员变量不能覆盖)。
class PolyDemo1{
public static void main(String[] args){
Jing8 jing8=new Jing8();
jing8.shout();
System.out.println(jing8.name);
Dog d1=jing8; //多态
d1.shout();
System.out.println(d1.name);
}
}
abstract class Animal{
abstract void shout();
}
class Dog extends Animal{
public string name="小白";
public void shout(){
System.out.println("汪汪!");
}
}
class Jing8 extends Dog{
public string name="大黄";
public void shout(){ //对父类的方法进行重写
System.out.println("汪....汪....汪.....");
}
}
执行结果:
汪....汪....汪.....
大黄
汪....汪....汪.....
小白
由结果可知,在多态中,shout()方法因为重写被覆盖了,但是name属性却没有。
问题:在这种情况写如何才能访问到父类的成员变量呢?见如下代码:
class PolyDemo2{
public static void main(String[] args){
Car c=new Benz(); //多态
System.out.println(c.getColor());
}
}
class Car{
private String color = "无色";
public void setColor(String color){
this.color=color;
}
public String getColor(){
return color;
}
}
class Benz extends Car{
private String color = "黑色";
public void setColor(String color){ //重写方法时,可以调用父类的成员,但要注意成员的可见性。
super.setColor(color);
}
public String getColor(){
return super.getColor(); //这里利用super调用了父类的getColor方法,所以返回的应该是父类的颜色。注意:这里不能用super(),因为这是构造函数的调用;也不能用super.color,因为color在父类中是私有成员,不能访问。
}
}
结果:无色
这就实现了对父类成员变量的访问。