java学习笔记——多态和重写中有关可变形参的知识点

package com.atguigu.exer;

//考查多态的笔试题目:
public class InterviewTest1 {

	public static void main(String[] args) {
		Base1 base = new Sub1();
		base.add(1, 2, 3);

		Sub1 s = (Sub1)base;
		s.add(1,2,3);
	}
}

class Base1 {
	public void add(int a, int... arr) {
		System.out.println("base1");
	}
}

class Sub1 extends Base1 {

	public void add(int a, int[] arr) {
		System.out.println("sub_1");
	}

	public void add(int a, int b, int c) {
		System.out.println("sub_2");
	}

}

关于数组和可变形参是否形成了重写

这里首先Sub1中有两个add函数,其实只有第一个add函数完成了对父类的add函数的重写,为什么重写了呢,因为可变形参和数组其实是同样的,在前面的重载中,就明确了int …arr 和int[] arr这两个形参分别出现在同名函数中是不能同时存在在一个类内的,而是会被编译器当作为一摸一样的函数,那么既然是一模一样的函数,说明这里Sub1对父类的Base1中的add合理的形成了重写,而这一段代码

		Base1 base = new Sub1();
		base.add(1, 2, 3);

中的多态中调用的子类的重写函数是如何执行的‘,就是首先调用的是base父类中的add函数,但是这个函数在子类中进行了重写,转而执行重写的函数,而重写的函数是子类中的第一个add而不是第二个add,第二个add其实构成的是对第一个add的重载,并且也不构成对父类add的重写,所以执行结果是sub_1

关于当向下转型为子类之后调用方法的选择。

		Sub1 s = (Sub1)base;
		s.add(1,2,3);

这里进行强转后,编译器就可以看到子类中的方法了,那么父类中有一个add方法,子类中也有一个add方法,这个时候其实调用的就是固定的参数的方法,而不是可变参数的方法,就是说可以看成这两个方法放在同一类中,然后一个是可变形参,一个是多个固定形参,那么调用的话肯定优先选择固定形参。就是这么简单。
当然,这是某教学课程中的说法,我经过实验后发现好像并不是如此,因此给出自己的推理
首先,在向下转型后,调用add方法,首先肯定是先查看子类中有没有此方法,若有满足的方法,即执行,那么这里子类总有满足的方法第二个add,第一个add其实是不满足的,连编译都不能过我们假设,子类sub中只有第一个add方法,即


package com.atguigu.exer;

//考查多态的笔试题目:
public class InterviewTest1 {

	public static void main(String[] args) {
		Base1 base = new Sub1();

		Sub1 s = (Sub1)base;
		s.add(1,2,3);
	}
}

class Base1 {
	public void add(int a, int... arr) {
		System.out.println("base1");
	}
}
class Sub1 extends Base1 {

	public void add(int a, int[] arr) {
		System.out.println("sub_1");
	}
}

这里会直接编译报错,原因就是子类中已经对父类的方法进行了重写,那么其实父类中被重写的这个方法在编译器眼里已经默认被替换了,那么当你执行add的时候,给了三个实参1,2,3但是编译器找不到对应的可执行方法。尽管这个方法在父类中其实是有的,但由于已经被重写了,所以编译器看不到。而编译器能看到的只有子类中的add方法,但是子类中的add方法的形参是一个int类型,一个int[] 类型所以,自然而然会报编译错误。

至于第一个图片中的一大串代码,为什么父类的函数实际上被重写了,执行的归根到底其实也是子类中的第一个add函数即拥有形参int[] 的方法。因为前面也说了,其实在java中,int… a和int[] b在运行时是没有任何区别的!只是在编译的时候有区别,运行时在内存中其实都是连续的存储空间,所以在赋值给形参的时候,本质上还是赋值给连续的内存空间,所以说其实时没有区别的,都是以a的起始地址或b的起始地址为起点进行赋值,计算机语言上是不会有差别的。这也是追其根本为什么不能共存在同一类中的原因。这也是为什么明明在编译时,将多个参数赋值给int[] 不可以,但是在运行时,被重写的方法中有int[] 却可以赋值多个形参的原因。可以说是带有欺骗性。第一个图片中的代码先欺骗编译器,让编译器通过,最后在运行时用到了多态,并且使用的是重写后的方法。为什么构成了重写,前面也说到了,其实本质上都是连续的存储空间,这也是为什么不能共存的原因,因为本质上是一样的。所以同样也构成了重写。总结完毕。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值