Java:难以理解接口的用途?

时间:2014-06-30 22:12:43

标签: java interface

最近我介绍了Java中的接口,但是我无法理解它们的用途。所以,让我们说我有以下内容:

//this is an interface
public interface DanceMoves {
    public void theJitterbug(int twists);
    public void theHustle(int steps);
    public void theMoonwalk(int slides);
}

然后我有一个实现此接口的类:

public class DanceClub implements DanceMoves {
    public void theJitterbug(int twists) {
        System.out.println("Twist " + twists + " times!");
    }
    public void theHustle(int steps) {
        System.out.println("Step " + steps + " times!");
    }
    public void theMoonwalk(int slides) {
        System.out.println("Slide " + slides + " times!");
    }

    //more methods can go here

    public static void main(String[] args) {
        DanceClub letsDance = new DanceClub();
        letsDance.theJitterbug(5);
        letsDance.theHustle(4);
        letsDance.theMoonwalk(3);
    }        
}

也许我有另一个方法来实现这个接口:

public class Diner implements DanceMoves {
    public void theJitterbug(int twists) {
        System.out.println("Twist " + twists + " times!");
        System.out.println("We only do the jitterbug in diners!");
    }

    public void theHustle(int steps) {
    }

    public void theMoonwalk(int slides) {
    }

    public static void main(String[] args) {
        Diner letsDanceAgain = new Diner();
        letsDanceAgain.theJitterbug(5);
    }
}

所以我的问题是,如果我们不得不重写所有的接口方法,为什么还要打扰实现接口呢?这个重用代码怎么样?

编辑: 感谢所有回答的人!我是Java新手,到目前为止我学到的唯一其他语言是Jython。因此,虽然很多概念很好地转化,但是一些新的东西对我来说有点难以掌握。

我也很欣赏下面给出的回答示例,以及前面问题和外部来源的链接。我之前已经阅读了大部分这些问题并且已经阅读过那些外部资源,但是在我能够更清楚地了解我实际阅读的内容后,它们更有帮助!

但无论如何!我真正想要做的就是写下关于界面的重要内容(为了我的缘故和后人的缘故),看看我是否真的这么做了。它&#34 ;.我以前的问题是,如果我们不得不重写所有的接口方法,为什么还要打扰实现接口呢?这个重用代码怎么样?。使用Elliot Frisch修改我的例子:

public interface Dance { //an interface
  public void boogie(int count);
}

现在,您可以拥有实现此接口的方法,无论是否相关 -

public class theMoonwalk implements Dance {
  public void boogie(int count) {
    System.out.println("Slide " + count + " times!");
  }
  public void mJ() {
    System.out.println("Michael Jackson did this dance!");

}
public class theHustle implements Dance {
  public void boogie(int steps) {
    System.out.println("Step " + steps + " times!");
  }
}
public class theJitterBug implements Dance {
  public void boogie(int twists) {
    System.out.println("Twist " + twists + " times!");
  }
}

public class crazyUncle implements Dance {
  public void boogie(int shimmy) {
    System.out.println("I really don't know how to dance.");
  }

  public void yap() {
    System.out.println("When I was your age...!");
  }
}

然后使用它,

public static void main(String[] args) {

  Dance[] dances = new Dance[] {
      new theHustle(), new theMoonwalk(), new theJitterBug(), new crazyUncle()
  };
  for (Dance d : dances) { //for each element in this array of type Dance...
    // Note: The caller just boogies. The object determines the "move".
    d.boogie(3);
  }
}

现在,我的解释为什么如果我必须重写所有接口方法,我应该为实现接口而烦恼:

因为theHustle,theMoonwalk,theJitterbug和crazyUncle类都实现了Dance界面,所以他们实际上已经签署了#34;" a"合同"这保证了这些类的实例至少包含Dance接口中的方法。 因此,即使例如,theMoonwalk类与crazyUncle类不同,例如,可以将Moonwalk对象和crazyUncle对象包含在Dance类型的数组中,因为这些对象包含" DNA"舞蹈界面。

此外,我可以在另一个类中使用另一个方法,该方法接受Dance类型的参数:

public void danceExercise(Dance d, int num) {        
    d.boogie(num); 

}

当调用danceExercise方法时,对于Dance d参数,我可以提供任何实现Dance接口的类型的值。因此,由于crazyUncle和theMoonwalk都实现了Dance,我可以提供一个crazyUncle的实例或者一个舞蹈预期的Moonwalk实例。

TL; DR谢谢大家!我现在对接口有了更清晰的理解。

5 个答案:

答案 0 :(得分:1)

你的问题实际上encapsulates是接口有用的一个完美例子 - 但是让我们“点击”这一点,

public void theJitterbug(int twists) {
    System.out.println("Twist " + twists + " times!");
}
public void theHustle(int steps) {
    System.out.println("Step " + steps + " times!");
}
public void theMoonwalk(int slides) {
    System.out.println("Slide " + slides + " times!");
}

所有都在跳舞!所以,让我们这样称呼他们......

public interface Dance {
  public void getDown(int count);
}

现在,你可以 -

public class TheMoonwalk implements Dance {
  public void getDown(int count) {
    System.out.println("Slide " + count + " times!");
  }
}
public class TheHustle implements Dance {
  public void getDown(int steps) {
    System.out.println("Step " + steps + " times!");
  }
}
public class TheJitterBug implements Dance {
  public void getDown(int twists) {
    System.out.println("Twist " + twists + " times!");
  }
}

然后使用它,

public static void main(String[] args) {
  Dance[] dances = new Dance[] {
      new TheHustle(), new TheMoonwalk(), new TheJitterBug()
  };
  for (Dance d : dances) {
    // Note: The caller just gets down. The object determines the "move".
    d.getDown(3);
  }
}

答案 1 :(得分:0)

rahul pasrich和ra2085指出了很多关于这个主题的信息。为了更直接地回答你的问题,你可以做一些事情,比如采用类型为DanceMoves的论点而不关心它的实现位置。您可能有6种不同类型的舞蹈动作,以及您发送给它们的单个头像对象。这是Polymorphism的关键概念之一。

答案 2 :(得分:0)

接口允许方法确信您传入的内容是兼容的。因此,它允许您编写如下代码:

interface Animal
{
    public String getSound();
}

并且有两个实现此接口的类Catlizard,然后它们将分别定义getSound()方法的作用。因此,假设您有这样的方法:

public void makeSound(Animal animal) { /*make the sound, using animal.getSound()*/}

该方法可以确保实现Animal的任何类必须具有已定义的声音,因为它是Animal的属性,因此可以安全地传入Lizard或{{ 1}}在他们实施Cat时。这样您就无法制作AnimalmakeSound(Cat cat)

这意味着你 重用代码,只需要不同的代码(makeSound(Lizard lizard)方法只需要定义一次!)。想象一下,它是一种契约形式,可确保Object与方法

兼容

答案 3 :(得分:0)

我最喜欢的问题是面试

https://en.wikipedia.org/wiki/Strategy_pattern

如果你得到了战略模式,那么你也可以解释其他人

答案 4 :(得分:0)

Java中的继承包含两个概念。如果X继承自Y,那意味着......

  1. X可以替代Y,这意味着可以在任何需要引用Y的地方使用对X的引用。

  2. X的实例可以使用继承的Y成员的成员作为自己的成员。

  3. Java运行时只允许类使用从其他类型继承的成员,就好像它们是自己的一样。因此,类可以仅从一个其他类继承。另一方面,没有理由为什么一个班级不能发挥许多不同的规则,可以替代许多不同的无关事物。

    接口允许一种定义替换类的方法,这样需要实现特定接口的代码的代码将能够接受对实现该接口的任何类型的对象的引用。因为历史上需要实现接口的类来实现所有接口成员本身,所以实现接口的类不会从那些接口继承任何东西,除了能够传递给期望接口类型的代码,因此运行时限制单继承不会妨碍实现多个接口的类。