【Java】 5.7 多态

目录

多态(ploymorphism)

变量引用的强制类型转换

instanceof 运算符


多态(ploymorphism)

【定义】Java引用变量有两种类型:一种是编译时类型,另一种是运行时类型。如果编译时类型和运行时类型不一致时,就能出现所谓的多态。即同一个类型的变量,在执行同一个方法时,表现出多种行为特征。

【多态的类型】Java的引用变量,有两个类型

  1. 编译时类型:有声明他的类型决定
  2. 运行时类型:由该引用实际指向的对象来决定

由于有如下关系:父类到子类是从一般到特殊的关系 —— 如,Animal an = new Wolf();

上面创建新对象的过程可以理解为:an是一种animal,哦~ 原来an是狼(前父后子的格式)

【得到第一个结论】子类的实例完全可以当成父类对象使用父类的引用变量完全可以指向子类的实例


class BaseClass {
	public int a = 5;

	public void base() {
		System.out.println("父类的普通方法");
	}

	public void test() {
		System.out.println("父类的被覆盖方法");
	}
}

public class SubClass extends BaseClass {
	// 重新定义一个a的实例变量隐藏父类的a实例变量
	public String a = "这是子类的字符串";

	public void test() {
		System.out.println("这是子类覆盖父类的方法");
	}

	public void sub() {
		System.out.println("这是子类的普通方法");
	}

	public static void main(String[] args) {
		// 下面编译时类型和运行时类型完全一样,因此不存在多态
		BaseClass bc = new BaseClass();
		// 下面代码的输出结果为5
		System.out.println(bc.a);
		// 下面两次调用BaseClass类中的两个方法
		bc.base();
		bc.test();
		// 下面编译时类型和运行时类型完全一样,因此不存在多态
		SubClass sc = new SubClass();
		// 下面代码的输出结果为"这是子类的字符串"
		System.out.println(sc.a);
		sc.base();
		sc.test();
		//下面代码编译时和运行时类型不一样,会出现多态。
		//编译时ploy的类型为BaseClass,运行时的类型为SubClass
		BaseClass ploy = new SubClass();
		ploy.base();
		ploy.test();
		// ploy的编译时类型是BaseClass
		// 因为BaseClass类中没有sub()方法,所以下面代码编译时会出现错误
		// ploy.sub;
	}
}

 运行结果:

【分析代码】

  1. 分析最后多态是的代码,ploy在SubClass类中没有base()方法,所以只能向上找它的直接父类,寻找base()方法;而SubClass类中有test()方法,且运行时的类型是SubClass类型(当然编译时是BaseClass类型且存在BaseClass类,所以编译能通过),所以会调用SubClass中的方法,即覆盖了父类方法的子类中的方法。
  2. ploy的编译时类型是BaseClass,因为BaseClass类中没有sub()方法,所以这条代码编译时会出现错误ploy.sub。

【多态的意义】多态增加了Java语言的灵活性,也是和设计模式紧密相连的

当我们调用引用变量时,他总是呈现它的运行时类型的特征

编译阶段,编译器并不知道引用变量实际所引用的对象类型,编译器只知道它编译时类型

========================================================================================

变量引用的强制类型转换

在Java程序中,引用变量只能调用它编译时类型的方法,而不能调用它运行时的方法,即使它实际所引用的变量确实包含该方法,这也也是不行的,一定要编译时,也就是引用类型一定要有该方法。

强制类型转换的运算符是(类型):

  1. 基本类型之间(除了Boolean之外),都可以进行转换
  2. 引用类型之间,只能在具有继承关系的两个类型之间转换
  3. 在强制类型转换中,使用instanceof运算符可以让强制类型转换更安全

【最有名的异常】

  1. NullPointerException(空指针异常)
  2. ArrayIndexOutofBoundsException(数组索引边界溢出异常)
  3. ClassCastException(类抛出异常,即是类型转换错误)

========================================================================================

instanceof 运算符

【定义】instanceof运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类(也可以是一个接口,可以把接口看作是一种特殊的类),它用于判断前面对象是否是后面对象的类,或者子类、实现类中的实例。如果是,返回true;否则,返回false。

注意前后类型要么和后面类型相同,要么和后面类型存在父子继承关系


public class InstanceofTest {
	public static void main(String[] args) {
		//Object类是所有类的父类,obj的实际类型是String
		Object obj = "这是instanceof 运算符测试现场";
		System.out.println(obj instanceof Object);
		System.out.println(obj instanceof String);
		System.out.println(obj instanceof Math);
		//Comparable接口实例
		System.out.println(obj instanceof Comparable);
	}
}

 运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_之桐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值