새소식

java

Interface

  • -

-

A라고 생긴 콘센트와 플러그는 220v를 사용한다는 매우 간결하며 강력한 약속

 

인터페이스란 클래스의 형태를 규정하는 것 (+ 인터페이스 작성시 대문자로 시작하고 형용사를 사용한다.) 

즉, 객체를 어떻게 구성해야 하는지 정리한 설계도이며

그 역할로는

1. 객체의 교환성(또는 다형성)을 높여주며,

2. 인터페이스 변수에 인터페이스가 구현된 서로 다른 구현 객체를 할당해서 사용이 가능하고,

3. 객체가 인터페이스를 사용하면, 인터페이스 메서드를 반드시 구현해야 하는 제약을 한다

 

 

" 자식 클래스가 여러 부모 클래스를 상속받을 수 있다면, 다양한 동작을 수행할 수 있다는 장점을 가지게 될 것입니다.

하지만 클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러 가지 문제가 발생할 수 있어 자바에서는 클래스를 통한 다중 상속은 지원하지 않습니다.

하지만 다중 상속의 이점을 버릴 수는 없기에 자바에서는 인터페이스라는 것을 통해 다중 상속을 지원하고 있습니다.

인터페이스(interface)란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미합니다. " - tcp school 인터페이스 개념

 

 

인터페이스의 역할, 출처: https://interconnection.tistory.com/129

 

  • 하나의 클래스는 여러개의 인터페이스를 구현할 수 있다.
  • 인터페이스에는 상수와 추상메서드만을 사용가능 하다.

 

interface Calculable{
    double PI = 3.14;
    int sum(int v1, int v2);
}
interface Printable{
    void print();
}
class RealCal implements Calculable, Printable{
    public int sum(int v1, int v2) {
        return v1+v2;
    }
    public void print() {
        System.out.println("This is RealCal!!");
    }
}
class AdvancedPrint implements Printable{
    public void print() {
        System.out.println("This is RealCal!!");
    }
}
public class InterfaceApp {
    public static void main(String[] args) {
        Printable c = new AdvancedPrint(); 
        // new 우측에는 똑같은 인터페이스를 지정하는 클래스라면 어떤것이든지 가능(호환성(다형성) 보장)
        // 어떠한 클래스가 데이터 타입을 무엇으로 하는지에 따라 다양한 모양이 가능함
        c.print();
        // c는 print()에는 접근 가능하지만, Calculable의 PI와 sum에는 접근 불가능하다.
    }
}

 

 

인터페이스의 개념은 이해했지만, 언제 사용할 지 모를 때??

클래스의 기능이 너무 많아서 클래스의 기능을 구획화하고 선택적으로 사용자에게 제공하고 싶을 때

또는 협업할 때 의뢰하고 싶은 기능을 명확히 하거나

여러가지 목적의 클래스가 있을 때 그 클래스들이 공통적으로 가져야 할 변수나 메소드들이 있을 때

인터페이스를 사용해서 이러한 목적들을 이룰 수 있다.

 

// 인터페이스로 변경 위한 코드

class Animal {
    String name;

    void setName(String name) {
        this.name = name;
    }
}

class Tiger extends Animal {
}

class Lion extends Animal {
}

class ZooKeeper {
    void feed(Tiger tiger) {  // 호랑이가 오면 사과를 던져 준다.
        System.out.println("feed apple");
    }

    void feed(Lion lion) {  // 사자가 오면 바나나를 던져준다.
        System.out.println("feed banana");
    }
}

public class Sample {
    public static void main(String[] args) {
        ZooKeeper zooKeeper = new ZooKeeper();
        Tiger tiger = new Tiger();
        Lion lion = new Lion();
        zooKeeper.feed(tiger);  // feed apple 출력
        zooKeeper.feed(lion);  // feed banana 출력
    }
}

 

 

interface Predator {
    String getFood(); // 무조건 "feed apple" 이라는 문자열을 출력하는 문제를 해결하기 위함
}
}

class Animal {
    String name;

    void setName(String name) {
        this.name = name;
    }
}


class Tiger extends Animal implements Predator {
// 인터페이스의 메서드는 항상 public으로 구현해야 함
	public String getFood() {
        return "apple";
    }
}
}

class Lion extends Animal implements Predator {
// 인터페이스의 메서드는 항상 public으로 구현해야 함
	public String getFood() {
        return "banana";
    }
}

//class ZooKeeper {
//   void feed(Predator predator) {
//        System.out.println("feed apple");
//    }
//}
// ZooKeeper클래스의 feed 메서드를 보면 호랑이가 오던지, 사자가 오던지 무조건 "feed apple" 이라는 문자열을 출력한다.
// 사자가 오면 "feed banana" 를 출력해야 함


class ZooKeeper {
    void feed(Predator predator) {
        System.out.println("feed "+predator.getFood());
    }
}
// ZooKeeper 클래스는 위와 같이 작성해야 함

 

 

@1

자바8 버전 이후부터는 디폴트 메서드(default method)를 사용할 수 있다.

인터페이스의 메서드는 몸통(구현체)을 가질 수 없지만 디폴트 메서드를 사용하면 실제 구현된 형태의 메서드를 가질 수 있다.

// 예를들어 Predator 인터페이스에 다음과 같은 디폴트 메서드를 추가
interface Predator {
    String getFood();

    default void printFood() {
        System.out.printf("my food is %s\n", getFood());
    }
}

// 디폴트 메서드는 메서드명 가장 앞에 "default" 라고 표기
// Predator 인터페이스에 printFood 디폴트 메서드를 구현하면 Predator 인터페이스를 구현한 Tiger, Lion 등의 실제 클래스는 printFood 메서드를 구현하지 않아도 사용할 수 있다.
// 디폴트 메서드는 오버라이딩이 가능하다. 
// 즉, printFood 메서드를 실제 클래스에서 다르게 구현하여 사용할수 있다.

 

 

@2

자바8 버전 이후부터는 인터페이스에 스태틱 메서드(static method)를 사용할 수 있다. 

인터페이스에 스태틱 메서드를 구현하면 인터페이스명.스태틱메서드명 과 같이 사용하여 일반 클래스의 스태틱 메서드를 사용하는 것과 동일하게 사용할 수 있다.

interface Predator {
    String getFood();

    default void printFood() {
        System.out.printf("my food is %s\n", getFood());
    }

    int LEG_COUNT = 4;  // 인터페이스 상수

    static int speed() {
        return LEG_COUNT * 30;
    }
}

// Predator.speed(); 이렇게 사용이 가능함.
// 인터페이스에 정의한 상수는 int LEG_COUNT=4; 처럼 public static final을 생략해도 자동으로 public static final이 적용됨

 

참고: https://wikidocs.net/217

 

05-07 인터페이스

인터페이스(Interface)는 초보 개발자를 괴롭히는 단골손님이다. 인터페이스에 대한 개념없이 코드로만 이해하려고 하면 곧 미궁에 빠지게 된다. 이렇게 이해하기 힘든 인터페이스…

wikidocs.net

 

'java' 카테고리의 다른 글

추상 클래스(abstract class)  (0) 2023.01.09
입출력  (0) 2023.01.08
접근 제어자(access level modifier)  (0) 2023.01.08
상속  (0) 2023.01.08
생성자와 this (기초개념)  (0) 2023.01.08
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.