父类与子类的实例化

        从很多java的书籍中我们都知道,一个类继承了另外一个类,要实例化子类,必须要先实例化父类。有了父亲,才可能有了儿子。但是,这个实例化大概是个怎样的一个过程呢?我们举几个例子。

(1)

public class Son extends Father{
private String s = "子成员变量";
public Son(){
}
@Override
public void message() {
System.out.println("儿子");
}
public static void main(String[] args) {
new Son();
}
}
class Father {
private String s = "父成员变量";
public Father(){
System.out.println(this.s);
this.message();
}
public void message() {
System.out.println("父亲");
}
}

也许有些初学者会觉得输出的是:

父成员变量

父亲的

包括我,以前不加思考,也觉得是这个答案。查看了一些资料,才知道,但实际上输出的是:

父成员变量

儿子

实际上,在Father类的构造函数中,this对象是Son而不是Father,我们用getClass().getName()方法就可以得知。但是,为什么同是this,既然this是指Son,那为什么this.s却输出的是"父成员变量"呢?而this.message()却调用的是Son的message()方法。这样子,给了我很大的不确定性啊。本来我父类想调用自己的方法,做一些初始化的事情,但子类一继承,我调的却不是自己的方法了,子类我也是未知的,我那里知道子类是谁,子类你覆盖了我的方法,做些我不可以接收的事那怎么办。多态,给我带来了不确定性。先不急,再看第二个例子。

(2)

public class Son extends Father{
private String s = "子成员变量";
public Son(){
}
@Override
public void message() {
System.out.println("儿子");
}
public static void main(String[] args) {
Son son = new Son();

Father father = son;

System.out.println(son.s);

System.out.println(father.s);

son.message();

father.message();
}
}
class Father {
private String s = "父成员变量";
public Father(){
}
public void message() {
System.out.println("父亲");
}
}

你没眼花,没错,输出的是:

子成员变量

父成员变量

儿子

儿子

而不是:

子成员变量

子成员变量

儿子

儿子

        father和son不是指向都是同一个对象吗?对。既然指向的都是同一个对象,那怎么输出会不一样呢?我是这样理解,父类与子类的实例化是这样的,对于方法,如果子类没有覆盖父类的方法,那么子类就会有父类方法的一个拷贝。如果子类覆盖了父类的方法,就不用拷贝了。但对于成员变量,无论是子类有没有一样的成员变量,子类都会有父类的所有成员变量的一个拷贝。我们用debug就可以看到,当Son实例化时,是有两个s成员变量的。但是,对于成员变量的调用,是由引用类型决定的,就是当我个调用father.s时,实际调用的是从Father继承过来的s成员变量,当我们调用son.s的时候,实际调用的是Son自己定义的s成员变量。而对于方法却不一样,方法的调用,是由实际类型决定的,不管你引用类型是什么,是father,还是son,调用的都是实际对象中的方法,即new出来的对象方法。

        由此,我们再回去看看(1)。在Father的构造方法中,this的实际对像是Son,所以当调用方法时,执行的是son方法。但是由于在Father的构造方法内,所以引用类型是Father,而调用成员变量时由引用类型决定,所以调用的是Father的成员变量。

        对于我们的javabean,要调用成员变量,我们通常都提供get方法。所以,不管是引用类型是什么,调用得到的都是new出来的对象的成员变量,这样,就减弱了多态带来的不确定性。

          这是我的一些理解,如果有不对的地方,大家指正。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值