4

我是一名初学 Java 程序员,在理解 Java 语言的 OOP 中实现的总体情况时遇到了困难。

我将尝试用下面的伪代码来构建我的问题(如果它不是那么漂亮,请道歉):

interface{
  foo();
}

class a {
  //stuff
  foo() OPERATIONS;
}
class b {
  //stuff
  foo() OPERATIONS;
}

//The OPERATIONS segment is actually the *work* the foo does: i.e., if foo were 
//print, it would be the System.out.println("");

现在,如果接口的 'foo' OPERATIONS 是在实际类中声明的,那么接口的目的是什么?我认为接口的目的是创建一个“方法抓取包”,它在所有类混淆之外,以避免必须重新构建可以在代码的一部分中修改的层次结构并应用于许多实现类。换句话说,我想象一个接口就像在“C”语言中使用的函数一样:一组隔离而简洁的操作聚集在一起并封装起来,以便在需要时调用,并分组在一个代码段中,以便可以在接口内修改 foo 的 OPERATIONS,它适用于实现该接口的所有类。我错过了什么?

谢谢!

4

8 回答 8

3

接口指定了一个类做什么的契约,但不指定它是如何做的。想象一个排序算法,可能有很多实现。

public interface Sorter {

    void sort(List<String> list);

}

您可以使用冒泡排序、合并排序、快速排序等

但作为分拣机的用户,我可能不在乎。

class SortClient {

    SortClient(Sorter sorter, List<String> list) {
      sorter.sort(list);
    }

}

SortClient不在乎你如何排序,只是它被排序。

在 Spring 或 Guice 等进行依赖注入的框架中,这变得非常重要。这些框架允许您在不更改用户的情况下配置使用哪个实现。

接口还有其他实际用途。它们对于创建用于测试的模拟/存根很有用。在上述SortClient情况下,也许您想为排序器创建一些存根,例如:

ExceptionThrowingStubSortClient implements Sorter {
   void sort(List<String> list) {
      throw new SortException("Testing the exception handling");
   }
}
于 2013-10-09T00:05:34.493 回答
2

首先阅读什么是接口?.

基本上,接口是一个契约,它声明所有实现都interface保证提供由interface. 需要注意的是,一个实现可能决定实现一个空方法而不是提供一个实际的编码实现,这取决于实现,但它确实保证interface可以在接口的实现上调用由 描述的方法。

例如...

public interface Foo {
    public void doBar();
}

声明任何实现都foo必须提供一个调用的方法,该方法doBar不返回任何内容(void)...

interface无法实例化

意味着你做不到

Foo foo = new Foo(); // Compiler error...

但是你可以interface在一个具体的class...

public class FooBar implements Foo {
    public void doBar() {
        // Functional implementation of doBar...
    }
}

这现在允许我们创建一个FooBar...的实例

FooBar fooBar = new FooBar();
fooBar.doBar();

您还可以将任何实现视为...Foo的实例Foo

Foo foo = new FooBar();
foo.doBar();

(ps-是的,我知道,从技术上讲,这不是 的实例Foo,而是简单的FooBar行为,例如Foo;))

这是多态性的核心

Foo这允许您解耦您的代码,因为您的代码不需要关心Foo.

这也允许您限制对实现的访问,这意味着因为Foo只定义了方法doBar,所以任何期望实现的方法Foo都不能调用任何其他方法doBar

(ps-是的,我知道有办法解决这个问题,但目的是,你不应该!)

这涉及到接口的程序的核心,而不是实现

于 2013-10-09T00:06:59.457 回答
2

Interface在 java 中就像与实施的合同class。当你实现一个接口时,你必须确保要么实现了类中的所有方法,要么实现了interface你的类abstract。让我们来一个真实的类比。

您正在创建汽车。现在你知道那里可能有很多汽车,例如梅赛德斯、宝马、奥迪等。您想确保每辆汽车都应包含changeGear(), hasWheels(),hasDoors()方法,那么您将如何对所有可能的汽车强制执行此标准。只需创建一个包含所有这些方法的interface命名,例如Car

public interface Car{
boolean changeGear();
boolean hasWheels();
boolean hasDoors();
}

现在每个class实现它interface的人都必须实现所有这些方法。所以,将来如果你创建一个Ferrari实现 Car 接口的类,它必须遵守这个约定。

编辑:这里要注意的是,所有实现 的类interface不限于仅使用接口中的方法。就像实现class必须确保它至少实现了interface. 就像我们的示例Ferrari类可以很好地实现isSportCar()只包含在Ferrari类中的方法。

于 2013-10-09T00:09:32.003 回答
1

Java中的接口用于为所有将要实现它的类以及所有那些将使用它来解决问题的类设置契约。但不像你说的那样,它可以像c或任何其他语言一样用作可重用函数,因为java中的所有函数/方法都封装在一个类中。

接口是抽象方法的集合,类实现接口,继承接口中声明的所有抽象方法。接口与类有一些相似之处,但接口不是类。例如,一个接口不能被实例化,它不能包含任何实例字段,只能有常量字段,如静态最终字段。

于 2013-10-09T00:10:46.367 回答
1

Java 接口的目的是对不同对象之间可能共有的某种行为进行建模。就像人可以弹跳一样,球也可以弹跳,因此可弹跳的行为在 2 类不同的对象之间很常见,即一个人和一个球

在上面的伪代码中,foo接口可以描述类ab之间常见的某种行为

喜欢:

interface Foo{
  void bounce();
}

class A implements Foo {
 public void bounce() {
       System.out.println("Class A instance is bouncing");
 }
}

class B implements Foo {
 public void bounce() {
       System.out.println("Class B instance is bouncing");
 }
}
于 2013-10-09T00:10:48.577 回答
0

相反,接口定义了一组可以从类中获得的行为。只是行为而不是实现。让我用一个简单的例子。你已经上过开车的课程,现在你有了驾照,你就可以开车了。你学的是哪个牌子的车?它是燃气发动机还是柴油发动机?最重要的是,这重要吗?

你学会了汽车的接口。既然您知道如何使用接口以及预期的行为,那么如何实现该行为并不重要。因此,任何品牌的汽车,任何发动机类型都适合您。另请注意,您不必真正了解汽车发动机的工作原理以驾驶汽车。

在软件中,接口用于指定行为。然后在您的代码中,您可以说我需要一个可以执行 bar() 操作的 Foo 对象。您不需要知道 bar() 的实现细节,只需知道调用它时会发生什么。

例如,您可能决定需要一个可能包含重复对象的 List 集合。在 Java API 中有不止一种 List 实现,例如 ArrayList 和 LinkedList。您可以编写使用 List(接口)的代码,而不必担心是哪个实现。这反过来又使您的代码更加健壮和可重用。

于 2013-10-09T00:08:43.727 回答
0

在某些方面,Javainterface类似于 C 头文件:它在单独的文件中声明类具有的方法/函数。

为什么这在面向对象系统中很有用?

这很有用,因为其他类可以实现接口,声明这些方法并以相同的方式使用它们,并遵守这些方法的规则(方法契约)。其他代码只能使用接口调用这些对象,并且可能不知道或关心除了实现接口之外的任何其他实现。

例如,一个 java OutputStream(从技术上讲是一个抽象类,但在本例中我们可以假装它是一个接口)具有写入字节的方法

abstract class OutputStream{ 

   void write(int byte);

   void write(byte[] buffer);

   void close();

 }

有几种实现OutputStream,一些写入平面文件,一些写入内存数组,一些写入数据到控制台。如果我们的代码使用 anOutputStream我们不必关心如何自己做所有这些事情,我们可以稍后在编译时或运行时替换不同的实现,我们的代码仍然可以工作!

于 2013-10-09T00:11:01.977 回答
-1

这是Oracle关于接口的文档的引用:

界面自行车{

//  wheel revolutions per minute
void changeCadence(int newValue);

void changeGear(int newValue);

void speedUp(int increment);

void applyBrakes(int decrement); 

}

为了实现这个接口,你的类的名字会改变(比如特定品牌的自行车,比如 ACMEBicycle),你可以在类声明中使用 implements 关键字:

类 ACMEBicycle 实现自行车 {

// remainder of this class 
// implemented as before 

}

这是了解更多信息的链接。

希望它有所帮助!

于 2013-10-09T00:04:11.240 回答