[Java] 인터페이스 이해하기

김예원·2022년 12월 12일
0

자바 기초 이론

목록 보기
5/7

인터페이스

인터페이스란(interface) ?

인터페이스란 다른 클래스를 작성하는데 도움 줄 목적으로 작성되는 일종의 추상 클래스를 의미한다.
인터페이스는 오로지 추상메서드와 상수만 멤버변수로 가질 수 있다.

  • 인터페이스가 추상클래스와 다른 점은 자바에서 추상클래스는 추상 메서드 뿐만 아니라 생성자, 필드, 일반 메서드도 포함할 수 있다.



인터페이스를 선언하는 방법은 클래스와 똑같다. 접근제어자와 함께 interface 키워드만 사용하면 된다.

접근제어자 interface 인터페이스 이름 {
    
    public static final 타입 상수이름 =;  // → 타입 상수이름 = 값;
    ...
    public abstract 메서드이름(매개변수들);  // → void 메서드이름(매개변수들);
}
- 인터페이스의 모든 멤버변수는 public stactic final 이어야 하며, 생략 가능하다.
- 모든 메서드는 public abstract 이어야 하며, 생략 가능하다.

인터페이스의 제어자는 모든 인터페이스에 공통으로 적용되기 때문에 컴파일 시 자바 컴파일러가 자동으로 추가해주기 때문에 생략 가능하다.



인터페이스의 구현

인터페이스는 추상클래스와 마찬가지로 자신이 직접 인스턴스를 생성할 수 없다.
따라서 상속받은 클래스가 인터페이스가 포함하고 있는 추상 메서드를 모두 오버라이딩하여 재구현해야한다.
인터페이스를 상속받을 때는 구현을 뜻하는 implements를 사용한다.

interface Animal { public abstract void cry(); }

class Cat implements Animal {

    public void cry() {
        System.out.println("애옹");
    }
}


public class JavaChapter {

    public static void main(String[] args) {
        Cat cat = new Cat();

        cat.cry();
    }
}
실행결과

애옹

만약 모든 추상 메서드를 구현하지 않는다면 abstract 키워드를 사용하여 추상클래스로 선언해야 한다.

interface Animal { public abstract void cry(); }

abstract class Cat implements Animal { }

자바는 클래스를 이용해서 다중 상속을 하게 될 때 생기는 메서드 호출의 모호성 때문에 다중 상속을 지원하지 않는다.
인터페이스를 사용하면 다중 상속이 가능하지만 많이 쓰이지는 않는다.



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

자식 클래스의 인스턴스를 조상타입의 참조변수로 참조하는 것이 가능하다. (다형성)

인터페이스는 이를 구현한 클래스의 조상이라 할 수 있으므로 해당 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며,
인터페이스 타입으로의 형변환도 가능하다.

fightable f = new Fighter();
fightable f = (Fightable) new Fighter(); //인터페이스 타입으로 형변환

메서드의 리턴타입으로 인터페이스의 타입을 지정할 수도 있다.

리턴타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 말이다.

아래와 같이 getParser() 메서드가 Parseable 인터페이스를 리턴타입으로 갖을 때,

HTMLParser 클래스의 인스턴스를 반환한다는 뜻이다.

이해가 잘 안되면 여러번 보면 된다. 왜냐면 저도 많이 여러번 보거든요,,

// 인터페이스
interface Parseable {
    public abstract void parse(String fileName);
}


class ParserManager {
    public static Parseable getParser(String type) {
        if (type.equals("XML")) {
            return new XMLParser();
        } else {
            Parseable p = new HTMLParser();
            return p;
        }
    }
}

// 인스턴스를 구현한 클래스 XMLParser
class XMLParser implements Parseable {
    public void parse(String fileName) {
        System.out.println(fileName + "xml 완성");
    }
}

// 인스턴스를 구현한 클래스 HTMLParser
class HTMLParser implements Parseable {
    public void parse(String fileName) {
        System.out.println(fileName + "html 완성");
    }
}

public class JavaChapter {

    public static void main(String[] args) {
        Parseable parseable = ParserManager.getParser("HTML");
        parseable.parse("test.html");

    }
}

++

인터페이스를 리턴타입으로 갖을 때 좋은 점이 뭘까 ?

  • 한 클래스가 다중구현을 했을 경우
interface Call {
    void BasicCall();
}
interface Game {
    void BasicGame();
}

class SmartPhone implements Call, Game {

    @Override
    public void BasicCall() {
        System.out.println("전화만 가능합니다 🙏");
    }

    @Override
    public void BasicGame() {
        System.out.println("게임만 가능합니다 😇");
    }
}

public class JavaChapter {
    public static void main(String[] args) {
        Call smartPhone = new SmartPhone();
        smartPhone.BasicCall();
    }
}
전화만 가능합니다 🙏

리턴 타입으로 설정한 인터페이스에 해당하는 구현 메서드만 접근이 가능하며, 구현된 다른 메서드가 잘못 사용될 걱정없이 사용할 수 있다.

  • 여러 클래스가 한 인터페이스를 구현할 경우
interface Swimable {
    void level();
}

class Beginner implements Swimable {

    @Override
    public void level() {
        System.out.println("배영 가능");
    }

    public void job() {
        System.out.println("나 같은 백수");
    }
}

class Intermediate implements Swimable {

    @Override
    public void level() {
        System.out.println("배영가능, 평형가능");
    }
    
    public void age() {
        System.out.println("3세");
    }
}

class Senior implements Swimable {

    @Override
    public void level() {
        System.out.println("배영가능, 평형가능, 접영 잠수 다 가능");
    }
}

public class JavaChapter {
    public static void main(String[] args) {
        Swimable level = new Beginner();
        level.level();
    }
}
배영 가능

각각 인터페이스에 해당하는 구현 메서드만 접근할 수 있고 상황에 따라 필요한 내용의 인스턴스를 골라서 사용할 수 있다.

즉 내가 백수인 것은 실수로라도 노출될 일이 없고 각 수영 실력에 따라 인스턴스를 골라서 사용할 수 있다는 뜻이다.



인터페이스의 장점

- 개발시간을 단축시킬 수 있다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다. 
- 독립적인 프로그래밍이 가능하다.
profile
기억력이 짧은 나를 위한 기록 🍀

0개의 댓글