Java常见疑难问题-类11


39. 重写、隐藏、重载、遮蔽、遮掩
重写:一个实例方法可以重写在其超类中可访问到的具有相同签名的所有实例方法,从而能
动态分派,换句话说,VM将基于实例的运行期类型来选择要调用的重写方法。重写是面向
对象技术的基础。
public class P{
public void f(){}
}
class S extends P{
public void f(){}//重写
}

重写时要求:
? 如果父类方法抛出的是捕获型,则子类也只能抛出同类的捕获型或其子
类,或不抛出。
? 父类抛出捕获型,子类却抛出运行时,这是可以,因为抛出运行时就相当
于没有抛出任何异常。
? 如果父类抛出的是非捕获型异常,则子类可以抛出任意的非捕获型异常,没有扩大
异常范围这一
? 如果父类抛出的是非捕获异常,子类也可以不用抛出,这与父类为捕获型异常是一
样的。
? 如果父类抛出的是非捕获异常,子类就不能抛出任何捕获型异常,因为这样会扩大
异常的范围。

返回类型的协变:从Java SE5开始子类方法可以返回比它重写的基类方法更具体的类
型,但是这在早先的Java版本是不允许–重写时子类的返回类型一定要与基类相同。
但要注意的是:子类方法返回类型要是父类方法返回类型的子类,而不能反过来。

方法参数类型协变:如果父子类同名方法的参数类型为父子关系,则为参数类型协变,此时
不属于重写,而是方法的重载,以前版本就是这样。

如果父类的方法为private时,子类同名的方法的方法名前可以使用任何修饰符来修饰。我
们可以随意地添加一个新的私有成员(方法、域、类型),或都是修改和删除一个旧的私有
成员,而不需要担心对该类的客户造成任何损害。换而言之,私有成员被包含它们的类完全
封装了。

父与子类相同签名方法不能一静一动的,即父类的方法是静态的,而子类不是,或子类是静
态的,而父类不是,时都不会通过。

父与子相同签名方法都是静态的方法时,方法名前的修饰符与非静态方法重写的规则一样,
但不属于重写,因为静态方法根本就不具有多态性。

最后,属于成员也不具有多态特性,相同名的域属于隐藏,而不管域前面的修饰符为什么:
class P {
public static final String str = “P”;
}
class S extends P {
//能通过。可以是final,这里属于隐藏
public static final String str = “S”;
public static void main(String[] args) {
System.out.println(S.str);//s
}
}

隐藏:一个域、静态方法或成员类型可以分别隐藏在其超类中可访问到的具有相同名字(对
方法而言就是相同的方法签名)的所有域、静态方法或成员类型。隐藏一个成员将阻止其被
继承。
public class P{
public static void f(){}
}
class S extends P{
//隐藏,不会继承P.f()
public static void f(){}
}

重载:在某个类中的方法可以重载另一个方法,只要它们具有相同的名字和不同的签名。由
调用所指定的重载方法是在期选定的。
public class T{
public static void f(int i){}
public static void f(String str){}//重载
}

遮蔽:一个变量、方法或类型可以分别遮蔽在一个闭合的文本范围内的具有相同名字的所有
变量、方法或类型。如果一个实体被遮蔽了,那么你用它的简单名是无法引用到它的;根据
实体的不同,有时你根本就无法引用到它。
public class T {
private static String str = “feild”;
public static void main(String[] args) {
String str = “local”;// 遮蔽
System.out.println(str);// local
// 可以通过适当的方式来指定
System.out.println(T.str);// feild
}
}

public class T {
private final int size;
// 参数属于方法局部范围类变量,遮蔽了同名成员变量
public T(int size) {
//使用适当的引用来指定
this.size = size;
}
}

遮掩:一个变量可以遮掩具有相同名字的一个类型,只要它们都在同一个范围内:如果这个
名字被用于变量与类型都被许可的范围,那么它将引用到变量上。相似地,一个变量或一个
类型可以遮掩一个包。遮掩是唯一一种两个名字位于不同的名字空间的名字重用形式,这些
名字空间包括:变量、包、方法或类型。如果一个类型或一个包被遮掩了,那么你不能通过
其简单名引用到它,除非是在这样一个上下文环境中,即语法只允许在其名字空间中出现一
种名字:
public class T {
static String System;
public static void main(String[] args) {
// !!不能编译,遮掩 java.lang.System
// !! System.out.println(“Hello”);
// 可明确指定
java.lang.System.out.println(“Hello”);
}
}

声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 智乐兔
转载请注明:转自《Java常见疑难问题-类11
本文地址:https://www.zhiletu.com/archives-244.html
关注公众号:智乐兔

赞赏

wechat pay微信赞赏alipay pay支付宝赞赏

上一篇
下一篇

相关文章

在线留言

你必须 登录后 才能留言!

在线客服
在线客服 X

售前: 点击这里给我发消息
售后: 点击这里给我发消息

智乐兔官微