코딩하는 털보

STUDY HALLE - 8주차 본문

Diary/Study Halle

STUDY HALLE - 8주차

이정인 2021. 1. 9. 02:11

STUDY HALLE

8주차 : 인터페이스


목표

자바의 인터페이스에 대해 학습하세요.

학습할 것

  • 인터페이스 정의하는 방법
  • 인터페이스 구현하는 방법
  • 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
  • 인터페이스 상속
  • 인터페이스의 기본 메소드 (Default Method), 자바 8
  • 인터페이스의 static 메소드, 자바 8
  • 인터페이스의 private 메소드, 자바 9

인터페이스 정의하는 방법

인터페이스(interface)는 클래스들이 구현해야 하는 추상메소드를 지정해 놓는데 사용되는 추상 자료형이다.

인터페이스는 interface라는 키워드를 사용하여 선언하며, 메소드 시그니처(메소드의 이름과 매개변수 리스트)와 상수 선언(static과 final이 둘 다 선언되는 변수 선언)만을 포함할 수 있다.

  • 자바 8 미만의 버전에서의 인터페이스의 모든 메소드는 구현부가 없다.
  • 자바 8부터, defaultstatic 메소드는 구현부를 가지고 있을 수 있다.
  • 자바 9부터, private 메소드까지 구현부를 가지고 있을 수 있다.

인터페이스 정의하기

[접근지시자] interface InterfaceName [extends other interfaces] {
        ...
}

인터페이스의 요소

  • 추상 메소드

    • 정의상 인터페이스 안의 모든 메서드들은 추상적이기 때문에 abstract 키워드는 생략한다.
    • 암묵적으로 public 접근지시자의 속성을 가진다.
  • 상수 : 인터페이스는 인스턴스로 생성할 수 없기때문에 모든 변수는 상수이다.

  • static 메소드 (자바8)

    • 인터페이스 내에서도 구현이 필요한 메소드. 다른 인터페이스나 인터페이스를 구현하는 클래스에 상속되지 않는다.
  • 기본 메소드 (자바8)

    • 인터페이스 내에서도 구현이 필요한 메소드. 다른 인터페이스나 인터페이스를 구현하는 클래스에 상속된다.
  • private 메소드 (자바9)

    • 인터페이스 내에서도 구현이 필요한 메소드. 다른 인터페이스나 인터페이스를 구현하는 클래스에 상속되지 않는다.
    • 외부에서 접근할 수 없다.

참조

위키백과 인터페이스 (자바)


인터페이스 구현하는 방법

인터페이스 구현하기

인터페이스를 구현할 클래스에서 다음 구문을 사용한다.

class ClassName implements InterfaceName[, another interface, another, ...] {
    ...
}
public interface MyInterface {
    void show(String string);
    void sum(int num1, int num2);
}
public class MyClass implements MyInterface{
    @Override
    public void show(String string) {
        ...
    }

    @Override
    public void sum(int num1, int num2) {
        ...
    }
}

만약 구현 클래스에서 인터페이스에 정의된 메소드를 모두 구현하지 않는다면, abstract class 가 되어야 한다.

public abstract class MyClass implements MyInterface{
}

이 메소드를 구현하기 전까지 상속받는 모든 클래스는 abstract이다.

동시에 여러 인터페이스를 구현할 수도 있다.

public interface MyInterface2 {
    void show();
    void max(int num1, int num2);
}
public class MyClass implements MyInterface, MyInterface2{
    @Override
    public void show(String string) {
                ...
    }

    @Override
    public void sum(int num1, int num2) {
                ...
    }

    @Override
    public void show() {
                ...
    }

    @Override
    public void max(int num1, int num2) {
                ...
    }
}

참조

위키백과 인터페이스 (자바)


인터페이스 레퍼런스를 통해 구현체를 사용하는 방법

클래스 타입 처럼 인터페이스 타입으로 참조변수를 선언할 수 있다.

  • 이 참조변수에는 인터페이스를 구현한 클래스 타입의 객체가 대입되며, 인터페이스의 메소드를 호출하면 객체의 타입이 되는 클래스에서 구현한 메소드가 사용된다. 즉, 어떤 객체를 사용하느냐에 따라 메소드가 다르게 동작한다.

  • 동시에 여러 인터페이스를 구현한 클래스 타입의 객체가 대입되면 참조변수의 타입이 되는 인터페이스에 정의된 메소드만 사용할 수 있다.

public class MyClass implements MyInterface, MyInterface2{
    @Override
    public void show(String string) {
        System.out.println("show method");
    }

    @Override
    public void sum(int num1, int num2) {
        System.out.println("sum method");
    }

    @Override
    public void show() {
        System.out.println("non param show method");
    }

    @Override
    public void max(int num1, int num2) {
        System.out.println("max method");
    }
}
class MyClassTest {

    @Test
    public void test() {
        MyInterface ref1 = new MyClass();
        MyInterface2 ref2 = new MyClass();

        //ref1 레퍼런스에서는 show(String string)와 sum(int num1, int num2) 메소드만 사용할 수 있다.
        ref1.show("test");
        ref1.sum(1,2);
        //ref2 레퍼런스에서는 show()와 max(int num1, int num2) 메소드만 사용할 수 있다.
        ref2.show();
        ref2.max(1,2);

          //구현 클래스 타입으로 다운캐스팅(MyInterface -> MyClass)하여 구현 클래스 타입의 참조변수에 대입할 수도 있다.
        MyClass myClass = (MyClass) ref1;
        myClass.max(1,2);
    }
}

인터페이스 상속

인터페이스 간에 상속을 받을 수 있다.

클래스 상속처럼 extends 키워드를 사용한다.

public interface MyInterface {
    void show(String string);
    void sum(int num1, int num2);
}
public interface MyInterfaceSec extends MyInterface{
    void sub(int num1, int num2);
}

상속받은 인터페이스를 구현할 때 상위 인터페이스의 추상 메소드까지 구현해야 한다.

public class MyClass implements MyInterfaceSec{
    @Override
    public void show(String string) {

    }

    @Override
    public void sum(int num1, int num2) {

    }

    @Override
    public void sub(int num1, int num2) {

    }
}

인터페이스는 클래스와 다르게 여러 인터페이스를 동시에 상속받을 수 있다.

interface InterfaceName extends InterfaceName[, another interface, another, ...] {
    ...
}
public interface MyInterface2 {
    void show();
    void max(int num1, int num2);
}
public interface MyInterfaceSec extends MyInterface, MyInterface2{
}

인터페이스의 기본 메소드 (Default Method), 자바 8

구현하는 클래스에서 구현하지 않더라도 사용할 수 있도록 인터페이스에서 미리 구현하는 메소드이다.

  • 구현 클래스의 인스턴스를 생성하지 않으면 사용할 수 없다.
  • 구현 클래스 또는 하위 인터페이스에 상속된다.
  • 상속되기 때문에 구현 클래스에서 재정의 할 수 있다.
public interface MyInterface {
    void show(String string);
    void sum(int num1, int num2);

    default void defaultMethod() {
        System.out.println("default method");
    }
}
class MyClassTest {

    @Test
    public void test() {
        //인스턴스를 생성해야 호출할 수 있다.
        MyInterface myInterface = new MyClass(); 
        myInterface.defaultMethod();
    }
}

구현 클래스에서 기본 메소드 재정의하기

public class MyClass implements MyInterface, MyInterface2{
    @Override
    public void show(String string) {
        System.out.println("show method");
    }

    @Override
    public void sum(int num1, int num2) {
        System.out.println("sum method");
    }

    //기본 메소드 재정의
    @Override
    public void defaultMethod() {
        System.out.println("override default method");
    }
}

인터페이스의 static 메소드, 자바 8

구현하는 클래스에서 구현하지 않더라도 사용할 수 있도록 인터페이스에서 미리 구현하는 메소드이다.

  • 구현 클래스의 인스턴스를 생성하지 않더라도 사용할 수 있다.
  • 구현 클래스 또는 하위 인터페이스에 상속되지 않는다.
  • 상속되지 않기 때문에 구현 클래스에서 재정의 할 수 없다.
public interface MyInterface {
    void show(String string);
    void sum(int num1, int num2);

    static void staticMethod() {
        System.out.println("static method");
    }
}
class MyClassTest {

    @Test
    public void test() {
        //인스턴스를 생성하지 않아도 바로 호출할 수 있다.
        MyInterface.defaultMethod();
    }
}

인터페이스의 private 메소드, 자바 9

인터페이스에서 미리 구현하는 메소드이며, 특별히 인터페이스 내부에서만 기능하도록 구현하는 메소드이다.

  • 구현 클래스 또는 하위 인터페이스에 상속되지 않는다.
  • 상속되지 않기 때문에 구현 클래스에서 재정의 할 수 없다.
  • 외부에서 접근할 수 없으며 구현 클래스의 인스턴스를 생성하더라도 사용할 수 없다.
public interface MyInterface {
    void show(String string);
    void sum(int num1, int num2);

    private void privateMethod() {
        System.out.println("private method");
    }
}
class MyClassTest {

    @Test
    public void test() {
        MyInterface myInterface = new MyClass();

        //인스턴스를 생성하더라도 사용할 수 없고 컴파일 에러가 발생한다.
        myInterface.privateMethod();
    }
}
Comments