㈠ 关于java中用子类初始化父类对象的问题
>>为什么这里b2.x输出的值是10呢???
答:Java中方法为动态绑定,但是属性是静态绑定的,也就是说虽然b2指向的是一个Sub类对象,但是由于属性的静态绑定原则,b2本身作为base类型的对象他的属性x依然是base类中的x,这也可以说明:多态在面向对象中是针对方法而言的。
>>这和b2是base型有什么关系,b2是base型在这里有什么意义。
>>最好能举个例子。
答:b2作为base类型的对象,在面向对象语言中,父类类型的引用是可以指向子类类型的对象的,因此b2是base类型的引用指向sub类型的对象。如:
Collection c = new ArrayList();
这里的c也是这种情况。
>>顺便问一下溯造型是怎么回事?
我学Java这么长时间没听说过"溯造型"的概念,也可能是叫法不同,但是在我想你说的应该是类型转换的问题,在面向对象语言中子类对象可以直接转换变成父类对象,如Collection c =new ArrayList(),同时父类对象也可以通过强制类型转换变成父类对象,前提是父类对象的实际类型是子类对象,如:
Collection c1 = new ArrayList();
Collection c2 = new HashSet()
ArrayList a = (ArrayList)c1;//成功
ArrayList b = (ArrayList)c2;//失败
>>最后一个问事关于“上溯造型”的。
答案同上个问题
㈡ Java子类构造函数初始化问题
刚刚想当然的回答了一个3,然后发现不妥,试了一下果然不对,就可耻的把回答删除了,删除后居然不能重新回答,果断重新注册个号回答
首先我们加上点东西
publicclassDemo10{
publicstaticvoidmain(String[]args){
newJoo();
}
}
classIoo{
inta=3;
publicIoo(){
System.out.println("Ioo构造方法执行");
System.out.println("Ioo中this类型为:"+this.getClass().getSimpleName());//查看this是什么类型
this.t();
System.out.println("Ioo构造方法执行完毕");
}
publicvoidt(){
System.out.println("执行Ioo的t方法");
System.out.println(this.a);
System.out.println("Ioo中的t方法执行完毕");
}
}
classJooextendsIoo{
intb=3;
publicJoo(){
System.out.println("Joo构造方法执行完毕");
}
@Override
publicvoidt(){
System.out.println("执行Joo中的t方法");
System.out.println(this.b);
System.out.println("Joo中的t方法执行完毕");
}
}
输出结果为:
-------------------------------------
Ioo构造方法执行
Ioo中this类型为:Joo
执行Joo中的t方法
0
Joo中的t方法执行完毕
Ioo构造方法执行完毕
Joo构造方法执行完毕
-------------------------------------
为什么输出的是0呢?又为什么Ioo中this的类型会是Joo呢?
接下来我们反编译一下class文件
classIoo{
inta;
publicIoo(){
a=3;
System.out.println("Ioo构造方法执行");
System.out.println("Ioo中this类型为:"+getClass().getSimpleName());
t();
System.out.println("Ioo构造方法执行完毕");
}
publicvoidt(){
System.out.println("执行Ioo的t方法");
System.out.println(a);
System.out.println("Ioo中的t方法执行完毕");
}
}
classJooextendsIoo{
intb;
publicJoo(){
b=3;
System.out.println("Joo构造方法执行完毕");
}
publicvoidt(){
System.out.println("执行Joo中的t方法");
System.out.println(b);
System.out.println("Joo中的t方法执行完毕");
}
}
我们可以看出,成员变量的赋值操作是放到了构造方法中执行的,我们根据控制台输出语句的顺序来模拟java的执行顺序,由于我们实例化的是子类Joo,他会首先执行父类的构造方法,我们先来看执行顺序
a赋值为3
输出"Ioo构造方法执行"
由于this代表当前对象,那么既然是实例化Joo时调用的方法,this代表的就是Joo,故输出Joo
执行t方法(由于class反编译后,this.被简化了,所以我们观察源代码,this.t(),既然this的类型是Joo,那么this.t()执行的就是Joo中的t方法)。此时控制台输出"执行Joo中的t方法"
此时应该执行System.out.println(b),我们想当然的以为应该是3,结果却输出了0,原因是这样:我们在Joo的构造方法中加入了输出语句,可是在控制台,此时并没有输出"Joo构造方法执行完毕",可见Joo的构造方法并没有执行,就是b = 3的赋值语句同样没有执行,此时的b默认值为0,故控制台输出了0。
此时t方法执行完毕,输出"Joo中的t方法执行完毕",Ioo的构造方法也执行完毕,输出"Ioo构造方法执行完毕"
父类Ioo的构造方法执行完毕,最后执行子类Joo的构造方法,我们看到,此时的b才被赋值为3,最后输出"Joo构造方法执行完毕"
至此,模拟完成,有不懂的可以再hi我,不要hi这个号,这号只是为了临时回答注册的,如无意外,不会再上,我常用的叫kq346635081,在这条回答的评论里
㈢ Java 子类初始化的疑问,感觉是大牛的人进!
B b = new B();
∵B继承A
∴B的run()方法覆盖了A的run()方法
∵new B()首先隐含调用了super()
∴执行了public A(){run();}方法
∵这个run()方法是子类B的方法
又∵这时候子类B的构造方法还没有执行
∴子类B的属性i还没有值
∴现在i是默认的0
楼主的困惑就在于没有理清那个输出0的run()方法是谁的run(),你分别在两个run()方法里加入System.out.println("class A");System.out.println("class B")就能明白了。你可能会发现没打印class A。
㈣ 请问Java能不能直接用子类初始化父类
其实回答你这个问题挺难的,因为你问的问题本身就是个问题,通过你问的问题,你很多概念其实没有搞清楚...。
首先子类父类的继承性问题是类之间的关系,而初始化是对象的问题(当然类也能初始化,但是这种初始化无关于子类父类,这也不牵扯到你问的问题)。对象是没有父子的问题的,当你实例化一个类的对象出来,这个对象是属于这个类以及这个类的所有父类的,即是说,如果User继承Personnel再继承Object,那么你实例化一个User对象Jone,那么Jone既是User的对象同时也是Personnel的对象同样也是Object的对象,但是这里只有一个对象,没有三个对象,Jone包含三个类的所有特性,包括属性,方法等等。所以当你实例化Jone这个对象以后,它其实已经同时初始化三个类所定义的所有属性。而java机制是从父类到子类初始化的。从这个概念上来讲,实例化一个类的对象出来,那么久必须把这个类的所有父类定义的全部特性全部初始化,而且必须初始化,这不是能不能的问题,是必须这么做。
就目前而言,你对java内部的编译和运行机制不甚了解的情况下,思考这种问题其实无益,你应该更多的着眼于目前的基础知识,很多问题在你了解更多的知识以后这些都不是问题,你现在去想这种似是而非的问题,会让你思维混乱的,因为你这个问题的本身问法就是错的,从一个错误的问题出发,即使别人给你回答,那么怎么回答都是错的,别人需要从很基础的知识一点一点给你讲,大多数人不会浪费这么多时间不会跟你解释的,你要注重自我学习,不要乱提错误的问题。
㈤ 当java父类和子类都有构造函数时,求子类对象初始化过程详解
你好,初始化过程是这样的:
1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
3.其次,初始化父类的普通成员变量和代码块,在执行父类的构造方法;
4.最后,初始化子类的普通成员变量和代码块,在执行子类的构造方法;
最后,给你个例子吧。你运行着帮助理解。
class Super{
public static int a ;
private int b ;
static{
System.out.println("此时a的值为:" + a) ;
a = 10 ;
}
public Super(){
System.out.println("此时a的值为:" + a) ;
System.out.println("此时b的值为:" + b) ;
b = 20 ;
}
{
System.out.println("此时b的值为:" + b);
b = 30 ;
}
}
class Sub extends Super{
public static int aa ;
private int bb ;
static{
System.out.println("此时aa的值为:" + aa) ;
aa = 10 ;
}
public Sub(){
System.out.println("此时aa的值为:" + aa) ;
System.out.println("此时bb的值为:" + bb) ;
bb = 20 ;
}
{
System.out.println("此时bb的值为:" + bb);
bb = 30 ;
}
}
public class ConstructorTest {
public static void main(String[] args) {
new Sub() ;
}
}
㈥ java 编写一个子类(选择在子类中初始化父类成员方法)
super,超类,即父类。当你实例化一个子类的时候,编译器会自动查找子类的父类,并先将父类初始化。
当你的子类使用带参数的构造函数时,你必须保证该子类的父类也有相同的带参数的构造器。
1.super(),它用来告诉编译器,爷我用的是哪个型号的构造器,方便你找俺老子。
2.super.属性,用于访问父类属性或方法。
比如,
public class Father(){
public Father(){}
public Father(String name,String sex){
this.name=name;
this.sex=sex;
}
public String name="免贵姓唐";
public String sex;
}
public class Son_1(){
public Son_1()
public Son_1(String name,String sex){
super(name,sex);
}
public String name="真的免贵";
public static void main(String[] arg){
print(super.name+" "+name);
}
}
快睡了,思维有点混。不懂hi我好了。568418555,Q我也成。
㈦ Java 构造方法初始化顺序
初始化子类,调用子类有参的时候默认情况下也是先去调用父类的无参构造,除非你在子类的构造方法中使用super来指明调用父类中的哪个构造方法。
㈧ java 初始化其子类必先初始化其父类什么意思
因为子类的构造函数里面必然调用了父类的构造函数
一般来说,子类的构造函数里面会隐式的调用父类的构造函数,就是那个super.什么什么的
因为隐式调用,所以看不到。但是是存在的。如果你显式的调用那么必须放在第一行。
而且从理论上来说,既然你要初始化子类,子类会继承父类的一部分属性和方法,如果你不初始化父类,那么子类岂不是没有意义。继承不了父类的属性和方法。
所以,初始化子类必须要初始化父类
㈨ java中继承及子类初始化问题
在语句A a=new A();中
new的作用是为对象a分配内存并将a的来自S的字段x和来自A的字段x都初始化为默认值0。
A()的作用是调用类A的构造器。当进入A的构造器的调用后,super()将调用父类S的构造器,在S的构造器中会再调用类Object的构造器,然后从Object的构造器返回,执行S的字段初始化语句public int x=6;(这是编译器自动为你执行的),然后返回到S的构造器中,再调用test方法,由于A复写了超类S的test方法,所以多态机制会发生作用,这里实际上调用的是A类的test方法,输出的是来自A的x的值,从前面可知,它的值还是0,所以输出0。接着调用从S的构造器返回,执行A的初始化语句public int x=5;(同样,这是编译器自动为你执行的),再返回到A的构造器中,完成对象a的构造。接着调用a.test();自然调用的是类A的test方法,输出的是来自A的当前x的值5。
㈩ java初学者:子类继承父类,子类初始化会调用父类的构造方法,是不是因为子类要想实例化必须父类先实
子类要想实例化必须先实例化父类
因为子类继承父类,继承的是父类中的成员(成员变量及成员方法),要想使用父类的成员就得实例化父类,才能使用
情况一:父类有无参构造方法
JAVA默认是会调用父类的构造方法的,在子类的构造函数中,编译器会自动的加一个super来调用父类的构造方法
情况二:父类的构造方法是带参数的,而且没有无参数的构造方法
那么在子类的构造方法中必须显式地调用父类的构造方法。