子类与父类构造函数顺序,包括静态…

说下子父类构造函数的调用
创建子类的时候,先检查父类是否有静态的属性,如果有,则先调用静态属性的语句,然后检查子类是否也有静态类型属性,有,则调用子类的静态类型,然后在调用父类普通变量,构造函数,然后才是子类的普通属性,构造函数。
顺序是:
父类静态
子类静态
父类属性
父类构造函数
子类属性
子类构造函数
///但是!!!
如果父类是个抽象类,而这时候父类构造函数调用到子类里的函数,而且需要引用子类的某个属性,这时候这个属性输出多少呢?答案从上面的构造顺序知道,因为父类构造函数运行的时候子类的属性还没有被初始化(准确说应该是没有被用户初始化,但是编译器已经初始化为0) 所以,输出的结果是0


--------------所以在编写构造器的时候应该注意,下面引用thinking in java的一句话--------------------
因此,编写构造器时有一条有益的规则:
“用尽可能简单的方法使对象进入正常状态;如果
可以的话,
避免调用其他方法” 在构造器内唯一能够安全调用的那些方法是基类中的 final
方法(也适用于 private 方法,它们自动属于 final 方法)。这些方法不能被重载,因此也
就不会出现上述令人惊讶的问题。
------------------------------------------------------------------------------------
import tools.P;


public class SubClass extends Shape{

public static void main(String[] args) {
// TODO Auto-generated method stub
Shape cir = new Circle();
Shape sub = new SubClass();
SubClass sc = new Test();
sc.f();
}

private void f(){
P.rintln("subclass f()");
}
}

class Shape {
Info in2 = new Info("shape");
static Info in = new Info("statc Shape");
public Shape(){
draw();
P.rintln("Shape constructor");
}
public void draw(){
P.rintln("Shape.draw()");
}
private void f(){
P.rintln("private f()");
}
}

class Circle extends Shape{
int r;
Info in2 = new Info("circle");
static Info in = new Info("static circle"); 
public Circle(){
r=8;
P.rintln("circle constructor");
}
public void draw(){
P.rintln("Circle.draw() r="+r);
}
public void f(){
P.rintln("public f");
}
}

class Test extends SubClass{
public void f(){
P.rintln("test f()");
}
}

class Info{
public Info(String str){
P.rintln(str);
}
}

------------------------------------输出----------------------------
statc Shape
static circle
shape
Circle.draw() r=0
Shape constructor
circle
circle constructor
shape
Shape.draw()
Shape constructor
shape
Shape.draw()
Shape constructor
subclass f()

你可能感兴趣的:(java)