惨淡人生,平淡生活

The Feature Is Stupid

关于extends 和 constructor的默认实现与覆盖策略

今天在TSS上又看到有人讨论java多继承的问题,是想起这个话题的原因。^_^


java中任何类都默认继承 Java.lang.Object,除非被另一个继承覆盖(override),hoho 俺一直这么称呼override的,感觉更加贴切一些。
请看以下代码:

package org.myth.test;

public class SuperSon{
    
    SuperSon(){
        System.out.println(
"this is super son");
    }

}

对于编译器来说,这段代码会被首先补全为:

package org.myth.test;

public class SuperSon extends Object{
    
    SuperSon(){
        System.out.println(
"this is super son");
    }

}

对待任何一个类,编译器会去检查extends关键字,如果没有,编译器会默认添加extens Object

extends Object就是一段默认隐藏的代码,同样在Constructor中,也有一段默认隐藏的代码。

package org.myth.test;

public class SuperSon extends Object{
    
    SuperSon(){
        
super();//这就是一段默认隐藏代码
        System.out.println("this is super son");
    }

    //
整个构造方法也是一段默认隐藏代码

}

如同编译类时编译器回去检查extends关键字一样,编译器会首先检查是否存在constructor,如果没有,默认增加ClassName()构造方法。
在构造方法内部,编译器会检查第一行代码是否为super构造方法,如果不是,默认添加super()

这个就是为什么 new一个对象的时候,首先调用的是父类的构造方法。

一个错误代码示例:
package org.myth.test;

public class SuperMan {
    
    SuperMan(String s){
        System.out.println(
"this is super man");
    }

}



package org.myth.test;

public class SuperSon extends SuperMan{
    
    SuperSon(){
        System.out.println(
"this is super son");
    }

}


嘿嘿 第一篇文章

posted on 2008-05-28 10:44 季失羽 阅读(1279) 评论(10)  编辑  收藏

评论

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-28 11:11 Happy漫步者

不错 关注下^_^  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-28 11:13 Happy漫步者

第一篇文章 我收藏拉   回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-28 11:40 隔叶黄莺

博主可由此延展一下,在父类没有默认构造函数时,对子类构造函数有什么要求。  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-28 13:41 季失羽

@隔叶黄莺
这个问题,你看我最后一个错误代码示例 就知道了 ^_^  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略[未登录] 2008-05-28 21:26 Matthew Chen

黄莺真的很认真啊。
对于lz说的被另一个继承覆盖(override)的说法,怎么看得别扭,就是继承自非object的类就好了,没必要太复杂。  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-28 21:41 隔叶黄莺

最后一段错误代码,你还没有说明白错误的原因,也没给出解决的办法。

只要知道子类和父类之间是一种 Has-A 的关系就好理解了,在父类没有默认构造方法时,在创建子类实例时,它就无从获悉该如何实例化出它的部分--父类实例,super() 已经不见效了,因为父类不存在 super() 了,所以就要求在子类的构造方法中显式的调用父类的某个构造方法。  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-29 10:00 季失羽

@隔叶黄莺
在构造方法内部,编译器会检查第一行代码是否为super构造方法,如果不是,默认添加super()
按照上面这句话的理解 就是
package org.myth.test;

public class SuperSon extends SuperMan{

SuperSon(){
System.out.println("this is super son");
}

}

其实等同于
package org.myth.test;

public class SuperSon extends SuperMan{

SuperSon(){
super();
System.out.println("this is super son");
}

}

显然,父类中是不存在无参数构造方法的,所以编译器回报错,不存在super()构造方法。


另外,对于您说的has-a的关系,特定界定之下可以这么讲,但是更准确而言,子类是父类 应该是is a 的关系。  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-29 10:02 季失羽

@Matthew Chen
是,继承另一个类也许更加清楚一些,但是 既然文章的主要意思是说默认实现与覆盖关系的 hoho 这么说是一种惯性XD  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略 2008-05-29 12:28 隔叶黄莺

要继承一个无默认构造方法的父类,在子类中应如何处理还可以说明白一些

其实只要记住这一点,在构造子类实例前必须构造一个父类实例作为子类实例的部分,所以从这一层面讲存在一种 has-a 关系。

在C++或某些具体面对象的C组件中很清楚体现这一点,父类实例要放在子类实例的首地址,所以才能保证向上安全转型

如果没有默认增加ClassName()构造方法。 这句话不是很好理解,没有增加ClassName()构造方法是人的行为,不存在是否默认

关于对象模型,C++有些书籍讲述的比较透沏。  回复  更多评论   

# re: 关于extends 和 constructor的默认实现与覆盖策略[未登录] 2008-05-29 19:08 季失羽

@隔叶黄莺
在构造子类实例前必须构造一个父类实例作为子类实例的部分
这句话太正确了。

如果没有默认增加ClassName()构造方法。
晕,刚刚发现,句读错了,中间有个逗号。汗一个 XD
如果没有,默认增加ClassName()构造方法。

其实 俺这篇文字 完全可以三句话说完的

第一句,任何一个类都有Constructor
第二句,任何一个类的Constructor第一行代码就是调用父类的构造函数
第三局,就是 以上两句说的东西,你可以代码中不写,因为有默认实现,并且默认实现与编码出来的实现不能并存,会被覆盖。

XD 骗字数而已 XD  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: