java - Java中的接口(interface)是什么?

标签 java inheritance interface oop

就像 this question 的对立面一样: Java 中的接口(interface)是什么?

最佳答案

接口(interface)是抽象类的一种特殊形式,它不实现任何方法。在 Java 中,您可以像这样创建一个接口(interface):

interface Interface
{
    void interfaceMethod();
}

由于接口(interface)不能实现任何方法,这意味着整个事物,包括所有方法,都是公共(public)的和抽象的(Java 术语中的抽象意味着“没有被这个类实现”)。所以上面的界面和下面的界面是一样的:
public interface Interface
{
    abstract public void interfaceMethod();
}

要使用这个接口(interface),你只需要实现这个接口(interface)。很多类可以实现一个接口(interface),一个类可以实现很多接口(interface):
interface InterfaceA
{
     void interfaceMethodA();
}

interface InterfaceB
{
    void interfaceMethodB();
}

public class ImplementingClassA
    implements InterfaceA, InterfaceB
{
    public void interfaceMethodA()
    {
        System.out.println("interfaceA, interfaceMethodA, implementation A");
    }

    public void interfaceMethodB()
    {
        System.out.println("interfaceB, interfaceMethodB, implementation A");
    }
}

public class ImplementingClassB
    implements InterfaceA, InterfaceB
{
    public void interfaceMethodA()
    {
         System.out.println("interfaceA, interfaceMethodA, implementation B");
    }

    public void interfaceMethodB()
    {
        System.out.println("interfaceB, interfaceMethodB, implementation B");
    }
}

现在,如果您愿意,可以编写如下方法:
public void testInterfaces()
{
    ImplementingClassA u = new ImplementingClassA();
    ImplementingClassB v = new ImplementingClassB();
    InterfaceA w = new ImplementingClassA();
    InterfaceA x = new ImplementingClassB();
    InterfaceB y = new ImplementingClassA();
    InterfaceB z = new ImplementingClassB();

    u.interfaceMethodA();
    // prints "interfaceA, interfaceMethodA, implementation A"
    u.interfaceMethodB();
    // prints "interfaceB, interfaceMethodB, implementation A"
    v.interfaceMethodA();
    // prints "interfaceA, interfaceMethodA, implementation B"
    v.interfaceMethodB();
    // prints "interfaceB, interfaceMethodB, implementation B"
    w.interfaceMethodA();
    // prints "interfaceA, interfaceMethodA, implementation A"
    x.interfaceMethodA();
    // prints "interfaceA, interfaceMethodA, implementation B"
    y.interfaceMethodB();
    // prints "interfaceB, interfaceMethodB, implementation A"
    z.interfaceMethodB();
    // prints "interfaceB, interfaceMethodB, implementation B"
}

但是,您可以 从不请执行下列操作:
public void testInterfaces()
{
    InterfaceA y = new ImplementingClassA();
    InterfaceB z = new ImplementingClassB();

    y.interfaceMethodB(); // ERROR!
    z.interfaceMethodA(); // ERROR!
}

你不能这样做的原因是 yinterfaceA 类型, 并且没有 interfaceMethodB()interfaceA .同样,zinterfaceB 类型并且没有interfaceMethodA()interfaceB .

我前面提到过,接口(interface)只是抽象类的一种特殊形式。为了说明这一点,请查看以下代码。
interface Interface
{
    void abstractMethod();
}

abstract public class AbstractClass
{
    abstract public void abstractMethod();
}

您将从这些类继承几乎完全相同的方式:
public class InheritsFromInterface
    implements Interface
{
    public void abstractMethod() { System.out.println("abstractMethod()"); }
}

public class InteritsFromAbstractClass
    extends AbstractClass
{
    public void abstractMethod() { System.out.println("abstractMethod()"); }
}

实际上,您甚至可以像这样更改接口(interface)和抽象类:
interface Interface
{
    void abstractMethod();
}

abstract public class AbstractClass
    implements Interface
{
    abstract public void abstractMethod();
}

public class InheritsFromInterfaceAndAbstractClass
    extends AbstractClass implements Interface
{
    public void abstractMethod() { System.out.println("abstractMethod()"); }
}

但是,接口(interface)和抽象类之间有两个区别。

第一个区别是接口(interface)不能实现方法。
interface Interface
{
    public void implementedMethod()
    {
        System.out.println("implementedMethod()");
    }
}

上面的接口(interface)会产生一个编译器错误,因为它有一个 implementedMethod() 的实现。 .如果您想实现该方法但无法实例化该类,则必须这样做:
abstract public class AbstractClass
{
    public void implementedMethod()
    {
        System.out.println("implementedMethod()");
    }
}

这不是一个抽象类,因为它的成员都不是抽象的,但它是合法的 Java。

接口(interface)和抽象类的另一个区别是一个类可以继承多个接口(interface),但只能继承一个抽象类。
abstract public class AbstractClassA { }
abstract public class AbstractClassB { }
public class InheritsFromTwoAbstractClasses
    extends AbstractClassA, AbstractClassB
{ }

上面的代码产生编译错误,不是因为类都是空的,而是因为InheritsFromTwoAbstractClasses试图从两个抽象类继承,这是非法的。以下是完全合法的。
interface InterfaceA { }
interface InterfaceB { }
public class InheritsFromTwoInterfaces
    implements InterfaceA, InterfaceB
{ }    

接口(interface)和抽象类之间的第一个区别是第二个区别的原因。看看下面的代码。
interface InterfaceA
{
    void method();
}

interface InterfaceB
{
    void method();
}

public class InheritsFromTwoInterfaces
    implements InterfaceA, InterfaceB
{
    void method() { System.out.println("method()"); }
}

上面的代码没有问题,因为InterfaceAInterfaceB没有什么可隐瞒的。很容易看出调用 method将打印“方法()”。

现在看下面的代码:
abstract public class AbstractClassA
{
    void method() { System.out.println("Hello"); }
}

abstract public class AbstractClassB
{
    void method() { System.out.println("Goodbye"); }
}

public class InheritsFromTwoAbstractClasses
    extends AbstractClassA, AbstractClassB
{ }

这与我们的另一个示例完全相同,除了因为我们被允许在抽象类中实现方法,我们做到了,并且因为我们不必在继承类中实现已经实现的方法,所以我们没有。但是你可能已经注意到了,有一个问题。当我们调用 new InheritsFromTwoAbstractClasses().method() 时会发生什么?它打印“你好”还是“再见”?你可能不知道,Java 编译器也不知道。另一种语言 C++ 允许这种继承,他们以通常非常复杂的方式解决了这些问题。为了避免这种麻烦,Java 决定将这种“多重继承”设为非法。

Java 解决方案的缺点是无法完成以下操作:
abstract public class AbstractClassA
{
    void hi() { System.out.println("Hello"); }
}

abstract public class AbstractClassB
{
    void bye() { System.out.println("Goodbye"); }
}

public class InheritsFromTwoAbstractClasses
    extends AbstractClassA, AbstractClassB
{ }
AbstractClassAAbstractClassB是“混合”或不打算实例化的类,而是向通过继承“混合”的类添加功能。如果您调用new InheritsFromTwoAbstractClasses().hi(),显然没有问题弄清楚会发生什么。或 new InheritsFromTwoAbstractClasses().bye() ,但您不能这样做,因为 Java 不允许这样做。

(我知道这篇文章很长,所以如果有任何错误,请告诉我,我会纠正它们。)

关于java - Java中的接口(interface)是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59342785/

相关文章:

java - Android - GridView 中的按钮连续点击

java - `new Class<?>[] {}` 是什么意思?

Fortran 中的接口(interface)类型绑定(bind)过程

java - 只允许某些类访问私有(private)变量的接口(interface)

ruby - 使用多级继承而不是 ruby​​ mixins

typescript - 在使用 Typescript 实现期间立即检查类的静态端

java - 如何在Java中正确实现MVC模式?

java - 如何测试声明为 "public class"的类型是使用 java.lang.Class 的类?

java - asList 函数是 Lamdaj 库的一部分

c# - XAML 继承、代码重用、优化