나를 기록하다
article thumbnail
Published 2023. 6. 19. 10:15
[TIL-4 / 230618] Java - 인터페이스 TIL
반응형

인터페이스(Interface)

  1. 기능: 추상 메서드들의 집합. 인터페이스를 사용하기 위해서는 추상메서드의 집합인 인터페이스를 구현하는 클래스가 존재하여야 한다.
  2. 상속: 클래스와 달리 인터페이스는 다중상속을 허용 → 이유: 클래스는 복잡하지만 상대적으로 인터페이스는 단순한 추상메서드들의 집합
  3. 구현: 인터페이스들을 구현하는 클래스 입장에서는 인터페이스의 계층 구조를 따져서 그 인터페이스의 모든 부모 인터페이스에 존재하는 추상 메서드까지 클래스가 다 구현을 해주어야 한다. 하나의 인터페이스는 여러 인터페이스를 구현할 수 있다.
  4. 결론: 인터페이스를 구현하는 클래스는 자신이 구현하는 모든 인터페이스, 그리고 그 인터페이스의 부모 인터페이스까지 다 따져서 그 전체에 포함된 모든 추상 메서드를 다 오버라이딩해서 구현해주어야 한다.
  5. 구성: 인터페이스가 추상메서드와 상수를 가질 수 있다. (JDK 1.8 이후) default 메서드 + static 메서드도 가질 수 있다.
  6. 목적: 인터페이스는 인스턴스를 생성할 수 없고, 클래스 작성에 도움을 줄 목적으로 사용
  7. 용도: 정해진 규칙에 맞게 구현하도록 표준을 제시하는 데 사용

인터페이스의 작성

‘class’ 대신 ‘interface’를 사용한다는 것 외에는 클래스 작성과 동일

interface 인터페이스 이름 {
			public static final 타입 상수이름 = 값;
			public abstract 메서드이름(매개변수목록);
}

규칙

  1. 인터페이스는 static 필드가 존재하지 않는다. 선언과 동시에 초기화 하여야 한다.
  2. 인터페이스의 모든 멤버는 public이다.
  3. 모든 상수는 public static final이고 생략 가능
  4. 모든 메서드는 public abstract이고 생략 가능

인터페이스의 상속

  1. 인터페이스도 클래스처럼 상속이 가능(클래스와 달리 다중상속 허용)
  2. 인터페이스는 Object 클래스와 같은 최고 조상이 없다.

인터페이스의 구현

  1. 인터페이스를 구현하는 것은 클래스를 상속받는 것과 같다. 다만 ‘extends’ 대신 ‘implements’를 사용한다.
  2. 인터페이스를 구현하는 클래스는 자신이 구현하는 모든 인터페이스, 그리고 그 인터페이스의 부모 인터페이스까지 다 따져서 그 전체에 포함된 모든 추상 메서드를 다 오버라이딩해서 구현해주어야 한다.
  3. 상속과 구현이 동시에 가능하다. (extends와 implements를 함께 사용할 수 있다.)

인터페이스를 이용한 다형성

1. 인터페이스 타입의 변수로 인터페이스를 구현한 클래스의 인스턴스를 참조할 수 있다.

2. 인터페이스 타입의 레퍼런스 - 이미 완성된 타입의 프로그램을 외부에서 사용하기 위해서 부모 클래스 - 자식 클래스를 제어하기 위해서 → 각각의 상황에 맞게끔 사용할 것

3. 참조형 변수 레퍼런스를 만들 때 사용하는 타입의 종류
     1)배열 2) 클래스 3) 인터페이스 4) enum
4. 인터페이스를 메서드의 매개변수 타입으로 지정 가능

void attack(Fightable f) {
			// ...
}

5. 인터페이스를 메서드의 리턴타입으로 지정 가능

Fightable method() {
			// ...
			return new Fighter();
}

 

인터페이스의 장점

  1. (인터페이스가 제공이 된다면) 개발시간을 단축시킬 수 있다. 단, 인터페이스를 만드는 데 걸리는 시간도 생각해야 한다.
  2. 표준화가 가능하다.
  3. 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
  4. 독립적인 프로그래밍이 가능하다.

인터페이스의 장점 - 예제

비어있는 인터페이스 자주 사용

public interface Repairable {}

이유: 비어있는 인터페이스를 구현하는 클래스들은 수리가능한 유닛이 됨.

인터페이스의 이해

  1. 인터페이스는 두 대상(객체) 간의 ‘연결, 대화, 소통’을 돕는 ‘중간 역할’을 한다.
  2. 선언(설계)와 구현을 분리시키는 것을 가능하게 한다.
  3. 인터페이스를 이해하려면?
    1. 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provider)이 있다.
    2. 메서드는 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 된다.

디폴트 메서드

구현부를 가지는 메서드.

인터페이스에 디폴트 메서드, static 메서드를 추가 가능

  • 디폴트 메서드가 기존의 메서드와 충돌하는 경우 해결방법
    1. 여러 인터페이스의 디폴트 메서드 간의 충돌
    2. → 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.
    3. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
    4. → 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.

 

인터페이스 사용 예제

로또 번호 생성

package chap07;

public class MyLotto {

    private int[] lotto;

    public MyLotto() {
        this.lotto = new int[6];
        this.setLotto();
        this.sortLotto();
    }

    // 로또 번호 중복 검사 메서드
    boolean isUnique(int num) {
        boolean result = true;

        for (int i = 0 ; i < this.lotto.length ; i++) {
            if (this.lotto[i] == num) {
                result = false;
                break;
            }
        }
        // enhanced for문
//        for (int lottoNum : this.lotto) {
//            if (lottoNum == num) {
//                result = false;
//                break;
//            }
//        }
        return result;
    }

    // 로또 배열 초기화 메서드
    void setLotto() {
        int temp;
        for (int i = 0 ; i < this.lotto.length ; ) {
            // 증감 연산자를 안넣는 이유 - 증감연산자를 넣으면 6번만 반복
            // 중복이 발생하지 않는 로또 번호를 만들었을 때, 1을 증가시킴
            while (true) {
                temp = (int) (Math.random() * 45) + 1;

                if (this.isUnique(temp)) {
                    lotto[i] = temp;
                    i++;
                    break;
                }
            }
        }
    }

    // 선택 정렬
    void sortLotto() {
        int temp;

        for (int i = 0 ; i < this.lotto.length - 1 ; i++) {
            for (int j = i + 1 ; j < this.lotto.length ; j++) {
                if (lotto[i] > lotto[j]) {
                    temp = lotto[i];
                    lotto[i] = lotto[j];
                    lotto[j] = temp;
                }
            }
        }
    }

    int[] getLotto() {
        return this.lotto;
    }

    public String toString() {
        String result = "";
        for (int num : lotto) {
            result += num + "  ";
        }
        return result;
    }
}

실행 예제

package chap07;

public class Exam2_ans {
    public static void main(String[] args) {
        MyLotto lotto = new MyLotto();
        System.out.print("\t [ 로또 추첨 프로그램 ]\n\t\t로또 추천 번호\n" +
                         "\t =================\n\t");
        System.out.println(lotto);
    }
}

 

반응형
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...