赞
踩
多态
什么是多态
同一个对象,在不同时刻表现出来的不同形态.
我们可以说猫是猫:猫 cat = new 猫();
我们也可以说猫是动物:动物 animal = new 猫();
这里猫在不同的时刻表现出来了不同的形态,这就是多态
多态的前提
要有继承/实现关系
要有方法的重写
要有父类引用指向子类对象
多态的特点:
需要有继承关系
方法重写
父类引用执行子类对象
public static void main(String[] args) {
// Animal a = new Animal();
// Cat c = new Cat();
// 父类引用指向子类对象
Animal cat = new Cat();
Animal dog = new Dog();
System.out.println(cat.leg);//2
System.out.println(dog.leg);//2
cat.eat();//猫吃鱼
dog.eat();// 狗吃骨头
}
多态访问成员变量的 特点:
在多态中,如果在 子类和父类中出现同名的成员变量 则使用的是父类的成员变量
总结:成员变量的访问: 编译看左边 运行看左边
多态访问成员方法的特点:
在多态中,如果子类重写了父类 的方法。则使用的是子类的方法
总结:成员方法的 访问:编译看左边 运行看右边
若编译时类型和运行时类型不一致, 就出现了对象的多态性(Polymorphism)
多态情况下成员方法, “看左边” : 看的是父类的引用(父类中不具备子类特有的方法)
“看右边” : 看的是子类的对象(实际运行的是子类重写父类的方法)
成员变量: 不具备多态性,只看引用变量所声明的类。
使用多态来调用方法 只能调用子类和父类都有的方法(必须存在方法的重写)。而不能调用子类 特有的方法
多态的好处和弊端(记忆)
好处
提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
弊端
不能使用子类的特有成员
public class Person {
// 人要饲养一只动物 使用父类作为参数 当引用的时候 传入具体所指的真实 子类
public void siyang(Animal animal){
animal.eat();
}
}
public static void main(String[] args) { // Animal a = new Animal(); // Cat c = new Cat(); // 父类引用指向子类对象 Animal cat = new Cat(); Animal dog = new Dog(); System.out.println(cat.leg);//2 System.out.println(dog.leg);//2 cat.eat();//猫吃鱼 dog.eat();// 狗吃骨头 Person person = new Person(); person.siyang(cat);// 传入真实的所引用的对象 person.siyang(dog);//传入真实 的所引用的对象 }
对于子类特有成员的 访问
// 只有 真实的类型对象 才能调用当前子类中特有的 方法
Cat c = new Cat();
Dog d = new Dog();
c.play();
d.work();
// 进行类型转换
Cat cc = (Cat) cat;
cc.play();
Dog dd = (Dog) dog;
dd.work();
类型转换
类型提升:将父类型的引用 执行子类对象 由小到大 进行自动转换(多态)
造型 :将父类型的引用对象 转换为子类型的对象 由大到小 强制转换
• 从子类到父类的类型转换可以自动进行
• 从父类到子类的类型转换必须通过造型(强制类型转换)实现
• 无继承关系的引用类型间的转换是非法的
在类型转换中 (造型)
Dog dog1 = (Dog) cat;
dog1.work();
类型转换异常
如何解决类型转换异常的出现:
Instanceof 判断一个引用是否是某一个类的实例对象
if(cat instanceof Dog){
Dog dog1 = (Dog) cat;
dog1.work();
}else{
System.out.println("类型不匹配");
}
方法的重载与重写
重载,是指允许存在多个同名方法,而这些方法的参数不同。 编译器根据方法不同的参数表, 对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。 它们的调用地址在编译期就绑定了。 Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以: 对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定” ;
而对于多态,只有等到方法调用的那一刻, 解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”
案例:计算图形面积
定义三个类,父类GeometricObject代表几何形状,子类Circle代表圆形, MyRectangle代表矩形。
定义一个测试类GeometricTest, 编写equalsArea方法测试两个对象的面积是否相等(注意方法的参数类型,利用动态绑定技术),编写displayGeometricObject方法显示对象的面积(注意方法的参数类型,利用动态绑定技术)。
public class GeometricObject { protected String color; protected double weitht; public GeometricObject(String color, double weitht) { this.color = color; this.weitht = weitht; } public String getColor() { return color; } public void setColor
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。