java学习笔记-多态
多态概述:同一个对象 不同时刻 表现出来的不同形态
多态实现的前提
- 有继承或者实现关系
- 有方法重写
- 有父类引用指向子类对象
多态中成员变量的访问特点
- 构造方法:同继承一样,子类会通过super访问父类的构造方法
- 成员变量:编译看左边(父类),执行看左边 (父类)
- 成员方法:编译看左边(父类),执行看右边(子类)
为什么关于成员变量和成员方法 访问是 不一样的 因为 成员方法有重写覆盖的概念 成员变量没有
多态的好处与弊端
- 提高了程序的扩展性 具体体现:定义方法的时候 使用父类 作为参数 该方法就可以接受 该父类的任意子类对象
- 不能调用子类特有的内容
多态的转型
-
向上转型
从子类转换成父类 其实就是父类引用指向子类对象 -
向下转型
从父类到子类 父类引用转换成子类对象
package com.ustc.test4;
public class Test4Polymoric {
public static void main(String[] args) {
//向上转型 父类引用指向子类对象
Fu f = new Zi();
f.show();
//多态的弊端:不可以调用子类特有的方法
//f.method();
//向下转型 从父类类型 转换成子类类型
Zi z = (Zi)f; //强制类型转换
z.method();
}
}
class Fu{
public void show()
{
System.out.println("父类方法调用:");
}
}
class Zi extends Fu{
@Override
public void show()
{
System.out.println("子类方法调用:");
}
public void method()
{
System.out.println("子类特有的方法:");
}
}
多态中存在的风险
概述:如果被转换的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException
package com.ustc.test3;
public class Test1Polymorphic {
public static void main(String[] args) {
useDog(new Dog());
useCat(new Cat());
//这里首先 传来一个dog对象 向上转型 调用eat方法(共有的方法)
//之后又把 a转换成一个 dog对象 向下转型 调用dog类特有的方法 没有问题
//但是 传来一个Cat对象 这里 调用eat方法 没有问题
//但是第二次 将cat对象 转换成dog对象 出现错误
useAnimal(new Dog()); //Animal a = new Dog();
useAnimal(new Cat()); //Animal a = new Cat();
//注意
}
public static void useDog(Dog dog)
{
dog.eat();
}
public static void useCat(Cat cat){
cat.eat();
}
public static void useAnimal(Animal a)
{
a.eat();//一般的 只能调用子类与父类共有的方法
Dog d = (Dog)a;//向下转型 将父类转换成子类
d.watchHome();
}
}
abstract class Animal{
int num = 10;
public abstract void eat();
}
class Cat extends Animal
{
int num = 20;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dog extends Animal{
@Override
public void eat()
{
System.out.println("狗吃肉");
}
public void watchHome()
{
System.out.println("看家:");
}
}
避免问题:instanceof
if(a instaceof Dog){
Dog dog = (Dog)a
Dog.watchHome();
}