class Test{
public static void main(String[] args) {
Animal a1=new Animal();
a1.move();
Cat c1=new Cat();
c1.move();
Bird b1=new Bird();
b1.move();
}
}
class Animal{
public void move() {
System.out.println("动物在移动");
}
}
class Cat extends Animal{
public void move() {
System.out.println("猫在走猫步");
}
}
class Bird extends Animal{
public void move() {
System.out.println("鸟儿在飞行");
}
}
以上代码运行结果为:
动物在移动
猫在走猫步
鸟儿在飞行
重写了就调用了子类的
语法:
Animal a2=new Cat();
Animal a3=new Bird();
程序不报错,编译通过
分析:
1.Animal和其他两个类是继承关系,Animal是父类,Cat,Bird是子类
2.Cat is a Animal这句话可以说通
3.父类型的引用允许指向子类型的对象
a2是父类型的引用,new Cat()是子类型对象
基础语法:
1.向上转型
子---->父
2.向下转型
父---->子
注意:
java中允许向上或向下转型,前提是有继承关系
a2.move();
a3.move();
结果是:
猫在走猫步
鸟儿在飞行
却不是执行Animal方法中的move()方法,类型却是Animal
分析:
a2.move()
第一,编译阶段:
对于编译器来说,编译器只知道a2的类型是Animal,
所以编译器检查语法的时候,会去Animal.class
字节码文件中找到move()方法,找到了就绑定上move()
方法,编译通过,静态绑定成功。
第二,运行阶段
运行阶段的时候,实际上在堆内存当中创建的java对象是
Cat对象,所以move的时候,真正参与move的对象是一只猫,
所以运行阶段会动态执行Cat对象的move()方法,这个阶段属于
运行阶段绑定。
多态表示多种形态:
编译一种形态,运行一种形态
编译父类,运行子类
class Test{
public static void main(String[] args) {
Animal a1=new Animal();
a1.move();
Cat c1=new Cat();
c1.move();
Bird b1=new Bird();
b1.move();
Animal a2=new Cat();
Animal a3=new Bird();
a2.move();
a3.move();
Animal a4=new Cat();
a4.catchMouse();
}
}
class Animal{
public void move() {
System.out.println("动物在移动");
}
}
class Cat extends Animal{
public void move() {
System.out.println("猫在走猫步");
}
public void catchMouse() {
System.out.println("猫正在抓老鼠");
}
}
class Bird extends Animal{
public void move() {
System.out.println("鸟儿在飞行");
}
}
代码报错,编译阶段时候,代码先对Animal类进行检查,但是找不到相应的catchMouse()方法,编译立马报错。
这时候就要引用向下转型
2.向下转型:
要访问子类中特有的方法,运用向下转型
(强制类型转换):
Animal a4=new Cat();
Cat x=(Cat)a4;
x.catchMouse();
向下转型,访问子类的方法
但是向下转型有风险:
Animal a5=new Cat();
Bird y=(Bird)a5;
a5.move();
编译不报错,运行报错
Exception in thread "main" java.lang.ClassCastException: class javaTest.Cat cannot be cast to class javaTest.Bird (javaTest.Cat and javaTest.Bird are in module javaTest of loader 'app')
java.lang.ClassCastExoeption;
避免风险:
instanceof
运行阶段动态判断引用指向对象类型
引用 instanceof 类型
Animal a5=new Cat();
if(a5 instanceof Animal) {
Cat y=(Cat)a5;
y.catchMouse();
}
作用:
class Test{
public static void main(String[] args) {
//创建主人对象
Master zhangsan=new Master();
Dog zanao=new Dog();
zhangsan.feed(zanao);
}
}
class Dog{
public void eat() {
System.out.println("狗吃屎");
}
}
class Master{
public void feed(Dog d) {
d.eat();
}
}
过了一段时间,主人要养新宠物
class Cat{
public void eat() {
System.out.println("猫吃鱼");
}
}
public void feed(Cat c) {
c.eat();
}
新添加方法,喂养猫,需求添加。
主人扩展了功能,但是修改代码太多了
直接添加不修改原先程序
加一个宠物类,主人可以直接喂养宠物,这个宠物想要什么就什么
class Test{
public static void main(String[] args) {
//创建主人对象
Master zhangsan=new Master();
Dog zanao=new Dog();
Cat mimi=new Cat();
zhangsan.feed(zanao);
zhangsan.feed(mimi);
}
}
class Dog extends pet{
public void eat() {
System.out.println("狗吃屎");
}
}
class Master{
public void feed(pet p) {
p.eat();
}
}
class Cat extends pet{
public void eat() {
System.out.println("猫吃鱼");
}
}
class pet{
public void eat() {
}
}
编译时候是pet,运行是具体宠物:
实现多态