Java学习笔记之多态(运行时多态)

本文通过标签概念深入解析Java中的多态特性,探讨对象变量、方法调用权限及对象执行方法的本质,辅以实例说明多态下成员变量与方法的访问规则。

封装、继承和多态是OOP的三大特性。其中多态的实现建立在前两者的基础之上,既是重点也是难点。我在初学Java时对这方面就难以理解,这次复习又认真揣摩了一下,在此记录自己的总结心得。

一、对象变量就是标签

在我看来,多态首先是给对象贴上标签。怎么理解呢?我们不妨先举个例子:

class Fruit{
	public Fruit(){
		System.out.println("这是一个水果");
	}
}

class Apple extends Fruit{
	public Apple() {
		super();
	}
	
	public void printName() {
		System.out.println("这是水果中的苹果");
	}
}

class Banana extends Fruit{
	public Banana() {
		super();
	}
	
	public void printName() {
		System.out.println("这是水果中的香蕉");
	}
}

以上,我定义了一个水果类,以及继承它的苹果类和香蕉类。在Java中,首先对象变量是多态的,即父类对象变量既可以引用父类对象,也可以引用子类对象,即:

		Fruit[] f = new Fruit[3];
		f[0] = new Fruit();
		f[1] = new Apple();
		f[2] = new Banana();

可以看出,数组f的每个元素都是Fruit类的对象变量,但它们既可以引用Fruit类对象,也可以引用Apple类和Banana类的对象。这里我把对象变量理解成“标签”,标签就是对类的概括描述。我现在手上拿着水果标签,遇到一个水果类,直接就可以贴上去。遇到苹果呢?苹果当然是水果啊,贴!香蕉也是如此。可见,对象变量就是标签,标签就是对类的一个描述,只不过有准确描述和概括描述之不同罢了。

二、贴什么标签,就做什么事

在上述示例中,我们初步了解了对象变量就是标签。现在我们再来看一个例子:

		Apple a = new Apple();
		Fruit f = a;
		a.printName();
		f.printName(); //ERROR

其中a引用了一个Apple对象,可以调用printName()方法。然而,f虽然引用的也是Apple对象,但其本身只是Fruit标签,由于贴标签时描述的精确度不够,所以就不能确定其是否贴在了苹果上,也许只是普通的水果呢?你说你是个苹果,但你能拿出什么证据呢?贴在你身上的只是一个水果标签啊!所以为了安全起见,我们不能允许它调用这个方法。从中我们可以看出:贴什么标签,就做什么事,越俎代庖就是不行。

三、标签是脸蛋,做事落到实处

为了解决上述代码的问题,我在Fruit类中加入了printName()方法,以使其能够成功编译。然而,运行时我们可以看到,f.printName()调用的是Apple类的方法!这是为什么呢?之前不是说贴什么标签就做什么事吗?

其实我们这里陷入了一个误区。贴什么标签做什么事这个原则当然没错,但标签只是脸蛋,是没有能力做事的啊!所以,只要子类中存在同名方法,就一定要优先调用子类的方法。标签只是脸蛋,而做事却要落到实处,我的标签贴在谁身上,谁就来执行这个方法,就这么简单。

四、不同多态情况的理解辨析

在上面,我们讲了三个要点:1.对象变量是标签;2.标签规定了调用方法的权限;3.是对象而不是标签来调用方法。为了深入理解上述内容,我们来看几个例子:

  1. 多态情况下,子父类存在同名的成员变量时,访问的是父类的成员变量;
  2. 多态情况下,子父类存在同名的非静态成员函数时,访问的是子类的成员函数;
  3. 多态情况下,子父类存在同名的静态成员函数时,访问的是父类的成员函数;
  4. 多态情况下,不能访问子类特有的成员。
    (此处引用部分出自【多态】@author 一大三千@大千世界

如果深入理解了标签的意义,这几点就不难理解了。

第一点,标签其实就是脸蛋,成员变量作为对象的属性,当然也是对象的脸蛋。所以子父类存在同名成员变量时,必然访问父类成员变量。

第二点在前面已经说过,我们主要看一下第三点。为什么此处访问的是父类成员函数呢?不是说标签是脸蛋、做事落到实处吗?可偏偏静态方法是个特例,要知道静态方法其实是类的方法,是不依赖对象而存在的呀!所以静态方法不会被重写,只能被重载、隐藏和继承。此处一旦贴上父类的标签,子类的静态方法自然被隐藏起来,于是无法被调用,这当然是顺理成章的了。

第四点,其实也不用多说了。你的标签就是你的脸蛋、你的属性,父类标签上没贴的东西,子类又怎么能越俎代庖呢?其特有的成员变量和方法都是不能被访问的。

五、结语

本文总结了运行时多态的一些常见情况,并独创“标签”概念对各种情况进行辨析。当然,由于本人才疏学浅,又是第一次写博客,难免有不当之处。如有错误,还望有识之士不吝赐教。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值