目录
多态
多态的前提:
1. 满足继承关系或者实现关系(两个以上的类) 2. 有方法的重写(不强制, 但是不重写没意义)
多态的概念:
指的是一个事物在不同时刻下体现的不同形态,子类当下是以子类自身还是父类的形态去体现
多态的定义:
已有Cat类继承了Animal类, 用父类引用指向子类对象(表现形式)
Animal a = new Cat();
多态的访问特点
多态的分析分为编译和运行两个阶段,编译过程中父类引用会在父类中找调用的属性或者方法,能找到则编译通过
使用父类引用访问成员变量
编左看左: 编译和运行都看左边父类, 也就是说编译运行都看父类的成员变量值
public abstract Animal{
String name;
int age;
}
class Cat extends Animal{
int age = 10;
}
class Test{
public static void main(String[] args){
Animal a = new Cat();
System.out.println(a.age);
}
}
使用父类引用访问成员方法
编左看右: 编译看左边,运行看右边, 父类有该成员方法才能编译通过,但运行时访问的是子类重写后的方法
public abstract Animal{
public abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼..");
}
}
class Test{
public static void main(String[] args){
Animal a = new Cat();
a.eat();
}
}
多态的应用
1. 父类引用访问子类对象
public abstract Animal{
String name;
int age;
public abstract void eat();
}
class Cat extends Animal{
int age = 10;
public void eat(){
System.out.println("猫吃鱼..");
}
}
class Test{
public static void main(String[] args){
Animal a = new Cat();
System.out.println(a.age);
a.eat;
}
}
2. 隐藏在方法参数
public abstract Animal{
public abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼..");
}
}
class Test{
public static void main(String[] args){
Cat cat = new Cat();
//多态体现在这一步
useEat(cat);
}
public static void useEat(Animal a){
a.eat();
}
}
3. 隐藏在返回值
public interface Flyable{
//接口中方法不写public abstract 也会默认加上
void fly();
}
class Bird implement Flyable{
public void fly(){
System.out.println("小鸟扇动翅膀飞...");
}
}
class Plane implement Flyable{
public void fly(){
System.out.println("飞机靠发动机飞...");
}
}
class Test{
public static void main(String[] args){
//toFly()的返回值是Flyable 因此只能用Flyable的引用接收
Flyable f = toFly();
}
//这里的返回值是Flyable 因此只能用Flyable的引用接收
public static Flyable toFly(){
if(new Random().nextInt(10)%2==0){
return new Bird();
}else{
return new Plane();
}
}
}
多态的弊端与解决办法
在使用多态的过程中, 无论是访问成员变量还是成员方法, 只能访问父类已存在的内容无法访问子类特有的属性和方法, 否则编译不通过
针对这种情况,我们可以使用向下转型, 将父类引用更改为子类引用指向子类对象.
Animal a = new Cat();
//父类引用只能使用父类存在的方法
a.eat();
//向下转型后的子类对象可以调用子类独有的方法
Cat cat = (Cat)a;//需要强转
cat.catch();
在使用编写程序时 instanceof关键字 判断子类是否是父类 让我们更灵活使用多态的向下转向型
eg : cat instanceof Animal (true)
public static void useUsb(USB usb){
//USB对象特有方法
usb.powerOn();
//如果传进来的USB 是Mouse,向下转型成Mouse,执行Mouse特有的方法
if (usb instanceof Mouse){
Mouse mouse = (Mouse) usb;
mouse.click();
//如果传进来的usb是Keyboard,向下转型成Keyboard,执行Keyboard特有的方法
}else if (usb instanceof Keyboard) {
KeyBoard keyBoard = (KeyBoard) usb;
keyBoard.enter();
}
//USB对象特有方法
usb.powerOff();
}