밑에서 몇차례 golang의 interface에 대해서 언급이 된 글이 있습니다만, 이 글에서는 golang과 java에서 사용되는 interface의 차이점에 대해서 살펴보겠습니다.


우선 Cat, Dog이 Animal이라는 상위 개념으로 대변할 수 있고, Animal은 소리를 낼 수 있다라고 가정한 코드를 만들어보겠습니다.


public interface Animal {
  public void sound();
}

public class Cat implements Animal {
  public void sound() {
    System.out.println("냐옹");
  }
}

public class Dog implements Animal {
  public void sound() {
    System.out.println("멍멍");
  }
}

public static void main(String[] args) {
  Animal animal1 = new Cat();
  Animal animal2 = new Dog();

  animal1.sound();
  animal2.sound();
}



설명은 뒤에서 계속 하도록 하고 golang으로 만든 코드를 살펴보겠습니다.

package main

import "fmt"

type Cat struct {
}

type Dog struct {
}

func (c Cat) Sound() {
	fmt.Println("냐옹")
}

func (d Dog) Sound() {
	fmt.Println("멍멍")
}

type Animal interface {
	Sound()
}

func main() {
	var animal1 Animal
	var animal2 Animal

	animal1 = Cat{}
	animal2 = Dog{}

	animal1.Sound();
	animal2.Sound();
}

java에서의 interface는 상위 개념이 먼저 선언이 되어야합니다.

즉, 다음과 같은 흐름으로 개발이 진행되어야합니다.


1. Animal은 소리를 낸다.

2. Dog은 Animal의 하위개념이므로 Animal이 할 수 있는 것을 할 수 있어야하므로 sound를 구현해야한다.

3. Cat도 마찬가지이다.


이런 식의 흐름입니다. 


쉽게 말하자면 interface를 먼저 선언을 하고, 그 interface를 구현하는 class를 만들어 나가는 방식입니다.



반면에 golang에서의 interface는 java와는 흐름이 정반대입니다.


1. Dog은 소리를 낸다.

2. Cat은 소리를 낸다.

3. 그러므로 Dog과 Cat은 Animal의 한 종류이다.


이런 식의 흐름을 보여주고 있습니다.


이미 있는 struct에 같은 method들이 있으면 하나의 interface로 묶을 수가 있는 방식입니다. 

실제 소스에서 보면 Cat, Dog의 선언에 Animal이라는 내용이 전혀 들어가있지 않는 것을 알 수 있습니다.



이 차이는 패키지 하나만 사용할 때는 크게 차이가 없을 수 있으나, 자기가 만든 것이 아닌 다른 패키지를 사용해야할 경우라면 큰 차이가 발생합니다.


Java에서는 외부라이브러리에 선언된 class는 이미 interface가 정해져있고, 그 interface를 사용해야만 합니다. 


즉, Cat과 Dog이 이미 Animal이라는 interface를 구현하고 있고, 또 다른 라이브러리에서 Cow라는 class는 Living이라는 interface를 구현한다면 이 3개의 class를 동시에 만족시킬 interface는 없습니다.


하지만, golang에서는 이렇게 되어있다 할지라도 공통된 method를 포함하는 interface를 새로이 선언하여 한데 묶을 수 있는 장점이 있습니다.



귀납법과 유사한 golang의 interface가 실제 개발에서는 좀 더 유용할 것 같아보입니다.