Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的接口-它们的用途是什么?_Java_Interface - Fatal编程技术网

Java中的接口-它们的用途是什么?

Java中的接口-它们的用途是什么?,java,interface,Java,Interface,可能重复: 不久前我才开始学习Java。 我遇到过接口,我知道如何使用,但仍然不能完全理解它。 据我所知,接口通常由类实现,然后类必须实现接口中声明的方法。 问题是——重点到底是什么?仅仅从接口实现方法作为普通类方法不是更容易吗?使用接口的优势到底是什么 我试着在谷歌上寻找答案。有很多,但我还是不明白它的意义。我也读过书和它的答案,但整个合同的事情只是让它变得更复杂 希望有人能把它简化得足够好!:) 提前谢谢 它们用于实现而不需要使用继承。接口指定功能。在某种程度上,它们提供了多重继承。假设我

可能重复:

不久前我才开始学习Java。
我遇到过
接口
,我知道如何使用,但仍然不能完全理解它。
据我所知,
接口
通常由类实现,然后类必须实现接口中声明的方法。
问题是——重点到底是什么?仅仅从接口实现方法作为普通类方法不是更容易吗?使用接口的优势到底是什么

我试着在谷歌上寻找答案。有很多,但我还是不明白它的意义。我也读过书和它的答案,但整个合同的事情只是让它变得更复杂

希望有人能把它简化得足够好!:)

提前谢谢

它们用于实现而不需要使用继承。

接口指定功能。在某种程度上,它们提供了多重继承。假设我有一个函数,它可以处理列表。但不只是一个列表,只是任何集合。任何我能在内容上循环的东西。所以我使用接口Iterable

public int randomMethod(Iterable<Integer> li) {
...
}
public int-random方法(Iterable li){
...
}
现在,这适用于列表和哈希集以及所有不同的东西,它们以完全不同的方式实现和工作,属于不同的类结构,但都提供了这一基本功能。这与大型游戏循环不同,
.update()
s扩展公共类的所有实体,尽管可以使用接口

列表
界面为例。您只能在一点上决定是否要在特定场合使用
ArrayList
LinkedList
(或其他相关内容)


然而,它们都实现了
列表
接口。因此,无论它们是如何工作的,或者它们是否在等级上有关联,可以保证它们公开了一组您可以使用的方法,并且您不必在代码的每一点上都知道最终得到的集合对象背后的实现。

我建议您查看和组合模式。

您的问题非常广泛,可以在一篇文章中回答,而不必太过复杂做作的或过于笼统而没有用处的。因此,我将尝试给出一个有希望的有意义的例子,说明接口何时非常有用

假设您有许多表示各种类型对象的类。。可能是一打,或任何足够大的数字。在另一个类中有一些函数,可以对任意对象进行排序。为此,它需要能够比较任意两个对象,并确定一个对象大于或小于另一个对象。由于每个对象都可以是多种类型的类中的任意一种,因此编写此比较函数将非常繁琐,因为它必须确定每个对象的类型,然后通过调用每个类的适当逻辑来进行比较

输入接口。此时,您可以让所有类实现一个接口,例如Comparable,该接口指定实现它的任何类都将实现一个Compare方法

现在,orders对象的函数将变得很容易编写,因为它可以依赖这样一个事实,即它需要比较的任何对象类都将具有相同的Comapre方法


这只是一个例子,也是一个相当常见的例子。

接口允许您在运行时提供不同的实现,注入依赖项,分离关注点,使用不同的实现进行测试

只需将接口视为类保证实现的契约。实现接口的具体类是无关的。我不知道这是否有用

我想一些代码可能会有所帮助。这并不能解释接口的所有内容,请继续阅读,但我希望这能让您开始。这里的要点是,您可以改变实现

package stack.overflow.example;

public interface IExampleService {
void callExpensiveService();
}

public class TestService implements IExampleService {

@Override
public void callExpensiveService() {
    // This is a mock service, we run this as many 
    // times as we like for free to test our software

}
}

public class ExpensiveService implements IExampleService {
@Override
public void callExpensiveService() {
    // This performs some really expensive service,
    // Ideally this will only happen in the field
    // We'd rather test as much of our software for
    // free if possible.
}
}


public class Main {

/**
 * @param args
 */
public static void main(String[] args) {

    // In a test program I might write
    IExampleService testService = new TestService();
    testService.callExpensiveService();

    // Alternatively, in a real program I might write
    IExampleService testService = new ExpensiveService();
    testService.callExpensiveService();

    // The difference above, is that we can vary the concrete 
    // class which is instantiated. In reality we can use a 
    // service locator, or use dependency injection to determine 
    // at runtime which class to implement.

    // So in the above example my testing can be done for free, but 
    // real world users would still be charged. Point is that the interface
    // provides a contract that we know will always be fulfilled, regardless 
    // of the implementation. 

}

}
因为“致命的死亡钻石”。 让我们考虑一下这种情况:

您可以用编程语言编写类(名称:
Parent
),其中允许多重继承。该类包含一个实例变量(
inta;
)和一个方法(
voidhello()
)。然后创建两个类(
Kid1
Kid2
)。每个类都扩展了父类
。然后重写
hello()Kid1
Kid2
类中都使用code>method,您可以为
Kid1
Kid2
类中的
a
变量赋值。在最后一步中,您创建了扩展
Kid1
Kid2
类(多重继承)的第4个类(如
Main
)。现在…问题是,
hello()方法将
Main
类继承
a
变量的哪个值


因为Java中没有多重继承,所以我们有
接口
。。。包含抽象方法的抽象类。我们可以实现多个接口,但在这种情况下,我们必须覆盖实现的
接口
包含的所有方法。

接口可以用于许多事情。最常见的用法是多态性和,您可以在运行时更改依赖项。例如,假设您有一个名为Database的接口,该接口有一个名为
getField(…)
的方法

现在假设您在应用程序中使用了两个数据库,具体取决于您的客户机:MySQL和PostgreSQL。您将有两个具体的类:

public class MySQL implements Database
{
    // mysql connection specific code
    @Override
    public void getField(String field)
    {
        // retrieve value from MySQL
    }
}
而且

public class PostgreSQL implements Database
{
    // postgre connection specific code
    @Override
    public String getField(String field)
    {
        // retrieve value from Postgre
    }
}
现在,根据您的客户机偏好,您可以在主数据库中实例化MySQL或PostgreSQL类

 public static void main(String args[])
 {
     if (args[2].equals("mysql"))
         Database db = new MySQL();
     else
         Database db = new PostgreSQL();
 }

 //now get the field
 String foo = db.getField();
或者您可以将Factory/Abstract Factory或脚本引擎与JS或Ruby结合使用

带int的想法
 public static void main(String args[])
 {
     if (args[2].equals("mysql"))
         Database db = new MySQL();
     else
         Database db = new PostgreSQL();
 }

 //now get the field
 String foo = db.getField();
public void passMeSomethingThatICanClose(AutoCloseable bar) {
    //stuff goes here
    bar.close(); //the compiler knows this call is possible
}
public class BrokenCloseable implements AutoCloseable {
    public void colse() {  //ERROR — see the typo?
        //blah
    }