我们知道,final,private,static和构造方法都是无法被继承的,但是细究起来还是稍有区别,看代码:
测试类:
Father:
同包下子类:
来一个一个分析,首先:
final方法:
很干脆,注释显示:final不能被覆写。
private方法:
并没有报错,但是回想一下Java修饰符那节:private下,父类的testPrivate()方法对于子类Son是不可见的,故可以推测:系统认为testPrivate()是子类自己的方法,并不是父类的方法,改一下代码,实验一下:
Father:
Son:
结果:
果然,另外,加上@Override试一下:
报错了:
报错很生硬:Method does not override method from its superclass
static方法:
同样没有报错,同样试一下:
测试类:
Father:
Son:
结果:
可以看到一个有趣的现象,父类引用指向子类对象时,testStatic()执行的是父类的静态方法,子类引用指向子类对象时,testStatic()执行的是子类的静态方法,这印证了一句话:静态方法只能被隐藏,不能被覆盖。引用访问的具体是谁的方法要视引用本身的类型而定。
对于静态变量同样如此,这里就不实验了。
对于上面private要不要这样实验一下呢,即:
看看是不是private也只是被隐藏了?
不需要,因为Father的testPrivate()是private属性的,在Son中根本就不可见,上面的代码直接报错(已实验过)。
构造方法:
直接报错:
显示没有返回值,则加上返回值:
结果:
即,系统认为这个Son的一个普通方法,只是方法名和Father的构造方法(类名)一样而已,此时好事的人又要想试一下这种:
但是,Java基础知识告诉我们,父类引用指向子类对象后,只能访问父类已有的变量和方法,访问子类新增的变量或方法(不是覆写)时,会直接报错的,验证一下:
另一方面,在Son的Father方法前加上@Override注解也能验证Father不能被覆写:
或者在已经成为普通方法的public void Father()前面加上@Override注解也能验证这个Father()方法不是继承而来的:
故,综上:
- final,覆写直接报错
- private,写完是子类的普通方法
- static,写完后,没有被覆盖,只是被隐藏
- 构造方法,覆写直接报错,加上返回值后成为普通方法