黑马程序员技术交流社区
标题:
关于静态代码块和构造代码块继承的问题
[打印本页]
作者:
胡军
时间:
2013-3-29 11:18
标题:
关于静态代码块和构造代码块继承的问题
本帖最后由 胡军 于 2013-3-31 14:01 编辑
class Father
{
static
{
System.out.println("父类静态代码块");
}
{
System.out.println("父类构造代码块");
}
}
class Son extends Father
{
static
{
System.out.println("子类静态代码块");
}
{
System.out.println("子类构造代码块");
}
Son()
{
System.out.println("子类无参数构造函数");
}
}
class StaticExtendsDemo
{
public static void main(String[] args)
{
Son s = new Son();
}
}
复制代码
运行结果:
父类静态代码块
子类静态代码块
父类构造代码块
子类构造代码块
子类无参数构造函数
为什么结果是这样,为什么父类的静态代码块和构造代码块没有被覆盖呢?
是它们不能被继承还是其他原因导致的。
作者:
张玉保
时间:
2013-3-29 11:38
静态代码块:要明白静态代码块是给类初始化,随着类的加载而执行,并且优于主函数执行且只运行一次;所以静 态代码块只要定义了就会随着类的加载而运行。
构造代码块:是给本类所有对象初始化,并且优先于构造函数执行。
关于覆盖的问题我认为java中在子类继承父类或者子类实现接口的时候,只有父类和接口中的方法才能覆盖,即覆盖知识针对方法而言的。(自己的理解)
作者:
刘焕新
时间:
2013-3-29 12:23
本帖最后由 刘焕新 于 2013-3-29 12:51 编辑
当父类与子类都有
静态代码块、初始化块
和
构造函数
的时候,执行顺序如下:
父类静态代码块 > 子类静态代码块 >
父类初始化块 > 子类初始化块 >
父类构造函数 > 子类构造函数
(先有父亲,后有孩子)
父类的非静态方法可以被子类重写(也就是覆盖);而静态方法和静态代码块只能被继承,重写无效,即不构成多态。
子类执行创建对象时,会先上溯寻找父类及其祖宗类,如果是多级继承,则最顶级的父类会先执行对象的创建,再依次往下创建子孙类对象;
例如上面的代码,准备执行"Son s = new Son()"时,虚拟机会先去寻找Son类的父辈类。
其实还可以这样看,所有Object的子类的构造函数内部都会隐式包含一条super()语句,如:
Son()
{
super(); //而super()的意思正是上溯寻找它的父类及其调用无参构造函数。
...
}
复制代码
作者:
王杰123
时间:
2013-3-29 16:17
静态代码块的初始化顺序
class Parent{
static String name = "hello";
{
System.out.println("parent block");
}
static {
System.out.println("parent static block");
}
public Parent(){
System.out.println("parent constructor");
}
}
class Child extends Parent{
static String childName = "hello";
{
System.out.println("child block");
}
static {
System.out.println("child static block");
}
public Child(){
System.out.println("child constructor");
}
}
public class StaticIniBlockOrderTest {
public static void main(String[] args) {
new Child();//语句(*)
}
}
问题:当执行完语句(*)时,打印结果是什么顺序?为什么?
解答:当执行完语句(*)时,打印结果是这样一个顺序 :
parent static block
child static block
parent block
parent constructor
child block
child constructor
分析:当执行new Child()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静态代码块,当子类的静态代码块执行完毕之后,它接着又去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法,这个就是一个对象的初始化顺序。
总结:
对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
作者:
胡军
时间:
2013-3-30 10:21
王杰123 发表于 2013-3-29 16:17
静态代码块的初始化顺序
class Parent{
多谢讲解,顺便问一句如何把主题改为已解决啊
作者:
王杰123
时间:
2013-3-30 12:42
胡军 发表于 2013-3-30 10:21
多谢讲解,顺便问一句如何把主题改为已解决啊
你在重新编辑一下 帖子,把它设置为已解决。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2