一.属性的隐藏
父类和子类拥有相同名字的属性或者方法( 方法隐藏只有一种形式,就是父类和子类存在相同的静态方法)时,父类的同名的属性或者方法形式上不见了,实际是还是存在的。
当子类执行继承自父类的操作时,操作的继承自父类的属性或方法;当子类处理自己声明的方法时,处理的就是自己声明的属性。若想直接访问父类的属性,可以通过super.属性来访问。
class Parent{
Number aNumber;
}
class Child extends Parent{
Float aNumber;
}
例
class A1{
int x = 2;
public void setx(int i){
x = i;
}
public 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);
b1.printb();
b1.printa();
a1.printa();
}
}
//运行结果
4
super.x = 12 x = 100
12
super.x = 16 x = 100
16
4
当发生隐藏的时候,声明类型是什么类,就调用对应类的属性或者方法,而不会发生动态绑定。
二.属性的覆盖
如果子类不需要使用从超类继承来的方法的功能,则可以声明自己的同名方法,称之为方法覆盖。覆盖方法的返回类型、方法名称、参数个数以及类型必须和被覆盖的方法一模一样。覆盖方法的访问权限可以比被覆盖的宽松,但是不能更严格。
原则:
1.必须覆盖的方法:子类中必须覆盖超类中的抽象方法,否则子类自身也会称为抽象类。
2.不能覆盖的方法:超类中声明为final、static的方法。
3.调用被覆盖的方法:super.overridenMethodName();
public class Test {
public static void main(String[] args) {
Circle circle = new Circle();//本类引用指向本类对象
Shape shape = new Circle();//父类引用指向子类对象(会有隐藏和覆盖)
System.out.println(circle.name);
circle.printType();
circle.printName();
//以上都是调用Circle类的方法和引用
System.out.println(shape.name);//调用父类被隐藏的name属性
shape.printType();//调用子类printType的方法
shape.printName();//调用父类隐藏的printName方法
}
}
class Shape {
public String name = "shape";
public Shape(){
System.out.println("shape constructor");
}
public void printType() {
System.out.println("this is shape");
}
public static void printName() {
System.out.println("shape");
}
}
class Circle extends Shape {
public String name = "circle"; //父类属性被隐藏
public Circle() {
System.out.println("circle constructor");
}
//对父类实例方法的覆盖
public void printType() {
System.out.println("this is circle");
}
//对父类静态方法的隐藏
public static void printName() {
System.out.println("circle");
}
}
//运行结果
shape constructor
circle constructor
circle
this is circle
circle
shape
this is circle
shape