1. 능력

인터페이스의 이점과 사용 위치를 더 잘 이해하려면 좀 더 추상적인 것에 대해 이야기해야 합니다.

클래스는 일반적으로 특정 개체를 모델링합니다. 인터페이스는 개체보다는 개체의 능력이나 역할에 더 많이 해당합니다.

인터페이스의 본질

예를 들어 자동차, 자전거, 오토바이, 바퀴 등은 클래스와 개체로 가장 잘 표현됩니다. 그러나 "나는 탈 수 있다", "나는 사람을 수송할 수 있다", "나는 서 있을 수 있다"와 같은 그들의 능력은 인터페이스로 더 잘 표현된다. 여기 몇 가지 예가 있어요.

암호 설명
interface CanMove
{
   void move(String newLocation);
}
이동 능력에 해당
interface Rideable
{
   void ride(Passenger passenger);
}
탈 수 있는 능력치에 해당
interface CanTransport
{
   void addStuff(Object stuff);
   Object removeStuff();
}
물건을 운반하는 능력에 해당
class Wheel implements CanMove
{
   ...
}
클래스 이동Wheel 가능
class Car implements CanMove, Rideable, CanTransport
{
   ...
}
수업 Car움직이고, 탈 수 있고, 물건을 옮길 수 있습니다.
class Skateboard implements CanMove, Rideable
{
   ...
}
클래스 이동 및 탈Skateboard 수 있습니다


2. 역할

인터페이스는 프로그래머의 삶을 크게 단순화합니다. 매우 자주 프로그램에는 수천 개의 객체와 수백 개의 클래스가 있지만 단지 수십 개의 인터페이스 , 즉 역할이 있습니다 . 역할은 거의 없지만 이들을 결합하는 방법(클래스)은 많습니다.

요점은 다른 모든 클래스와 상호 작용하기 위해 각 클래스에 대한 코드를 작성할 필요가 없다는 것입니다. 그들의 역할(인터페이스)과 상호 작용하기만 하면 됩니다.

당신이 애완동물 조련사라고 상상해보세요. 당신이 함께 일하는 각 애완동물은 여러 가지 다른 능력을 가질 수 있습니다. 당신은 누구의 애완동물이 가장 큰 소리를 낼 수 있는지에 대해 이웃과 우호적인 논쟁을 벌입니다. 문제를 해결하려면 "말"할 수 있는 모든 애완동물을 일렬로 세우고 그들에게 다음과 같은 명령을 내립니다. 말하세요!

당신은 그들이 어떤 종류의 동물인지 또는 그들이 어떤 다른 능력을 가지고 있는지 상관하지 않습니다. 트리플 백 공중제비를 할 수 있다고 해도. 이 특정 순간에 당신은 그들의 큰 소리로 말하는 능력에만 관심이 있습니다. 코드에서 다음과 같이 표시됩니다.

암호 설명
interface CanSpeak
{
   void speak();
}
능력 CanSpeak. 이 인터페이스는 에 대한 명령을 이해합니다 speak. 즉, 해당 메서드가 있음을 의미합니다.
class Cat implements CanSpeak
{
   void speak()
   {
      println("MEOW");
   }
}

class Dog implements CanSpeak
{
   void speak()
   {
      println("WOOF");
   }
}

class Fish
{
   ...
}
이 기능을 가진 동물.

이해를 돕기 위해 클래스 이름을 영어로 제공했습니다. 이는 Java에서 허용되지만 매우 바람직하지 않습니다.













우리는 Fish말할 수 있는 능력이 없습니다( CanSpeak인터페이스를 구현하지 않음).

public static void main(String[] args)
{
   // Add all the animals to the list
   ArrayList pets = new ArrayList();
   pets.add(new Cat());
   pets.add(new Dog());
   pets.add(new Fish());

   // If the ability exists, then make a sound
   for(Object pet: pets)
   {
      if (pet instanceof CanSpeak)
      {
         CanSpeak loudmouth = (CanSpeak) pet;
         loudmouth.speak();
      }
   }
}
그리고 우리는 그들에게 어떻게 명령을 내릴까요?

프로그램의 클래스 수가 수천에 도달하면 인터페이스 없이는 살 수 없습니다. 수천 개의 클래스의 상호 작용을 설명하는 대신 수십 개의 인터페이스의 상호 작용을 설명하는 것으로 충분합니다. 이는 삶을 크게 단순화합니다.

그리고 다형성과 결합하면 이 접근 방식은 일반적으로 대성공입니다.



3. default인터페이스 메서드 구현

추상 클래스는 변수와 메서드 구현을 가질 수 있지만 다중 상속을 가질 수는 없습니다. 인터페이스는 변수나 메서드 구현을 가질 수 없지만 다중 상속을 가질 수 있습니다.

상황은 다음 표에 표현되어 있습니다.

능력/재산 추상 클래스 인터페이스
변수
방법 구현
다중 상속

따라서 일부 프로그래머는 인터페이스가 메소드 구현 기능을 갖기를 정말로 원했습니다. 그러나 메서드 구현을 추가할 수 있다고 해서 항상 추가된다는 의미는 아닙니다. 원하는 경우 추가하십시오. 또는 그렇지 않다면 하지 마십시오.

또한 다중 상속 문제는 주로 변수로 인해 발생합니다. 어쨌든 그것은 그들이 결정하고 행한 것입니다. JDK 8부터 Java는 인터페이스에 메서드 구현을 추가하는 기능을 도입했습니다.

다음은 업데이트된 표입니다(JDK 8 이상용).

능력/재산 추상 클래스 인터페이스
변수
방법 구현
다중 상속

이제 추상 클래스와 인터페이스의 경우 구현을 포함하거나 포함하지 않고 메서드를 선언할 수 있습니다. 그리고 이것은 훌륭한 소식입니다!

추상 클래스에서 구현이 없는 메서드는 키워드 앞에 와야 합니다 abstract. 구현이 있는 메서드 앞에 아무 것도 추가할 필요가 없습니다. 인터페이스에서는 그 반대입니다. 메서드에 구현이 없으면 아무 것도 추가하면 안 됩니다. 그러나 구현이 있는 경우 default키워드를 추가해야 합니다.

간단하게 하기 위해 다음 작은 표에 이 정보를 제공합니다.

능력/재산 추상 클래스 인터페이스
구현이 없는 메서드 abstract
구현이 있는 메서드 default

문제

메서드가 있는 인터페이스를 사용하면 대규모 클래스 계층 구조를 크게 단순화할 수 있습니다. 예를 들어 추상 InputStreamOutputStream클래스를 인터페이스로 선언할 수 있습니다! 이를 통해 훨씬 더 자주 그리고 훨씬 더 편리하게 사용할 수 있습니다.

그러나 전 세계에는 이미 수천만(수십억?)의 Java 클래스가 있습니다. 그리고 표준 라이브러리를 변경하기 시작하면 무언가가 깨질 수 있습니다. 모든 것처럼! 😛

실수로 기존 프로그램과 라이브러리를 중단하지 않기 위해 인터페이스의 메서드 구현이 가장 낮은 상속 우선 순위를 갖도록 결정되었습니다 .

예를 들어, 한 인터페이스가 메서드가 있는 다른 인터페이스를 상속하고 첫 번째 인터페이스가 동일한 메서드를 선언하지만 구현이 없는 경우 상속된 인터페이스의 메서드 구현은 상속되는 인터페이스에 도달하지 않습니다. 예:

interface Pet
{
   default void meow()
   {
      System.out.println("Meow");
   }
}

interface Cat extends Pet
{
   void meow(); // Here we override the default implementation by omitting an implementation
}

class Tom implements Cat
{
}

Tom클래스가 메서드를 구현하지 않기 때문에 코드가 컴파일되지 않습니다 meow().