- 백기선-JAVA STUDY/WEEK82021년 01월 29일 19시 28분 08초에 업로드 된 글입니다.작성자: jCurve728x90반응형
목표
자바의 인터페이스에 대해 학습하세요.
학습할 것 (필수)
- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스의 기본 메소드 (Default Method), 자바 8
- 인터페이스의 static 메소드, 자바 8
- 인터페이스의 private 메소드, 자바 9
인터페이스
자바에서 클래스는 단일 상속만 가능하기 때문에 제약이 생길 수 있는데 이러한 연유로 인터페이스를 도입했습니다.
인터페이스는 메소드는 정의하지만 구현은 하지 않고 클래스에서 담당합니다.
인터페이스 정의하는 방법
인터페이스는 interface 예약어를 통해 선언되며 접근 제어자로 public과 default를 사용합니다.
인터페이스는 중첩이 가능하며 인스턴스를 만들 수 없기 때문에 생성자는 존재하지 않습니다.
(인스턴스 변수는 가능하다는 소리)
상수를 선언할 경우 public static final로 선언이 되며 생략이 가능하다.
메서드 또한 따로 명시하지 않았다면 public abstract가 생략되어있는 것
public interface MyInterface{ int getNumber(); }
인터페이스는 추상 메서드를 제공하고 해당 메서드를 클래스에서 구현하는 형태이지만
자바 8부터는 static,default메서드를 자바 9부터는 private메서드를 정의할 수 있습니다.
인터페이스를 구현하는 방법
위에서 선언한 인터페이스를 클래스에서 implements 키워드를 통해 받아서 구현할 수 있습니다. (예시에서는 하나지만 인터페이스는 여러개를 implements 가능합니다)
개발 코드가 인터페이스 메소드를 호출하면 인터페이스는 객체의 메서드를 호출한다.
객체는 인터페이스에서 정의된 추상 메서드와 동일한 메서드 이름, 매개 타입, 리턴타입을 가진 메서드를 포함하여야하며 , 이러한 객체를 인터페이스의 구현 객체라고 하며 , 구현 객체를 생성하는 클래스를 구현 클래스라 한다.
구현 클래스
public class Real implements MyInterface{ @override public int getNumber(){ return 5; } public int getNewNumber(){ return 10; } }
익명 구현 객체
구현 클래스를 만들어서 사용하면 재사용이 가능하여 편리하지만, 한 번만 사용하는 구현객체의 경우 구현 클래스를 만들지 않고 만드는 익명 구현 객체를 사용하는 것이 효율적이다.
public class Real{ MyInterface myInterface = new MyInterface(){ @Override public int getNumber(){ } }; }
위와 같이 인터페이스 변수를 만들고 추상 메서드의 실체를 구현해서 익명의 구현객체를 사용할 수 있다.
인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
MyInterface otherReal = new Real(); System.out.println(otherReal.getNumber()); //5
해당 인터페이스를 구현한 구현 클래스라면 위와 같이 사용하는 것이 가능하며 구현 객체가 인터페이스 타입으로 자동 타입 변환하며, 인터페이스에 선언된 메서드만 사용가능하다는 제약 사항이 따른다.
하지만 경웨 따라 구현 클래스에 선언된 필드와 메서드를 사용해야 할 경우가 발생하는데 이럴 경우 위에서 인터페이스 타입으로 자동 타입 변환된 것을 다시 강제 타입 변환을 해서 구현 클래스 타입으로 변환한 다음 구현 클래스의 필드와 메서드를 사용하면 된다.
otherReal.getNewNumber()// MyInterface에는 해당 메서드가 없다. Real real = (Real) otherReal; // 구현 클래스의 메서드를 사용하기 위해 강제 타입 변환 Sytstem.out.println(rea.getNewNumber()); // 10
인터페이스 상속
인터페이스의 상속 구조는 서브 인터페이스가 수퍼 인터페이스의 메서드까지 모두 구현해야한다.
인터페이스 레퍼런스는 인터페이스를 구현한 클래스의 인스턴스를 가리킬 수 있고, 해당 인터페이스에 선언된 메서드만 호출 가능하다.
public interface ParentInterface { void find(); } public interface ChildeInterface extends ParentInterface{ void check(); } public class Real implements ChildeInterface { @Override public void find(){ System.out.println("parent interace"); } @Override public void chekc(){ System.out.println("child interface"); } }
자바 8 부터 생긴 default 메서드는 인터페이스 상속시 3가지 방법으로 사용될 수 있다.
- default 메서드를 단순 상속
- default 메서드를 재정의
- default 메서드를 추상 메서드로 재선언
default 메서드는 밑에서 더 자세히 다루겠다.
public class Real implements Interface1 Interface2 Interface3{ }//인터페이스는 다중 상속 가능
인터페이스의 기본 메서드 default / JAVA 8
default 메서드는 인터페이스에 메서드 선언이 아니라 "구현체"를 제공하는 방법이다.
해당 인터페이스의 구현 클래스의 영향을 주지 않고 새로운 기능을 추가하는 방법이나
그에따른 리스크가 존재한다.
→ 컴파일 에러는 발생하지 않지만, 특정한 구현체의 로직에 따라 런타임 에러가 발생할 수 있다. (사용시 구현체에서 잘 못 사용하지 않도록 문서화를 해야한다. )
→Object가 제공하는 기본 메서드는 제공할 수 없다. (구현체가 재정의 하여 사용하는 것은 상관없음)
→ 본인이 수정할 수 있는 인터페이스에만 기본 메서드를 제공할 수 잇다.
→ 인터페이스를 상속받은 인터페이스에서 다시 추상 메서드로 변경 가능
→ 인터페이스 구현체가 default 메서드를 재정의 할 수 있다.
default메서드는 인터페이스에 새로운 기능을 추가해야하는데 구현 객체를 변경할 수 없는 경우 유용하다.
public interface Me{ void myName(); default void myAge(){ System.out.println("10"); } public class Real implements Me{ @Override public void myName(){ System.out.println("geneaky"); } }
위의 구현 클래스로 생성한 구현 객체는 바로 .myAge를 통해 메서드를 사용가능하다.
인터페이스의 스태틱 메서드 static/JAVA 8
인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메서드이다.
static 예약어를 사용하며, 접근제어자는 항상public이며 생략 가능하다.
메서드를 구현해야하며 구현 클래스에서 override가 불가능하다.
public interface MyStatic{ static void wow(){ System.out.println("wow"); } } ....//main 안에서 MyStatic.wow(); //wow
public interface MyStatic{ static void wow(){ System.out.println("wow"); } } ....//main 안에서 MyStatic.wow(); //wow
인터페이스의 private 메서드
java 9 에서 도입된 기능으로 java 8에서 기본 메서드 사용이 가능해졌기 때문에 로직을 분리하기 위해 사용할 수 있다.
private 메서드 이기 때문에 인터페이스에서 구현이 되어 있어야하고 추상 메서드일 수 없다.
구현체에서 구현할 수 없고 자식 인터페이스에서도 상속이 불가능 하다.
static 메서드도 private이 가능하다.
public interface Last{ static String thisIsLast(){ return "last"; } default void print(){ printFirst(); printLast(); } private void printFirst(){ System.out.println("first"); } private void printLast(){ System.out.println("last"); } }
private 메서드를 사용해서 default 메서드에서 사용할 로직을 분리 할 수 있다.
반응형'JAVA' 카테고리의 다른 글
백기선-JAVA STUDY/WEEK10 (0) 2021.02.21 백기선-JAVA STUDY/WEEK9 (0) 2021.01.29 백기선 - JAVA STUDY/WEEK7 (0) 2021.01.15 백기선-JAVA/STUDY/WEEK6 (0) 2021.01.07 백기선-JAVA STUDY/WEEK5 (0) 2020.12.19 댓글