java中的重写---在笔试中重新认识其特性
在笔试或面试中我们通常会被问到重写和重载的区别?
我们答案通常是:
重写是发生在子类继承父类的过程中,子类的方法覆盖了父类的方法,白话说就是子类再次实现父类已有的方法,方法名、返回值类型、参数列表相同。
重载是发生在同一个类中,返回值类型不做要求,方法名必须相同,参数列表必须相同。
一般会答到这里。但是如果出现在程序题中呢?
有如下class:
class A {
protected int method1(int a, int b) { return 0; }
}
下面哪些方法可以存在于继承class A的类中:
A. public int method1(int a, int b) { return 0; }
B. private int method1(int a, int b) { return 0; }
C. private int method1(int a, long b) { return 0; }
D. public short method1(int a, int b) { return 0; }
E. static protected int method1(int a, int b) { return 0; }
例如上面的这道题,对于只会背这些理论的同学是不是就懵了呢?反正我是。
那么我当时给出的答案是A,但是心里感觉不是很确定。笔试后就做了一下的实验,测试代码:
/**
*
* @author
*对于方法的重写在知道返回值类、方法名、参数列表相同是基础的,
*但是对于一些的情况下是这样的:
* 1.作用域符是可以改变的,但是一定要比父类的作用域符要宽,作用域符的作用范围:public>default>protected>private
* 2.返回值类型也是可以改变的,但一定不能是父类中该方法的返回值类型的父类,可以与其返回值类型相同,可以是父类中该方法返回值类的子类。
* 3.参数列表一定不能改变,个数/参数类型这两者是不能改变的。
*/
public class TestOverRide implements OverRide{
protected OverRide test(float t) {
System.out.println("父类的方法");
TestOverRide2 testOverRide = new TestOverRide2();
return testOverRide;
}
}
class TestOverRide2 extends TestOverRide {
@Override
public TestOverRide test(float t) {
System.out.println("子类的方法");
return null;
}
}
interface OverRide{
public abstract OverRide test(float t);
}
我也作出了其他的类型,在上一题中主要考察就是与父类之间的返回值类型、作用域符关系。
简单说明一下测试代码的结构,OverRide是一个接口,TestOverRide是其子类,TestOverRide2是TestOverRide的子类,TestOverRide2重写了TestOverRide的test()方法,我们可以看到TestOverRide2中的test()方法返回值类型改变了,但是是TestOverRide的子类。
那么我也做出了其他的尝试。下面是截图
在上题中的答案也就很清晰了,
<span style="font-size:18px;"> protected int method1(int a, int b) { return 0; } </span>
那么其子类中的访问作用符必须是protected ,参数列表必须相同,答案只有A符合。对于E这个选项就不可对了,因为我们静态方法是一个类的属性,子类一下把父类的属于对象的属性变成自己类的属性,自然就不对了,读者测试一下就可以验证了。
重载似乎就没有那么多的讲究了:
我们就记住重载条件是:必须在同一个类中,必须是方法名相同,必须是参数列表不同,其他的都不是必须的,就是说作用域符、返回值类型的不同不能作为方法重载的判断条件这两项可以相同可以不相同。
从这里我们也可以看到,我在使用一个方法时关注点是:
方法的返回值类型,访问权限,方法名,方法的参数列表,方法体就这5部分。