[Java] Interface

SeongEon Kim·2022년 5월 2일
0

JAVA

목록 보기
29/52

인터페이스(interface)를 알아보자.

  1. 문법과 개념

    어떤 객체가 있고 그 객체가 특정한 인터페이스를 사용한다면 그 객체는 반드시 인터페이스의 메소드들을 구현해야 한다. 만약 인터페이스에서 강제하고 있는 메소드를 구현하지 않으면 이 애플리케이션은 컴파일 조차 되지 않는다.

    package org.opentutorials.javatutorials.interfaces.example1;
    

interface I{
public void z();
}

class A implements I{
public void z(){}
}


 위의 코드에서는 클래스 A 뒤의 implements I는 이 클래스가 인터페이스 I를 구현하고 있다. 그것은 3행의 interface I의 맴버인 public void z() 메소드를 클래스 A가 반드시 포함하고 있어야 한다는 뜻이다. 따라서 위의 코드는 문제가 없다. 인터페이스의 의미를 좀 더 분명하게 하기 위해서 8행의 public void z(){}를 삭제하자. 컴파일 에러가 발생할 것이다. 

 인터페이스와 상속은 다르다. 상속이 상위 클래스의 기능을 하위 클래스가 물려 받는 것이라고 한다면, 인터페이스는 하위 클래스에 특정한 메소드가 반드시 존재하도록 강제한다. 


2. 기능
 
 상황극을 통해 이해해보자. 개발자 A와 개발자 B가 있다. 아래 두 개의 코드를 통해 설명하자면, 첫번째 코드는 개발자 A가 작성한 코드이고, 두번째 코드는 개발자 B가 작성한 코드다.
 
 개발자 A의 코드

package org.opentutorials.javatutorials.interfaces.example1;
class CalculatorDummy{
public void setOprands(int first, int second, int third){}
public int sum(){
return 60;
}
public int avg(){
return 20;
}
}
public class CalculatorConsumer {
public static void main(String[] args){
CalculatorDummy c = new CalculatorDummy();
c.setOprands(10,20,30);
System.out.println(c.sum()+c.avg());
}
}


 개발자 B의 코드

package org.opentutorials.javatutorials.interfaces.example1;

class Calculator {
int left, right;
public void setOprands(int left, int right) {
this.left = left;
this.right = right;
}
public void sum() {
System.out.println(this.left + this.right);
}
public void avg() {
System.out.println((this.left + this.right) / 2);
}
}


 개발자 A는 setOprands의 매개변수를 2개를 받았지만 개발자 B는 이 메소드가 변수 3개를 받을 것으로 예상하고 코드를 작성했다. 이런 문제를 해결하려면 협업자 상호간에 구체적인 약속을 하면 된다.
 클래스 Calculator를 사용할 개발자가 이 클래스가 가지고 있어야 할 메소드를 인터페이스로 만들어서 제공하는 것이다. 만드는 쪽에서 인터페이스를 제공하면 된다.
 아래와 같이 약속을 정의하고 있는 인터페이스 코드를 짤 수 있다.
 

package org.opentutorials.javatutorials.interfaces.example2;

public interface Calculatable {
public void setOprands(int first, int second, int third) ;
public int sum();
public int avg();
}


 다음은 인터페이스에 따라 구현된 클래스다.
 

package org.opentutorials.javatutorials.interfaces.example2;

class Calculator implements Calculatable {
int first, second, third;
public void setOprands(int first, int second, int third) {
this.first = first;
this.second = second;
this.third = third;
}
public int sum() {
return this.first + this.second + this.third;
}
public int avg() {
return (this.first + this.second + this.third) / 3;
}
}


마지막으로 클래스 CalculatroDummy를 실제 로직으로 교체해야 한다.

package org.opentutorials.javatutorials.interfaces.example2;
public class CalculatorConsumer {
public static void main(String[] args) {
Calculator c = new Calculator();
c.setOprands(10, 20, 30);
System.out.println(c.sum()+c.avg());
}
}


3. 규칙

 1) 하나의 클래스가 여러 개의 인터페이스를 구현할 수 있다.

package org.opentutorials.javatutorials.interfaces.example3;

interface I1{
public void x();
}

interface I2{
public void z();
}

class A implements I1, I2{
public void x(){}
public void z(){}
}

 단, 클래스 A는 메소드 x나 z 중 하나라도 구현하지 않으면 오류가 발생한다.
 
 2) 인터페이스도 상속이 된다.
 

package org.opentutorials.javatutorials.interfaces.example3;

interface I3{
public void x();
}

interface I4 extends I3{
public void z();
}

class B implements I4{
public void x(){}
public void z(){}
}


 3) 인터페이스의 멤버는 반드시 public이다.
 

package org.opentutorials.javatutorials.interfaces.example3;

interface I5{
private void x();
}

 위의 코드는 오류가 발생한다. 인터페이스는 그 인터페이스를 구현한 클래스를 어떻게 조작할 것인가를 규정한다. 따라서 외부에서 제어할 수 있는 가장 개방적인 접근 제어자인 public만을 허용한다. public을 생략하면 접근 제어자 default가 되는 것이 아니라 public이 된다. 왜냐하면 인터페이스의 멤버는 무조건 public이기 때문이다.
 
 4) abstract vs interface
 인터페이스와 추상 클래스는 서로 비슷한 듯 다른 기능이다. 인터페이스는 클래스가 아닌 인터페이스라는 고유한 형태를 가지고 있는 반면 추상 클래스는 일반적인 클래스다. 또 인터페이스는 구체적인 로직이나 상태를 가지고 있을 수 없고, 추상 클래스는 구체적인 로직이나 상태를 가지고 있을 수 있다.
profile
꿈을 이루는 사람

0개의 댓글