黑马程序员技术交流社区

标题: 关于extends的问题 [打印本页]

作者: 黄昆    时间: 2012-6-6 08:22
标题: 关于extends的问题
本帖最后由 hkylp 于 2012-7-1 09:10 编辑

1)class A{
A(){}
}
class B extends A{
B(){}    //这里的方法体没有加入父类的方法
}
class Test{
public static void main(String[] args){
  B b=new B();
  b.B();
}
}                                            
2)然后我把程序改为
class A{
A(){}
}
class B extends A{
B(){super();}
}
class Test{
public static void main(String[] args){
  B b=new B();
  b.B();
}
} //我在B的构造方法中加入了父类的方法,应该符合  子类的构造过程中必须调用父类的构造方法,这个条件,但是为什么还是出现同样的错误,求解!!!!

问题2是在调用子类的任何一种方法时(比如带返回值类型的方法)都必须先调用父类的方法,还是仅仅调用子类的构造方法时才必须调用父类的方法?


作者: 闾丘日月    时间: 2012-6-6 08:26
class A{
A(){}
}
class B extends A{
B(){}  
public void B(){}//这里的方法体没有加入父类的方法
}
class Test{
public static void main(String[] args){
  B b=new B();
  b.B();
} 就可以编译过了
构造器只能通过new来调用,不能通过你那种b.的方式哦
作者: 一生一世    时间: 2012-6-6 08:33
兄弟,哪有人这么调用构造方法的,你见过吗?这样根本就不对嘛,构造方法是在new对象是才调用的,怎么能直接用对象的引用调用呢???对象的引用调用的是成员方法,所以你这样写肯定会报错的,还有就是你的第二个问题,就是就近原则,如果子类有就调用子类的,如果子类没有就调用父类的。希望你能好好地理解一下构造方法。鄙人之见,仅供参考。谢谢
作者: 郑文博    时间: 2012-6-6 08:35
子类中所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类中每一个构造函数内的第一行都有一句隐式super(); 所以你的第5行虽然没有加父类方法,实质上已经有了父类方法。

而当父类中没有空参数的构造函数时,子类必须手动通过supper或者this语句形式来指定要访问的构造函数。
子类的构造函数第一行也可以手动指定this语句语句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。
作者: 古银平    时间: 2012-6-6 08:37
  1. class A{
  2. A(){}
  3. }
  4. class B extends A{
  5.   //在这会有一条默认的super()语句;必须放在类的第一行
  6. B(){super();}
  7. }
  8. class Test{
  9. public static void main(String[] args){
  10.    B b=new B();
  11.    b.B();
  12. }
复制代码
调用顺序:主函数中的B b=new B();然后但类B,那么第一行将执行super();就回到父类A中执行父类的构造函数,然后是子类B的构造函数。
作者: 朝哥    时间: 2012-6-6 09:02
lz,你把类里面到底有哪些内容搞混淆了。
类里面有什么了,看下面:
1、成员变量
2、成员方法
3、构造方法
4、代码块
当然局部变量和局部变量可以存在与2、3、4中。
构造方法是干嘛用了?它是初始化对象用的,你的写法b.B()是把B()当成了成员方法。所以会报错

总结,b.后边跟的是成员方法或者成员变量,不可能跟构造方法和代码块。

作者: 朝哥    时间: 2012-6-6 09:04
B()是构造方法。补充一句,函数又叫方法。
作者: 王月    时间: 2012-6-6 09:44
1,LZ的错误不再构造方法上。即使子类 B 中的构造方法中不加super()语句,也会默认加上的。
2,错误的地方是在主函数的 B b = new B; b.B();这里,构造方法是用来创建对象的,所以是不可能被对象调用的。最多也就可以在子类中被super或this指定。
3,解决:所以如果LZ想让主程序能以这样的形式执行的话,必须在子类中给定一个B的方法(普通方法)。LZ的代码我稍微修改了一下,希望能帮到你。

class A{
A(){}
}
class B extends A{
B(){}   //里面不需要加super,会默认加上的
public void B() {
   
}
}
class Test{
public static void main(String[] args){
   B b=new B();
    b.B();
}
}

4.楼主的第二个问题,是关于多态的。

1,如果是LZ上面那种格式:B b = new B();叫做子类引用指向子类对象,都是子类,不是多态,b.B();不需要调用父类方法,直接就能调用到子类本身的方法。
2,如果把B改成 A 即:A b = new B();这就叫做父类引用指向子类对象,是多态。所以b.B()方法会先去父类A需找是否有B()方法,如果有就执行,没有就会执行 B 中的B()方法。
注意:这里的B()方法是public void B() {}。

        帮LZ解答问题,我也重新复习了一遍,LZ多理解有颜色部分的内容。


作者: 孙峰    时间: 2012-6-6 10:14
王月 发表于 2012-6-6 09:44
1,LZ的错误不再构造方法上。即使子类 B 中的构造方法中不加super()语句,也会默认加上的。
2,错误的地方 ...

第二个关于 多态的问题中:
   对于调用B()方法: 在编译时:如果引用型变量所属的类中(父类)中有的话,则通过,么有就编译失败。
                     运行时: 参阅对象所属类中(子类),是否有该方法,有则运行正常。   
这里的B()是一般的成员方法。  当B是成员变量 或者 静态成员函数时,     无论是编译还是运行 都要参阅 父类的了。
作者: 黄昆    时间: 2012-6-14 18:54
朝哥 发表于 2012-6-6 09:02
lz,你把类里面到底有哪些内容搞混淆了。
类里面有什么了,看下面:
1、成员变量

透彻!懂了,谢啦!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2