java默认public、protected和包访问性的方法(实例方法)是虚方法,子类可以覆盖。具体在这,子类覆盖(重写)了这两个虚方法,当调用这两个方法时实行的是动态绑定(又叫迟绑定或运行时绑定,还有个与之对应的概念叫编译时绑定),多态机制会起作用。这里,因为实际上创建的是派生类(子类)的实例(通过new Dervied()语句),因此this引用的是一个Dervied类的对象,在父类的构造器中调用tellName和printName,就相当于是这样调用的this.tellName()this.printName()这会调用this引用的对象的实际所属类的方法,输出的是子类的name属性。记住:调用的是子类的方法,访问的也是子类的属性。
为什么会输出null?
因为这两个方法是在构造子类的、继承自父类的部分时(即父类的构造器中)调用的,子类的name属性还没有初始化。
这里的调用顺序是这样的:
new语句->本类构造器->父类构造器->本类的两个虚方法(它们访问子类的属性name)。
但java构造对象的执行顺序是这样的:
new语句->本类(子类)构造器嫌顷改(先不执行语句)->调用父类构造器(先不执行语句)->执行父类的属性定义->执行父类的初始化块->执行父类的构造芹判器语句(在这才执行乎拿@@)->返回子类的构造器(返回后依然先不执行语句)->执行子类的属性定义(##)->执行子类的初始化块->执行子类的构造器语句(在这才执行)->new返回。当父类也有父类时也按这个顺序执行,即先构造祖先,再构造父类,最后构造自己。
在这里,是在构造父类的时候(执行父类的构造器语句时)调用了tellName和printName方法,其中访问了子类的还未赋值的属性name,输出的当然是默认值。只有在执行子类的属性定义时(见上面的##标记的位置),name才会被赋值,而这还排在执行父类的构造器语句的后面(见上面的@@标记的位置)。
您好,非常荣幸能在此回滚拆答您的问题。以下是我对此问题的部分见解,若有错误,欢槐李迎指出。输出:5public void add(int pInt){ //定义一个方法,参数是一个int型
pInt ++//pInt = pInt + 1
}
这题主要是考你参数传递的问大明枣题,int型传的是值,所以虽然pInt++后pInt=6
但没有带回去,所以i还是5非常感谢您的耐心观看,如有帮助请采纳,祝生活愉快!谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)