为什么这个类不能编译?

时间:2018-06-07 08:25:04

标签: java inheritance extends

这段代码没有编译,我想知道是因为Puppy中没有构造函数(如超级构造函数或其他东西),还是因为其他东西?

class Pet {
    String name;
    Pet(String name) {
        this.name = name;
    }
}
class Puppy extends Pet {}

public class fiddle {

    public static void main(String[] args ){
        Pet pup = new Puppy("Doggo");
    }
}

5 个答案:

答案 0 :(得分:2)

请参阅this

  

子类继承所有成员(字段,方法和嵌套   来自其超类的类)。构造者不是成员,所以他们   不是由子类继承,而是超类的构造函数   可以从子类调用。

您可以将其更改为:

class Puppy extends Pet {
    public Puppy(String name) {
        super(name);
    }
}

答案 1 :(得分:1)

constructor第一项任务的Puppy来电将致电constructor的{​​{1}}。

如果parent class只有parent class,那么这不会造成问题。如果您向default (no parameter) constructor添加default constructor,再次没问题,但由于parent class中没有此类constructor,您需要告诉parent class怎么做。

因此,您需要向child class添加constructorchild class会调用constructor的{​​{1}}。

这可以是:

parent class

public Puppy(String input) {
  super(input);
}

但它需要将public Puppy() { super("default"); // or null, if you prefer that } 的现有constructor作为第一个声明。

答案 2 :(得分:0)

您的班级Puppy延伸PetPet有一个自定义构造函数,因此,Puppy需要一个public Puppy(String name){...}

答案 3 :(得分:0)

您已经提供了答案。由于Puppy不是抽象的,因此它必须是可实例化的。编译器抱怨,因为它无法这样做。要构造一个对象Puppy,您还需要至少调用其中一个超类构造函数。现在唯一一个带参数的构造函数,不能假定默认的无参数构造函数。这就是你需要自己提供它的原因。

类似的东西:

public Puppy(String name) {
   super(name);
}

或:

public Puppy() {
   super("puppy");
}

答案 4 :(得分:0)

扩展类时,仍然需要调用它的构造函数,以便初始化类及其字段。 Pet的构造函数接受一个String。默认情况下,当您扩展类时(如Puppy那样),编译器会将隐式调用添加到无参数构造函数中,以方便使用。因为Pet没有无参数构造函数,所以此代码不会编译。

您可以通过调用明确接受字符串的构造函数来修复它:

class Puppy extends Pet {
    Puppy(String name) {
        super("Puppy called " + name);
    }
}

class Puppy extends Pet {
    Puppy() {
        super("Puppy");
    }
}

同样地(尽管你可能不想这样做),如果你从Pet删除了构造函数,你的代码就会编译,因为一切都会隐式发生:

class Pet {
}
class Puppy extends Pet {
}

在内部,编译器将其转换为:

class Pet {
    Pet() {
        // do nothing
    }
}
class Puppy extends Pet {
    Puppy() {
        super(); // call Pet's constructor
    }
}