2010-12-06 160 views
3

嗨,大家好,我在一个问题集中遇到了一个“扩展”问题,我正在处理一个问题集 - 我想我只是有一个块,因为它被写有目的地混淆。这里是因为我得到了它的问题:Java - 扩展问题

class A { 
    int x; 
    A(int a) {System.out.println(" class A");} 
} 

class B extends A { 
    int x; 
    B() {System.out.println(" class B");} 
    public static void main (String [] args) { 
    A a = new B(); 
    } 
} 

当我编译,我得到以下错误从控制台踢出:

cannot find symbol 
symbol : constructor A() 
location: class A 
    B() {System.out.println(" class B");} 
    ^

,我应该能够解决这个错误在B班没有触及A班。我明显错过了一些显而易见的东西,但我已经尝试了一小时所能想到的一切排列,没有任何工作。

到目前为止,我已经试过:

  • 在B()的前投掷无效 - 相同的错误。
  • 将B()转换为A(int a) - 后者返回一个无效的方法声明错误(在它前面添加一个void将我踢回原始的“找不到符号”错误)
  • making B ()B(int a) - 同样的错误,加上抛出额外的“无法找到符号”的错误,因为我现在已经抛出了B()声明。
  • 使B类扩展到B类扩展A(int A) - 抛出9个错误。显然不是答案。
  • 将A的类名更改为Apple只是为了查看是否会给我一个答案 - 这要求我在Apple类的A(int a)前添加一个void,这是我无法做到的。

我到底在想什么?这不完全是一个高级班,所以它不会是非常复杂的任何事情,但这使我完全疯了。任何帮助将不胜感激。

回答

5

在派生类中,您需要调用基类构造函数。如果你没有明确地做到这一点,编译器会尝试插入对无参数构造函数的调用 - 如果基类中不存在,则会出现该错误。

的解决方案是显式调用基类构造函数的一些值:

B() { 
    super(0); 
    System.out.println(" class B"); 
} 
+0

你打我45秒:) – 2010-12-06 03:23:42

+0

啊 - 我记得我试过这样做超(a),它扔一个错误,可能是因为我实际上并没有定义一个。谢谢! – BigE 2010-12-06 03:27:57

+0

@BigE:请点击左侧旁边的复选框标记为正确答案。谢谢。 – Asaph 2010-12-06 05:20:23

0

A类没有默认构造函数,因为你没有写一个(但你没有写一个接受一个int参数)。

B类有一个无参数默认构造函数。它需要调用超类的构造函数,但它不能,因为A类中没有这样的东西。

+0

是的,我想到了很多,但我试图找出如何解决这个问题 - Anon。的文章有解决方案。谢谢! – BigE 2010-12-06 03:30:17

2

你在B的构造函数中的第一次调用需要超级(a); a是无论你想输入到B的构造函数。

1

1)当扩展一个类时,你的子类隐含地包含一个数据块,该数据块包含用于构建超类实例的所有数据。你也必须初始化这些数据。如果您没有说明它将如何初始化,则假定您需要默认构造函数,即A.A()。但是这个构造函数不存在 - 你只有A.A(int)

为此初始化,如在B的构造函数的第一行,您对一个构造函数的调用,具有特殊的语法如下:

B() { 
    super(42); 
    // because we are calling the constructor that takes an int, we must supply 
    // one. It's up to you to figure out what values should be supplied. Maybe 
    // you wanted to take an int in the B constructor, and pass it along? 
    System.out.println(" class B"); 
} 

2)你必须在这两个类中声明的int x; A和B类。这可能不是你想要的。如上所述,每个B实例已经包含一个int x-它自动获得的一个,因为B延伸A.