1、多态
polymorphic
同类型的对象,执行同一个行为,会表现出不同的行为特征
1.1 多态的常见形式
- 父类类型 对象名称=new 子类构造器;
Animal animal = new Dog();//动物:狗、乌龟
- 接口 对象名称 = new 实现类构造器;
USB usb = new Mouse();//USB接口:鼠标、键盘
1.2 成员访问特点
- 方法调用:编译看左边(写代码看Animal有没有run方法),运行看右边(看Dog的run方法)
- 变量调用:编译看左边,运行也看左边(多态侧重于行为多态)
代码举例
/**
* 父类
*/
public abstract class Animal {
public String name = "父类名字";
public abstract void run();
}
/**
* 子类:狗
*/
class Dog extends Animal{
public String name = "狗类名字";
@Override
public void run() {
System.out.println("狗跑的贼快");
}
}
/**
* 子类:乌龟
*/
class Tortoise extends Animal{
public String name = "龟类名字";
@Override
public void run() {
System.out.println("乌龟跑的贼慢");
}
}
public class Test {
public static void main(String[] args) {
Animal animal1 = new Dog();
animal1.run();//方法调用:编译看左边(写代码看Animal有没有run方法),运行看右边(看Dog的run方法)
Animal animal2 = new Tortoise();
animal2.run();
System.out.println(animal1.name);//变量调用:编译看左边,运行也看左边
System.out.println(animal2.name);
}
}
运行结果
狗跑的贼快//方法执行看向子类
乌龟跑的贼慢
父类名字//始终调父类的变量
父类名字
1.3 多态的前提
- 有继承/实现关系;
- 有父类引用指向子类对象;
Animal animal1 = new Dog();
- 有方法重写
1.4 多态的优势
- 在多态的形式下,右边对象可以实现解耦,编译扩展和维护
- 定义方法的时候,使用父类型作为参数,该方法就可以接收父类的一切子类对象,体现出多态的扩展性与便利
Animal a = new Dog();
a.run();//后续业务随对象而变,后续代码无需修改(运行看右边),只需要该Dog类
方法回调
把对象地址给到dog,再把地址传入方法里面,运行看右边
1.5 多态下的问题
多态下不能使用子类的独有功能
解决方法
多态下引用数据类型(自己定义的一些类)的类型转换
- 自动类型转换(从子到父):子类对象赋值给父类类型的变量指向
- 强制类型转换(从父到子):子类 对象变量 = (子类)父类类型变量;
代码举例
/**
* 父类
*/
public abstract class Animal {
public String name = "父类名字";
public abstract void run();
}
/**
* 子类:狗
*/
class Dog extends Animal{
public String name = "狗类名字";
@Override
public void run() {
System.out.println("狗跑的贼快");
}
public void dog_own(){//狗狗独有的方法
System.out.println("狗狗独有");
}
}
/**
* 子类:乌龟
*/
class Tortoise extends Animal{
public String name = "龟类名字";
@Override
public void run() {
System.out.println("乌龟跑的贼慢");
}
public void t_own(){//乌龟独有的方法
System.out.println("乌龟独有");
}
}
public class Test {
public static void main(String[] args) {
Animal animal = new Dog();//对象回调
compete(animal);
// animal.dog_own();报错
Dog dog1 = (Dog)animal;//强制类型转换
dog1.dog_own();
// Tortoise tortoise1 = (Tortoise) animal;//编译阶段不会报错(注意:有继承或者实现关系编译阶段可以强制,没有毛病),运行时可能会报错ClassCastException类型转换错误
// tortoise1.t_own();
//使得各对象能调用自己独有的方法
//instanceof:判断真实类型
if(animal instanceof Tortoise){
Tortoise tortoise1 = (Tortoise) animal;
tortoise1.t_own();
}else if(animal instanceof Dog){
Dog d = (Dog)animal;
d.dog_own();
}
}
public static void compete(Animal animal){
System.out.println("比赛开始了");
animal.run();
System.out.println("比赛结束了");
}
}
java建议强转前后使用instanceof判断当前对象的真实类型,再进行强制转换
变量名 instanceof 真实类型
- 判断关键字左边的变量指向的对象的真实类型是否是右边的类型或是其子类,是就返回true……
运行结果
比赛开始了
狗跑的贼快
比赛结束了
狗狗独有
狗狗独有
下一篇:内部类,待续~~~