隐藏和覆盖
属性的隐藏
- 子类中声明了与超类中相同的成员变量将被隐藏
- 子类拥有了两个相同的名字的变量,一个继承来自超类,另一个由自己声明
- 当子类执行继承自超类的操作时,处理的是继承自超类的变量,而当子类执行它自己声明的方法时,所操作的就是它自己声明的变量
class A1
{ int x = 2;
public void setx(int i)
{ x = i; }
void printa()
{System.out.println(x);}
}
class B1 extends A1
{ int x=100;
void printb()
{ super.x = super.x +10 ;
System.out.println("super.x=" +
super.x + " x= " + x);
}
}
public class Exam4_4Test
{ public static void main(String[] args)
{ A1 a1 = new A1();
a1.setx(4);
a1.printa();
B1 b1 = new B1();
b1.printb();
b1.printa();
b1.setx(6); // 将继承x值设置为6
b1.printb();
b1.printa();
a1.printa();
}
}
运行结果:
4
super.x= 12 x= 100
12
super.x= 16 x= 100
16
4
访问被隐藏的超类属性
- 调用从超类继承的方法,则操作的是从超类继承的属性
- 本类中声明的方法使用"super.属性"访问从超类继承的属性
class A {
static int x = 2;
public void setx(int i) {x = i;}
void printa() {
System.out.println(x);
}
}
class B extends A {
int x = 100;
void printb() {
super.x = super.x + 10;
System.out.println("super.x= " + super.x + " x= " +x);
}
}
public class Tester {
public static void main(String[] args)
{
A a1 = new A();
a1.setx(4);
a1.printa();
B b1 = new B();
b1.printb();
b1.printa();
b1.setx(6);
b1.printb();
b1.printa();
a1.printa();
}
}
运行结果:
4
super.x= 14 x= 100
14
super.x= 16 x= 100
16
16
方法覆盖
- 如果子类不需要使用从超类继承来的方法的功能,则可以声明自己的同名方法,称为方法覆盖
- 覆盖方法的返回类型,方法名称,参数的个数及类型必须和被覆盖的方法一模一样
- 只需要在方法名前面使用不同的类名或不同类的对象名即可区分覆盖方法和被覆盖方法
- 覆盖方法的访问权限可以比被覆盖的宽松,但不能更为严格
方法覆盖的场合
- 子类中实现与超类相同的功能,但采用不同的算法或公式;
- 在名字相同的方法中要做比超类更多的事情
- 在子类中需要取消从超类继承的方法
方法覆盖的注意事项
- 必须覆盖的方法
- 派生类必须覆盖基类中的抽象的方法,否则派生类自身也成为抽象类
- 不能覆盖的方法
- 基类中声明为fianl的终结方法
- 基类中声明为static的静态方法
- 调用被覆盖的方法
- super.overriddenMethodName();