【问题标题】:Constructor cannot be applied to given types, creating objects in Java, object oriented programming构造函数不能应用于给定类型,在 Java 中创建对象,面向对象编程
【发布时间】:2025-12-30 03:40:11
【问题描述】:

我正在尝试编写一个程序 (Driver),它将创建 Humans 及其 Pets 和特定类型,如下所示。

我遇到了多个错误:在 Driver 程序中,错误是当我尝试执行 Humans b = new Humans(); 时,我得到: constructor Humans in class Humans cannot be applied to given types.

此外,如果我尝试写出Humans b = new Humans("Jane", Pet/Dog...),我不确定如何指定该人的宠物类型。

任何帮助和指导将不胜感激。

public class Humans {
    String name;
    Pets pet;
    int popcount;

    public Humans(String hname, Pets hpet) {
        name = hname;
        pet = hpet;
    }

    public int populationCount() {
        return popcount;
    }

    public void makePetMakeNoise() {
        int randnum = (int) (Math.random() * 10);
        pet.makeNoise(randnum);
    }

    public void feedPet() {
        pet.eat();
    }
}

public class Pets {
    String name;
    String noise;
    boolean canMakeNoise;

    public Pets(String pname, String pnoise, boolean pcanmakenoise) {
        name = pname;
        noise = pnoise;
        pcanmakenoise = canMakeNoise;
    }

    public void makeNoise(int number) {
        if (canMakeNoise != false) {
            for (int i = 0; i < number; i++) {
                System.out.println(noise + name);
            }
        } else {
            System.out.println(name + " *remains silent*");
        }
    }

    public void eat() {
        System.out.println(name + " is eating...");
    }

    class Dog extends Pets {
        public Dog(String pname, String pnoise, boolean pcanmakenoise) {
            super(pname, pnoise, pcanmakenoise);
        }

        public void eat() {
            System.out.println(name + " is eating...");
        }
    }

    class Cat extends Pets {
        public Cat(String pname, String pnoise, boolean pcanmakenoise) {
            super(pname, pnoise, pcanmakenoise);
        }

        public void eat() {
            super.eat();
            System.out.println("I'm still hungry, meow");
        }
    }
}

public class Driver {
    public Driver() {
        Humans b = new Humans();
        b.name = "Jane";
        Pets bb = new Pets(Cat);
        b.pet = bb;
        bb.canMakeNoise = true;
        bb.name = "Bertha";
        ArrayList<String> list = new ArrayList<String>();
        list.add(b);

        ListIterator<String> itr = list.listIterator();
        while (itr.hasNext()) {
            String str = itr.next();
            str.makePetMakeNoise();
            str.feedPet();
        }
        System.out.println(Humans.populationCount());
    }
}

【问题讨论】:

  • 您好,欢迎来到 Stack Overflow!请尽量只提供clear and minimal example;您的代码在这里太长了!
  • 最好考虑一下每个类的对象代表什么。在您的情况下,Humans 的对象代表一个人类,因此最好将您的类命名为 Human(不带 s)。 Pets 也是如此。只有当类的对象确实代表多个(例如人类列表)时,才使用复数是一个好主意。

标签: java oop object subclass superclass


【解决方案1】:

您看到的第一个问题是您尝试不向 Humans 构造函数传递任何参数,但您没有定义不带参数的构造函数。解决这个特定错误的简单方法是向 Humans 添加一个默认构造函数:

public Humans() {}

可能更符合您尝试的做法是调用您拥有的构造函数。为此,您需要将姓名和宠物传递给Humans(String, Pets),您似乎已经知道了。

创建 Pets 对象很简单,但您不必像尝试那样指定宠物的类型:Pets 的每个子类本身就是一个类,因此您可以调用 new Pets.Cat(...) 而不是尝试在 Pets 上调用某些东西.

这让我们:

Pets bb = new Pets.Cat("Bertha", "meow", true);
Humans b = new Humans("Jane", bb);

这会导致更多的编译错误,但希望对您提出的构建问题有所帮助。


关于命名约定/结构的评论:

  1. 对象名称通常不是复数:Humans 类的一个实例代表一个人,而不是多个人(目前至少,不确定您将使用 population 去哪里),所以它会更合适命名为Human
  2. 子类不需要放在它们的父类中。 DogCat 更典型地会放在 Pets 类之外:extends Pets 的继承通知用户/编译器与 Pets 的关系,类定义的位置不需要。

【讨论】:

    【解决方案2】:

    你不能像这样构造对象

    Humans b = new Humans();
    b.name = "Jane";
    Pets bb = new Pets(Cat);
    b.pet = bb; bb.canMakeNoise = true;
    bb.name = "Bertha";
    

    因为您制作了 CatDog non-static nested classes 或内部(并且因为默认情况下类成员是私有的),所以您需要像这样收缩它们

    Pets p = new Pets("AllPets", "SomeSound", true);
    Humans b = new Humans("Jane", p.new Cat("Bertha", "meow", true));
    

    还有完整的代码

    Pets p = new Pets("AllPets", "SomeSound", true);
    Humans b = new Humans("Jane", p.new Cat("Bertha", "meow", true));
    ArrayList<Humans> list = new ArrayList<>();
    list.add(b);
    
    ListIterator<Humans> itr = list.listIterator();
    while (itr.hasNext()) {
        Humans h = itr.next();
        h.makePetMakeNoise();
        h.feedPet();
        System.out.println(h.populationCount());
    }
    

    但是,在这种情况下,Pets 具有构造函数参数是没有意义的。所以我猜你希望CatDog 是静态的。像这样

    static class Cat extends Pets {
        ...
    }
    static class Cat extends Pets {
        ...
    }
    

    或者您可以在父类之外定义它们(这更有意义)。

    然后就可以创建对象了

    Pets p = new Pets.Cat("Bertha", "mew", true);
    Humans b = new Humans("Jane", p);
    

    您也不能将Humans 对象添加到String 列表中(参见上面的代码)。

    【讨论】:

      【解决方案3】:

      遇到了多个错误:在 Driver 程序中,错误是当我尝试执行 Humans b = new Humans();我得到:类 Humans 中的构造函数 Humans 不能应用于给定类型。

      因为你已经创建了参数化构造函数,所以没有无参数构造函数。

      注意:- 如果我们手动创建构造函数,编译器不会自动放置默认构造函数。

      所以要解决这个问题你需要创建,

      人类 b=new Human("John Doe",new Pet("Lassy","Meyyeww",true));

      【讨论】:

        最近更新 更多