重新开始学Java——多态与instanceOf

多态是面向对象的重要特征,同时也是对象开发软件的一个特殊特性,指的是一个程序 总同名的不同方法共存的情况。

多态分为运行时多态与编译时多态。编译时多态用重载实现,即在.java 中的多个方法 在编译阶段即表现出多种形态(重载:同名不同参)。这种多态是通过参数的多样化来 实现的。

运行时多态:在运行阶段才表现出多种形态。基础:父类引用指向子类对象。
在 Human 中,定义了一个 name 属性:protected String name;定义了一个 eat 方法:public void eat(String food);

在 Sinaean 中,重写了继承自父类 Human 的 eat 方法;

在 Thai 中,重写了继承自父类 Human 的 eat 方法;

在 Englishman 中,重写了继承自父类 Human 的 eat 方法;

在运行阶段,Human 类型的引用变量引用那个子类类型的对象,就表芯那个对象的特征(就调用谁的 eat 方法)。

源码:

public class Human {
	protected String name;
	public void eat(String food){
		System.out.println(this.name+"吃"+food);
	}
	}
	public class Sinaean extends Human{
		// 重写 eat
		public void eat(String food){
		System.out.println(this.name +"是中国人");
		System.out.println("所以他一般用筷子吃 "+ food);
	}
}
public class Thai extends Human{
	// 重写 eat
	public void eat(String food){
		System.out.println(this.name +"是泰国人");
		System.out.println("所以他一般用手抓着吃 "+ food);
	}
}
public class Englishman extends Human {
	// 重写 eat
	public void eat(String food) {
		System.out.println(this.name + "是英国人");
		System.out.println("所以他一般用刀叉吃 " + food);
	}
}
运行代码:
public class Main {
	public static void main(String[] args) {
		// Human 类型的引用变量h 引用了堆区中的Human类型的一个对象
		Human h = new Human();
		h.name = "瑞文";
		h.eat("肉夹馍");
		// Human 类型的引用变量h 引用了堆区中的Sinaean类型的一个对象
		// 父类Human 类型的引用变量引用了 子类 Sinaean类型的一个对象
		h = new Sinaean();
		h.name = "诺克萨斯";
		h.eat("肉夹馍");// 调用 Sinaean 重写的 eat 方法
	}
}
注:在运行方法中,要把前边的三个都写上。

总结重点:

基础:子类继承父类,并重写继承自父类的方法,父类类型的引用 引用了子类类型的对象(所以表现不同的特征)。

运行时类型与编译时类型:
	在运行时多态中声明的那个父类类型的变量(h)的类型 Human 是 h 变量的【编译	时类型】;// Human h; 编译阶段就能明确确定 h 是 Human 的类型。
	在运行阶段,具体引用那个子类类型的对象,就表现那个类型的特征,这个类型叫【运	行时类型】;
	//h = new Sinaean();在运行阶段 h 变量引用了 Sinaean,所以当前它	的运行时类型是 Sinaean 类。
	
	Java 语言中,所有的类都继承了 java.lang.Object;因此所有的类都继承了 Object
	的方法。Object 类中定义了一个方法:getClass(),所以任何对象都可以通过	getClass()来获得其运行时类型。

instanceOf

用于类型检查的运算符:instanceof 的作用类似于判定 " xxx 是 xxx 吗 ",insatanceOf 仅仅用与判断引用类型的变量是否是某个类型。

instanceof 用于判断某个引用类型的变量是否是某个类型:instanceof 操作符的左边是需要判断的引用类型的变量;instanceof 操作符的右边是某个类型(可以是类、接口等);instanceof 返回 boolean 类型的结果:仅当 前面的引用类型变量 的类型的确是后面的类型 时返回 true 。

/**
* 1、instanceof 仅用来判断引用类型的变量是否是某个类型
* 2、通常,用 instanceof 来判断 某个 引用 是否是某个类型
* 判断类型,可能是为了确定变量的类型,然后完成类型转换
* if( h instanceof Sinaean){// 验明正身
* 	Sinaean s = (Sinaean)h; // 如果是 ,就转换
* 	s.surname = "金毛狮王"; // 转换是为了访问只有Sinaean 所定义的属性 和方法
* }
*/
public class TestInstanceOf {
	public static void main(String[] args) {
		int[] array = {1,4,5,6,8,9};
		// 判断array 变量是否是 int[] 类型
		System.out.println(array instanceof int[]);
		//h变量的【编译时类型】是 Human
		// h变量的【运行时类型】 是Sinaean
		Human h = new Sinaean();
		h.name = "谢逊";
		 //h.surname = "金毛狮王"; // h 是Human 类型,而 Human 中没有
		surname这个属性
		System.out.println(h instanceof Human);
		System.out.println(h instanceof Sinaean); // h所引用的变量是否是
		Sinaean 类型
		// 引用类型变量的强制类型转换
		Sinaean s = (Sinaean)h;
		s.surname = "金毛狮王"; // s的编译时类是是Sinaean,因此可以访问
		surname
	}
}

引用类型的强制类型转换:

/**
* 引用类型的强制转换,本质:
* 将栈中存放的对象的地址( h 中存放的地址) 赋值给另外一个变量( s ) 并转换成![](https://oscimg.oschina.net/oscnet/2f5997c075d9d8e651569c474ac8899b5fb.jpg)目标类型(Sinaean)
* Sinaean s = (Sinaean)h;
*/
public class TestConvert {
	public static void main(String[] args) {
		Human h = new Sinaean();
		if( h instanceof Sinaean){
			Sinaean s = (Sinaean)h;
			s.surname = "金毛狮王";
			 s.name = "谢逊";
		}
	}
}

示意图如下 :

转载于:https://my.oschina.net/lujiapeng/blog/2252646

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值