多态的前提:
有继承关系
有方法重写
没有方法重写也是可以的,但是没有重写就没有意义
动物 d = new 猫();
d.show();
动物 d = new 够();
d.show();
有父类应用指向子类对象
父 f = new 子();
多态中的成员访问特点:
成员变量
编译看左边,运行开右边
构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化
成员方法
编译看左边,运行看右边
静态方法
编译看左边,运行看左边
(静态和类相关,算不上重写,所以,访问还是左边的)
由于成员方法存在方法重写,所以它运行看右边
多态的好处
提高了代码的维护性(继承保证)
提高了代码的扩展性(由多态保证)
多态的弊端
不能使用子类特有的功能(父类中必须有,子类重写)
如果想用需要以下方法建议方法2.
方法1:占内存
Fu f = new Zi();
Zi z = new Zi();
方法2:把父类的引用强制转换子类的引用(不占内存)(向下转型)
Fu f = new Zi();
Zi z = (Zi)f;
对象间的转型问题:
向上转型:
Fu f = new Zi();
向下转型:
Fu f = new Zi();
Zi z = (Zi)f; // 要求该f必须是能够转换为Zi的.
多态的应用示例:
class Animal{
String name;
int age;
public Animal(){
//无参构造方法
}
public Animal(String name,int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(“animal+eat”);
}
}
class Dog extends Animal{
public Dog(){
//无参
}
public Dog(String name,int age){
super(name,age);
}
public void eat(){
System.out.println(name+“吃狗粮”);
}
public void xunLian(){
System.out.println(name+“会坐卧躺”);
}
}
class Cat extends Animal{
public Cat(){
//无参
}
public Cat(String name,int age){
super(name,age);
}
public void eat(){
System.out.println(name+“吃猫粮”);
}
}
class DuoTai{
public static void main(String[] args){
Animal a = new Dog(“果冻”,2);
animalTool(a);
Animal a1 = new Cat(“二傻”,1);
animalTool(a1);
// 还原成狗 要调用子类特有方法需要向下转型成
Dog g = (Dog)a;
g.xunLian();
//把a1变成Animal类的对象狗
a1 = new Dog("五金",10);
animalTool(a1);
// 把a1还原成狗类的对象
Dog g1 = (Dog)a1;
g1.xunLian();
}
//定义Animal类工具 可以传递所有Animal类的 具体动物如new Dog();
public static void animalTool(Animal a){
a.eat();
}
}
注意 如果父类中定义了变量a 子类中也定义了变量a
Fu f = new Zi(); // 此时a变量的值为父类的
Zi z = (Zi)f; //此时a变量的值为子类的
例:
class Fu{
int a = 10;
}
class Zi extends Fu{
int a = 20;
}
class DuoTaiDemo{
public static void main(String[] args){
Fu f = new Zi();
System.out.println(f.a); // 10
Zi z = (Zi)f;
System.out.println(z.a); // 20
}
}