【问题标题】:Call Method From interface in Java从Java中的接口调用方法
【发布时间】:2017-11-23 13:15:01
【问题描述】:

我正在尝试在我的 DogOwner 类中创建一个名为 makeDogsBark() 的方法,该方法应该执行当前 DogOwner 拥有的所有狗的 bark() 方法。

当我尝试调用该方法时,出现以下错误。 DogOwner.java:21:错误:狗是抽象的;无法实例化

这是我的 Dog.java 界面:

public interface Dog {
String getName();
String getBreed();
void bark();
}

这是我的第一堂课 Doggo.java:

public class Doggo implements Dog {
    private String name;

    public Doggo(String name){
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public String getBreed() {
        return "doggo";
    }

    @Override
    public void bark() {
        System.out.println("The doggo " + name + " made a noise: Woof!, it said.");
    }
}

这是我的第二课 Pupper.java:

public class Pupper implements Dog {
    private String name;

    public Pupper(String name){
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public String getBreed() {
        return "pupper";
    }

    @Override
    public void bark() {
        System.out.println("The pupper " + name + " made a noise: Bark! Bark! Bark!, it said.");
    }
}

这是我的第三类 DogOwner.java:

public class DogOwner {

private String name;
private ArrayList<Dog> dogsOwned;

public DogOwner(String name){
    this.name = name;
}

public void adoptDog(Dog newDog){
    if(!this.dogsOwned.contains(dogsOwned)){
        this.dogsOwned.add(newDog);
    }

}

public void makeDogsBark(){
    System.out.println("The person " + name + " made all his/hers dogs bark.");
    Dog dog = new Dog();
    dog.bark();
}
}

【问题讨论】:

  • 我可以知道你在哪里调用这些方法吗?请发布您收到的错误
  • “我尝试这样做,但它不工作” - “它不工作”是永远足够的信息。它会编译但抛出异常吗?它不编译吗?它是否编译然后毫无例外地运行,但没有给出预期的结果?什么是预期的结果?请提供minimal reproducible example,明确说明预期与实际行为。
  • 嗨乔恩,谢谢编辑我的原始帖子现在出现错误。
  • 你不能创建对象到接口,创建实例到类并调用方法

标签: java class methods interface


【解决方案1】:

强制(用于编译)

接口不能被实例化:

Dog dog = new Dog();  // <-- This cannot possibly compile

您必须选择:

Dog dog = new Doggo("good boy");

和

Dog dog = new Pupper("good boy");

那么让每只狗都叫的方法应该在列表中循环:

public void makeDogsBark() {
    this.dogsOwned.forEach(Dog::bark);
}

或 Java 7- 版本:

public void makeDogsBark() {
    for (Dog dog : this.dogsOwned) {
        dog.bark();
    }
}

可选(为了代码质量)

(可选)dogsOwned 属性也应该是List:

private List<Dog> dogsOwned;

并在构造函数中被实例化:

public DogOwner(String name) {
    this.name = name;
    this.dogsOwned = new ArrayList<>();  // new ArrayList<Dog>() Java 7-
}

(可选)另外,如果您希望您的 Dog 集合是唯一的,请使用 Set 而不是列表。

private Set<Dog> dogsOwned;

public DogOwner(String name) {
    this.name = name;
    this.dogsOwned = new HashSet<>();  // new HashSet<Dog>() Java 7-
}

这样你就可以:

public void adoptDog(Dog newDog) {
    this.dogsOwned.add(newDog);  // Won't add anything that already exists in the Set
}

问题是,它将比较并不总是理想的对象引用。 为了避免这种比较,您可以覆盖equals() 和hashcode() 方法以您想要的方式比较对象。在您最喜欢的搜索引擎上检查“实现等于和哈希码”。

【讨论】:

  • 嗯,然后得到以下错误:错误:类 Doggo 中的构造函数 Doggo 不能应用于给定类型; Dog dog = new Doggo();
  • 您必须永远在代码中的任何位置写入new Dog()。使用 Dog 的两种实现之一更改所有出现的情况。
  • 构造函数需要你给它一个名字。所以使用新的new Doggo("good boy")。或者为 Doggo 类编写另一个不带任何参数的构造函数。
  • 还应该提到Dog的实现需要实现正确的equals()和hashCode()方法
  • 谢谢阿德里安!解决了我的问题 :-) 不幸的是,我们只允许使用 ArrayList。不过遇到了一个新问题,显然你应该能够创建 2 个 DogOwners,这是我得到的错误:d.pr/i/KXGktF 我不明白为什么这是问题?还是我应该创建一个新的实例变量?
【解决方案2】:
public void makeDogsBark(){
    dogsOwned.forEach(it -> it.bark());
}

【讨论】:

    【解决方案3】:

    你不能实例化一个接口。

    Dog dog = new Dog();
    

    这是一个错误的代码行。

    除此之外,您可以遍历 dogsOwned 列表并让每只狗吠。

    for(Dog dog : dogsOwned){
            dog.bark();   
    }
    

    你也可以使用这个来跳过 Java 8 中的循环。

    dogsOwned.forEach(dog->dog.bark());
    

    希望对你有所帮助。

    【讨论】:

    • 如果你举例说明如何正确地做到这一点,那将是一个正确的答案!
    猜你喜欢
    • 2018-06-13
    • 2014-03-13
    • 2012-03-17
    • 2021-09-30
    • 2019-12-27
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多