关于子类和父类的一些事
程序员文章站
2022-05-27 09:19:34
...
目录
- 子类与父类同名的属性和方法,底层对他们的处理方式
- 两个并不能重写父类方法的例子:
① 参数列表不完全一致(类型是其子类也不算一致)。
② 子类没有访问父类函数的权限。 - 关于静态方法的"重写"
子类与父类同名的属性和方法,内存对他们的处理方式是不同的:属性是覆盖,方法是重写
class Father {
String x = "-父类属性";
public void f() {
System.out.println("-父类方法-");
}
}
class Son extends Father{
String x = "-子类属性-";
public void f() {
System.out.println("-子类方法-");
}
}
public class Test {
public static void main(String[] args) {
Father f1 = new Father();
Father f2 = new Son();
Son s1 = new Son();
System.out.print(f1.x);f1.f(); // -父类属性-父类方法-
System.out.print(f2.x);f2.f(); // -父类属性-子类方法-
System.out.print(s1.x);s1.f(); // -子类属性--子类方法-
}
}
从父类指针指向子类实例
这一例子中可以看出,f2的属性依然是使用父类的,而方法却使用的是重写后的。导致这样的原因就是因为他们内存中的存储是不一样的:
所以说,子类中有和父类同名的属性,其实是把父类的属性隐藏了,并不是覆盖了。而使用同名同参的方法,其实是进行了方法的重写
。
关于方法的重写,举两点需要注意的地方①如果我们在子类中写的函数,并不满足方法重写的要求(方法名相同,参数列表完全一致
),那么就会在子类中声明出一个新的函数,这个函数和父类是没关系的。比如下图中,由于参数列表的不完全一致,实际上方法并没有被重写:
②既然子类想要重写父类的构造方法,那么还有一点也是至少要保证的,就是子类是可以访问到父类的该方法的,如果由于访问权限的问题,那么方法也并不会被重写,比如下图的输入就会是父类方法,因为子类根本就没有重写进去,调用的还是父类的:
如果把上图中父类的private改成public,那么输出的结果将是"-子类方法-":
如果我们在子类写的方法,已经达到了重写的要求(方法名和参数列表一致),且访问权限也没有问题,那么我们就可以进行重写了,至于重写中其它的规范(返回类型,异常,static修饰符,访问权限等),如果不满足重写规范,则将在编译期报错。
最后再讲一下static方法。如果子类重写了父类的static方法,实际上是一种类似于属性的隐藏。也就是说父类的静态方法并不是被重写了,而是被隐藏了:
从上述例子就可以看出,虽然子类指针访问的静态变量是"重写"后的。但是父类指针所访问的,并不是被子类重写过后的静态方法,也就是说静态方法说到底还是属于类的,是不可以被重写,但是能被覆盖的。