Java 同名成员间关系

同名处理

覆写(Override)


子类成员方法覆写父类方法,多态性的核心
动态绑定,运行时决定调用哪个方法

要求:

  • 父类方法在子类可见并且非final
  • 方法名和参数完全一致
  • 子类返回值和异常可以是父类返回值和异常相容的类型
  • 子类修饰符不能缩小范围

覆写失败会导致子类新增了方法但是没有多态,为了避免可以加@Override让编译器进行检查
父类方法加final或者声明子类不可见,比如private可以禁止子类覆写

隐藏(Hide)


子类成员变量或者静态的方法和变量隐藏父类成员
隐藏后视为父子成员间独立存在,效果上子类没继承,子类静态访问到子类成员

父类静态方法加final可以禁止子类隐藏
父类成员无论是否静态都无法禁止隐藏

Sample
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Parent {
public static final int field = 1;

public static final void method() {
System.out.println("Parent");
}
}

class Child extends Parent {
public static int field = 2; //No error

public static void method() { //Error
System.out.println("Child");
}
}

隐藏通常应该避免

重载(Overload)


一个方法重载另一个方法

要求:

  • 方法名字相同
  • 方法参数不同

重载参数匹配流程

  1. 精确匹配
  2. 基本类型扩大
  3. 装拆箱
  4. 对象类型扩大
  5. 可变参数

重载使用时应保证方法间参数明显不相容,否则应该使用不同的方法名明确区分,避免混淆

遮蔽(Shadow)


闭合范围内变量遮蔽范围外同名变量

要求:

  • 同名
  • 同类型

构造时参数名和成员变量名

Sample
1
2
3
4
5
6
7
class Sample {
private int value;

public Sample(int value) {
this.value = value;
}
}

遮掩(Obscure)


同一闭合范围内,名字冲突

比如不同来源的库

Sample
1
2
System s = new System();
System.out.print(s); //error

变量甚至可以遮掩类型,遵循命名规则很重要

Sample
1
2
String System;
System.out.println(); //error