Java中不同的名称重用技术
覆盖一个实例方法会覆盖所有在超类中具有相同签名的可访问实例方法,从而实现动态调度;换句话说,VM 根据实例的运行时类型选择要调用的覆盖。覆盖是面向对象编程的基础,也是唯一不被普遍鼓励的名称重用形式:
Java
// Base Class
class Base {
public void f()
{ }
}
// Derived Class
class Derived extends Base {
// overrides Base.f()
public void f()
{ }
}
Java
// Base class
class Base {
public static void f()
{ }
}
// Derived class
class Derived extends Base {
// hides Base.f()
public static void f()
{ }
}
Java
// Base class
class GeeksForGeeks {
// int overloading
public void f(int i)
{ }
// String overloading
public void f(String s)
{ }
}
Java
// Base class
class GeeksForGeeks {
static String sentence = "I don’t know.";
public static void main(String[] args) {
// shadows static field
String sentence = "I know!";
// prints local variable
System.out.println(sentence);
}
}
Java
class Shirt {
private final int size;
// Parameter shadows Shirt.size
public Shirt(int size) {
this.size = size;
}
}
Java
public class Obscure {
// Obscures type java.lang.System
static String System;
public static void main(String[] args) {
// Next line won’t compile:
// System refers to static field
System.out.println("hello, obscure world!");
}
}
隐藏字段、静态方法或成员类型分别隐藏所有可访问的字段、静态方法或成员类型,它们在超类型中具有相同的名称(或者,对于方法来说,是签名)。隐藏成员可以防止它被继承:
Java
// Base class
class Base {
public static void f()
{ }
}
// Derived class
class Derived extends Base {
// hides Base.f()
public static void f()
{ }
}
重载类中的方法如果具有相同的名称和不同的签名,则它们会相互重载。在编译时选择调用指定的重载方法:
Java
// Base class
class GeeksForGeeks {
// int overloading
public void f(int i)
{ }
// String overloading
public void f(String s)
{ }
}
遮蔽变量、方法或类型分别遮蔽在文本封闭范围内具有相同名称的所有变量、方法或类型。如果实体被遮蔽,则不能通过其简单名称来引用它;根据实体,您根本无法引用它:
Java
// Base class
class GeeksForGeeks {
static String sentence = "I don’t know.";
public static void main(String[] args) {
// shadows static field
String sentence = "I know!";
// prints local variable
System.out.println(sentence);
}
}
尽管通常不鼓励使用阴影,但一种常见的习惯用法确实涉及阴影。构造函数经常重用其类中的字段名称作为参数名称来传递命名字段的值。这个习惯用法并非没有风险,但大多数Java程序员都认为文体上的好处大于风险:
Java
class Shirt {
private final int size;
// Parameter shadows Shirt.size
public Shirt(int size) {
this.size = size;
}
}
遮蔽如果两个变量都在范围内,则变量会遮蔽具有相同名称的类型:如果在允许变量和类型的地方使用名称,则它指的是该变量。类似地,一个变量或一个类型可以掩盖一个包。模糊是唯一一种名称重用,其中两个名称位于不同的名称空间中:变量、包、方法或类型。如果一个类型或一个包是模糊的,你不能通过它的简单名称来引用它,除非在语法只允许来自其命名空间的名称的上下文中。遵守命名约定在很大程度上消除了模糊
Java
public class Obscure {
// Obscures type java.lang.System
static String System;
public static void main(String[] args) {
// Next line won’t compile:
// System refers to static field
System.out.println("hello, obscure world!");
}
}