首先,很多同学存在几个误区。
第一个误区:父类中只要是私有的东西子类都是无法继承的。
第二个误区:父类中非Private成员都能被子类继承。
首先我们看看到底什么东西能被继承。
一个类中有三个分类。
构造方法
成员变量
成员方法
----------------------------------------------------------------------
元素 非private private
- 构造方法 不能继承 不能继承
- 成员方法 能继承 不能继承
- 成员变量 能继承 能继承
--------------------------------------------------------------------------
以上这个表格 我要求每一位同学都要会背,你不要质疑我,这个表绝对是对的。你记着就行了
然后我给你讲讲 我的疑惑 然后是怎么解决的。
首先是 构造方法 部分的疑惑。
我刚开始疑惑的是这个部分。我刚开始觉得子类是可以继承父类的原因是如下这代码段
class Role{
public Role() {
System.out.println("父类构建函数");
}
}
class Role2 extends Role{
public Role2(){
System.out.println("子类构建函数");
}
}
public class test {
public static void main(String argu[])
{
Role2 a=new Role2();
}
}
Role是父类 Role2是子类,意思就是我创建一个role2对象。
然后你猜运行的结果是什么样?
我创建一个子类对象 我发现不仅调用了子类的构建函数 还调用父类的构建函数。
然后我就以为
子类是继承了父类的构建函数。
你先不要笑我,我知道这个想法很离谱,但肯定很多人也是我这样想的。
后来想了想,因为你是现有父类才有子类,你的子类需要继承一个父类,所以得先创造一个父类(所以调用了构建函数),然后创造子类,虽然只有一个子类对象,其实这个子类对象的创建过程是包含了创建它的父类的。不知道你懂我意思没有。
所以这里并没有继承,子类是不能继承父类的任何构造函数的,无论前面是private还是非private。
------------------------------------------------
第二个疑惑点是在成员变量这个地方。
我一直以为的是,private变量是不能被继承的,因为你无法访问,但我发现你可以用父类的public方法访问,因为public方法是可以被继承的,如果我们在子类中调用了这个方法,并且可以正常显示,说明我们的假设是正确的。
下面我们来做一下这个实验。
package homwork4;
class Role{
public Role() {
System.out.println("父类构建函数");
}
private int father_data;
public void setFather_data(int m){
this.father_data=m;
}
public void display_Father_data(){
System.out.println(father_data);
}
}
class Role2 extends Role{
public Role2(){
System.out.println("子类构建函数");
}
}
public class test {
public static void main(String argu[])
{
Role2 a=new Role2();
System.out.println("首先不对father——data赋值直接输出:");
a.display_Father_data();
System.out.println("---------------------");
System.out.println("然后对father——data赋值后输出:");
a.setFather_data(250);
a.display_Father_data();
}
}
输出结果
由此可见,权限最为严格private成员变量都能被继承,其他更可以,所以成员变量无论权限如何都能被继承。
然后我的第三个疑惑点,就是在成员方法这里
首先成员方法是如何传递的?
继承中 成员方法是通过虚方法表来进行传递的,比如现在有爷爷类 儿子类 孙子类
那么爷爷的部分能被继承的成员方法,如果要给儿子,首先写入虚方法表,然后继承给儿子
儿子此时内部有两个分区,一个是自己的方法分区,一个是继承的虚方法分区。
如果此时儿子要继承给孙子方法,儿子把自己的方法也写入虚方法表,然后传给孙子。
孙子同样内部两个分区,一个是自己的方法分区,另一个是继承的虚方法分区,其中包括他爸爸和他爷爷的方法。
那什么方法能写入虚方法表呢?
重点来了!!
第一,private方法是不能写入虚方法表,或者说是不能继承的。
第二,非final 非static 非private方法,才能被继承,才能写入虚方法表。
第三,能够使用父类的方法,不代表子类继承了这个方法。(非常重要 好好理解)
我相信前两个都非常好理解,现在我们来看看第三个要怎么理解。第三个我显示尝试了一下,发现子类也可以使用父类的static方法,但是这算是继承吗?
代码如下
package homwork4;
class Role{
public Role() {
System.out.println("父类构建函数");
}
public static void display(){
System.out.println("父类静态方法");
}
}
class Role2 extends Role{
public Role2(){
System.out.println("子类构建函数");
}
}
public class test {
public static void main(String argu[]) {
Role2 a = new Role2();
a.display();
}
}
这样的结果是
我们上述可以发现子类可以调用父类的static方法,但这不算是继承。
并且我们的IDEA也不会建议我们这样写,不会给你自动填充,说明我们这样有一种强行转换的味道。子类是不继承父类的static变量和方法的。因为这是属于类本身的。但是子类是可以访问的。
但是这样写是不会报错的。
详细可以看这篇帖子 写的很好。
Java中子类是否可以继承父类的static变量和方法而呈现多态特性_wounler的博客-CSDN博客_java继承会继承静态变量吗