인터페이스

jisoo·2022년 7월 13일
0

추상화

목록 보기
2/2

인터페이스란? 🧐

일종의 추상클래스로이며, 추상클래스처럼 완성되지 않은 불완전한 것이기 때문에 그 자체만으로 사용되기보다는 다른 클래스를 작성하는데 도움 줄 목적으로 작성된다.

  • 추상 클래스처럼 자바에서 추상화를 구현하는 데 활용된다는 점에서 동일하지만, 추상 클래스에 비해 더 높은 추상성을 가진다.

  • 기본적으로 추상 메서드와 상수만을 멤버로 가질 수 있다.

    • 인터페이스 추상메서드의 집합으로 이뤄져있다.
  • 여러 하위 클래스가 동일한 구현으로 로직을 수행하면서, 그 중 일부 로직의 구현이 다를 때 추상 클래스를 고민한다.

    • 여러 하위 타입이 존재하는 경우 가능하면 최상위 타입은 인터페이스로 만드는것을 선호한다.




인터페이스의 기본 구조 & 구현


public interface InterfaceEx {
    public static final int rock =  1; // 인터페이스 인스턴스 변수 정의
    final int scissors = 2; // public static 생략
    static int paper = 3; // public & final 생략

    public abstract String getPlayingNum();
		void call() //public abstract 생략 
}

class 클래스명 implements 인터페이스명 {
	... // 인터페이스에 정의된 모든 추상메서드 구현
}
  • class 키워드 대신 interface 키워드를 사용한다.

  • 내부의 모든 필드가 public static final 로 정의 되고 static과 default 메서드 이외의 모든 메서드가 public abstract 로 정의 된다.(일부분 또는 전부 생략이 가능하다.)

  • 인터페이스를 구현할 경우 implements 키워드를 사용한다.

  • 인터페이스를 구현한다는 것은 그 인터페이스가 가진 모든 추상 메서드들을 해당 클래스 내에서 오버라이딩하여 바디를 완성한다.

  • 인터페이스는 다중 구현이 가능하다.






인터페이스의 장점

  • 일반적인 인터페이스의 기능처럼 역할과 구현을 분리시켜 사용자 입장에서 복잡한 구현의 내용 또는 변경과 상관없이 해당 기능을 사용할 수 있다.

    • 기능이 가지는 역활과 구현을 분리시켜 사용자로 하여금 복잡한 기능의 구현이나 교체/변경을 신경쓰지 않고도 코드 변경의 번거로움을 최소화하고 손쉽게 해당 기능을 사용할 수 있도록 한다.
  • 기능을 구현하는 개발자의 입장에서도 선언과 구현을 분리시켜 개발시간을 단추하고, 독립적인 프로그래밍을 통해 한 클래스의 변경이 다른 클래스에 미치는 영향을 최소화 할 수 있다는 장점이 있다.


사용 전

public class InterfaceExample {
    public static void main(String[] args) {
        User user = new User(); // User 클래스 객체 생성
        user.callProvider(new Provider()); // Provider객체 생성 후에 매개변수로 전달
    }
}

class User { // User 클래스
    public void callProvider(Provider provider) { // Provider 객체를 매개변수로 받는 callProvider 메서드
        provider.call();						// Provider2를 매개변수로 바꿔주고 싶을 경우 Provider 로 바꿔주어야한다.
    }
}


class Provider { //Provider 클래스
    public void call() {
        System.out.println("무야호~");
    }
}

class Provider2 { //Provider 클래스
    public void call() {
        System.out.println("야호~");
    }
}

// 출력값
야호~
  • Provider 클래스에 의존하고 있기 때문에 Provider2를 의존하고 싶을 경우 User 클래스의 코드 변경이 불가피하다.


사용 후

interface Cover { // 인터페이스 정의
    public abstract void call();
}

public class Interface4 {
    public static void main(String[] args) {
        User2 user2 = new User2();
//        Provider provider = new Provider();
//        user.callProvider(new Provider());
        user.callProvider(new Provider2());
    }
}

class User {
    public void callProvider(Cover cover) { // 매개변수의 다형성 활용
        cover.call();
    }
}

class Provider implements Cover {
    public void call() {
        System.out.println("무야호~");
    }
}

class Provider2 implements Cover {
    public void call() {
        System.out.println("야호~");
    }
}

//출력값
야호~
  • User 클래스에서는 매개변수의 다형성을 활용하여 구체적인 구현체가 아닌 인터페이스를 매개변수로 받도록 정의하였다.
    • 이에따라 이제 Provider 클래스의 내용 변경 또는 교체가 발생하더라도 User 클래스는 더이상 코드를 변경해주지 않아도 같은 결과를 출력해낼 수 있다.
  • 인터페이스를 사용하여 역할과 구현을 분리시켜 주면 코드를 일일이 변경해주어야 할 필요도 없어진다.
profile
Backend Developer 👩🏻‍💻

0개의 댓글