有关Java接口的一般问题

时间:2019-10-31 11:51:37

标签: java interface

我只是开始使用界面,我无法理解这个概念。

class Client {
    IServer x = new Server();
    void m() {
        x.p();
    }
}

interface IServer {
    void n();
    void p();
}

class Server implements IServer{
    public void n() {
        System.out.println("Methode n");
    }
    public void p() {
        System.out.println("Methode p");
    }
}

因此,客户端应该能够通过IServer接口使用服务器提供的方法。 IServer x = new server();是否正确?我发现的示例(https://www.w3schools.com/java/java_interface.asp)所有构建接口,然后主类调用另一个类而不使用该接口。 谢谢您的帮助,我想我只是在这里遗漏了一些明显的东西...

2 个答案:

答案 0 :(得分:0)

https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html

是官方的更好文档
  

在软件工程中有很多情况,对于不同的程序员群体来说,同意一份阐明其软件交互方式的“合同”很重要。每个小组都应该能够编写其代码,而无需了解另一小组的代码是如何编写的。一般来说,接口就是这样的合同。

使用接口,您可以强制类具有特定的行为,该行为在接口内定义,但在实现该接口的类内实现。

而且,如果您知道对象Dog实现了接口Run,并且该接口声明了方法run() {},则可以安全地在对象上调用方法run。对象Dog,因为它包含方法实现:

Interface Run
{
    public void run();
}

class Dog implements Run
{
    public void run()
    {
        // the dog is running
    }
}

Dog dog = new Dog();
dog.run();

答案 1 :(得分:0)

可以通过以下示例很好地说明接口如何工作以及为什么使用它们。假设我们有一个带动物的动物园物体。我们希望所有动物都能发出噪音,具体取决于它们是哪种动物。我们从以下课程开始:

public class Zoo {
    private List<Animal> animals;

    public Zoo() {
        animals = new ArrayList<>();
    }

    public void addAnimal(Animal animal) {
        animals.add(animal);
    }

    public void roar() {
        for(Animal a : animals) {
            a.makeNoise();
        }
    }
}

这基本上只是一个包含动物列表的对象,我们可以将动物添加到该列表中。当我们调用方法roar时,我们希望所有动物发出自己的声音并将其打印到控制台。现在这是在界面上有用的地方,因为我们知道我们将有多种类型的动物,所以我们可以指定基本的“动物”可以做什么,这些是描述它们可以某事但不能做到的通用特征如何。例如,一个盒子和一个人都可以移动,但是一个人可以自己移动,而一个盒子不能移动。也许人类可以上楼梯,而狗则不能。知道了这一点,我们创建了一个描述动物可以发出声音的基本界面:

public interface Animal {
    void makeNoise();
}

这将使我们能够创建所需数量的动物,同时迫使它们实现我们定义的功能。现在,我们可以创建一些动物:

public class Cat implements Animal {
    private String name;

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

    @Override
    public void makeNoise() {
        System.out.println(name + "said Meow");
    }
}

public class Dog implements Animal {
    @Override
    public void makeNoise() {
        System.out.println("Woof");
    }
}

如您所见,我们可以给两个类提供自己的功能,同时仍然强制两个类至少能够发出各自的声音。在这种情况下,猫可以起名字,而狗则不能。这意味着我们现在可以用所需的任何动物填充Zoo,并且由于它们都具有相同的覆盖界面,因此我们不必创建多个Collection来存储每种动物。我们可以根据它们的接口将它们全部扔进一大堆,然后可以通过该接口调用适当的方法:

public void run() {
    Zoo zoo = new Zoo();
    zoo.addAnimal(new Cat("Bob"));
    zoo.addAnimal(new Dog());
    zoo.addAnimal(new Cat("William"));
    zoo.roar();
}

就类型而言。它的工作方式与现实生活一样。按照我们的示例,狗是动物,但动物不一定是狗。由于在这种情况下(当它在动物园内时)我们的代码只知道它具有动物,而没有什么特定类型,因此它仅允许我们访问在接口中定义的功能。

这意味着我们可以做类似的事情:

Animal a = new Dog();
Dog b = new Dog();
Animal c = new Cat("Bob");
Cat d = new Cat("Wilbert");

但不是:

Animal a = new Dog();
Dog b = a;

自从我们分配a并说“你是动物”后,就不知道a中的数据是否真的是狗。