2022-7-25 学习日记(15th day)JAVA面向对象(多态)

目录

java多态

向上转型和向下转型

向上转型

向下转型

异常:


java多态

什么是多态?

多态,即多种形态、多种状态。编译期一种形态,运行期一种形态。
多态核心代码:父类型引用指向子类型对象

                                        !!!多态的前提是:有继承关系 !!!

public class Test {
	public static void main(String[] args){
		//父类型引用指向子类型对象
		Animal cat = new Cat();
		Animal dog = new Dog();
		//调用eat()
		cat.eat();
		dog.eat();
	}
}

class Animal {
	public void eat(){
		System.out.println("动物都能吃东西");
	}
}
//Cat继承Animal
class Cat extends Animal {
	//重写eat()
	public void eat() {
		System.out.println("猫吃猫粮");
	}
}
//Dog继承Animal
class Dog extends Animal {
	//重写eat()
	public void eat() {
		System.out.println("狗吃狗粮");
	}
}

 运行的结果:

猫吃猫粮

狗吃狗粮

向上转型和向下转型

向上转型

子类型 —> 父类型

父类 父类对象=new 子类
向上转型可以自动转换

向下转型

父类型 —> 子类型

子类 子类对象=new 父类
向下转型需要加强制类型转换符

前提:必须先发生向上转型

那么什么时候需要使用向下转型呢?

 在多态中,父类型引用子类型对象时,如果需要访问子类特有的属性或方法时,需要向下转型,否则编译无法通过。

public class Test {
	public static void main(String[] args){
		//父类型引用指向子类型对象(自动类型转换)
		Animal cat = new Cat();
		Animal dog = new Dog();

		//子类特有方法catchMouse()
		cat.catchMouse();
	}
}

class Animal {
	public void eat(){
		System.out.println("动物都能吃东西");
	}
}

class Cat extends Animal {
	//重写eat()
	public void eat() {
		System.out.println("猫吃猫粮");
	}
	public void catchMouse() {
		System.out.print("猫抓老鼠");
	}
}

class Dog extends Animal {
	//重写eat()
	public void eat() {
		System.out.println("狗吃狗粮");
	}
}

在编译期,编译器会检测到cat引用时Animal类型,编译器会到Animal.class中寻找catchMouse(),而Animal.class中并没有catchMouse(),所以编译器报错。

异常:

向上转型可能会出现异常:

在多态中,父类型引用指向子类型对象,在运行阶段会检测引用实际指向的对象,如果向上转型转换类型出错,并不会在编译期出现问题,但在运行期会抛出类型转换异常(java.lang.ClassCastException)

public class Test {
	public static void main(String[] args){
		//父类型引用指向子类型对象
		Animal dog = new Dog();
		Cat d = (Cat)dog;

	}


class Animal {
	public void eat(){
		System.out.println("动物都能吃东西");
	}
}

class Cat extends Animal {
	//重写eat()
	public void eat() {
		System.out.println("猫吃猫粮");
	}
	public void catchMouse() {
		System.out.print("猫抓老鼠");
	}
}

class Dog extends Animal {
	//重写eat()
	public void eat() {
		System.out.println("狗吃狗粮");
	}
}

在编译期,Animal类型的dog引用经过转型后变成Cat类型并将对象的地址给Cat类型的d引用,编译器检测到d是Cat类型所以编译能通过,但是在程序运行期间,检测到d引用指向的对象实际是Dog类型,所以会抛出类型转换异常(java.lang.ClassCastException)

那么应该如何避免ClassCastException:

        使用instanceof运算符判断引用指向对象的类型后再向下转型

instanceof运算符特点:

  1. instanceof用于检测引用指向的对象数据类型
  2. instanceof运算结果是true/false
  3. instanceof语法格式:引用 instanceof 数据类型

示例:

public class Test {
	public static void main(String[] args){
		Animal animal = new Cat();
		if(animal instanceof Dog) {
			Dog dog = (Dog)animal;
			dog.eat();
		} 
		if (animal instanceof Cat) {
			Cat cat = (Cat)animal;
			cat.eat();
		}
	}
}

class Animal {
	public void eat() {
		System.out.print("动物能进食");
	}
}
class Dog extends Animal{
	public void eat() {
		System.out.print("狗吃狗粮");
	}
}
class Cat extends Animal {
	System.out.print("狗吃狗粮");
}

结果输出:狗吃狗粮

那么就会有人说了,多态这个共为什么要这么麻烦呢,有什么作用吗?

答案当然是有啦:

                                多态的目的就是降低程序耦合提高程序的扩展能力。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值