🌻 JAVA/정리정리정리

JAVA - STUDY 8주차 과제 : 인터페이스

2021. 1. 8. 16:41
목차
  1.  
  2. 목표
  3. 학습할 것 (필수)
  4. 추상 클래스와 인터페이스의 차이점
  5. 인터페이스 정의하는 방법
  6. 인터페이스 구현하는 방법
  7. 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
  8. 인터페이스 상속
  9. 인터페이스의 기본 메소드 (Default Method), 자바 8
  10. 인터페이스의 static 메소드, 자바 8
  11. 인터페이스의 private 메소드, 자바 9
  12. 정리
  13.  
  14. REFERENCES
반응형

 

목표

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

 

학습할 것 (필수)

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

 

 

추상 클래스와 인터페이스의 차이점

추상 클래스(abstract class) 인터페이스(interface)
1. 일반 메소드 포함가능 1. 모든 메서드는 추상메서드
자바 8 이후 부터 default ,static  메소드 추가가능
2. 다중상속 불가능 2. 다중상속 가능
3. 상수, 변수 필드 포함가능 3. 상수필드만 포함가능

추상 클래스는 IS - A 이다. ( 개는 동물이다. )

인터페이스는 HAS - A 이다. ( 개는 수영을 할 수 있다. )

개는 동물인 것에 확실하지만, 어떤 개는 수영을 할 수도 있고, 못 할 수도 있다.

 

인터페이스 정의하는 방법

  • 인터페이스를 정의할 때에는 키워드 interface 를 사용한다.
  • 모든 필드는 public final static 이다.
  • 모든 메소드는 public abstract 이다.

 

변수 a에는 final static 을 붙여주고, b에는 생략을 해봤다.

메소드 cry와 feed도 마찬가지로 하나는 생략을 했다.

 

그렇지만 컴파일 에러가 나지 않고 잘 실행이 되었다. 왜그럴까??

 

아래 바이트 코드를 살펴보면 모든 필드, 메소드에 자동으로 추가가 되있는 것을 확인할 수 있다.

컴파일러가 자동으로 추가를 해준다. 즉, 생략이 가능하다는 의미이다.

 

인터페이스 구현하는 방법

구현을 할 때에는 클래스를 상속받는 것처럼 extends(상속) 대신 implements(구현) 를 사용한다.

public interface Animal {

    void cry();
}

public class Cat implements Animal {

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

 

 

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

인터페이스는 다형성을 이용해 구현할 수 있다.

자식 클래스의 인스턴스를 부모클래스의 참조변수로 참조하는 것이 가능하다는 의미이다.

 

인터페이스는 객체의 타입으로만 사용된다.
이 말은 상속에서와 같이 변수 선언 시에 객체의 타입으로 인터페이스를 사용할 수 있다는 것을 의미한다. 

 

인터페이스 타입이 있을 때는 항상 인터페이스 타입 기반으로 코딩해야 한다.

 

List 인터페이스를 예를 들어보자.

List를 구현한 구현체들은 여러가지가 있다. (예: ArrayList, LinkedList ..등등) 아래와 같이 선언할 수 있다.

// 좋은 예 : 객체 타입을 인터페이스로 선언.
List<Integer> list = new ArrayList<Integer>();

// 나쁜 예 : 객체 타입을 클래스로 선언
ArrayList<Integer> list = new ArrayList<Integer>();

인터페이스 로 객체 타입을 선언하게 된다면, 추후에  클래스를 교체할 일이 생겼을 시에 클래스만 바꿔끼면 된다. 시스템이 유연해지게 만드는 것이다. 

 

익명 구현 개체

인터페이스는 원칙적으로 객체화 될 순 없지만, 익명 객체를 통해서 인터페이스를 구현하는 일회용 객체를 만들 수 있다.

public interface MusicPlayer {

	void play();
}

// .. main

MusicPlayer mp = new MusicPlayer() {

    @Override
    public void play() {
    	System.out.println("play the music!");
    }
};

인터페이스에 선언된 추상 메소드를 오버라이드 해주면 된다.

 

인터페이스 상속

  • 인터페이스 끼리 상속을 할 때에는 extends 키워드를 사용한다.
public interface A {
	...
}

public interface B {
	...
}

/* 다중 상속 가능 */
public interface C extends A, B {
	...
}

 

 

  • 인터페이스는 다중 구현이 가능하다.
    • implements A, B, C ... 
public interface Animal {
	
    void cry();
}

public interface Pet {

    void play();
}


public class Cat implement Animal, Pet {

    public void cry() {
    	System.out.println("냐옹");
    }
    
    public void play() {
    	System.out.println("play!!");
    }
}

 

  • 클래스와 인터페이스를 동시에 상속(extends), 구현(implements)할 수 있다.
public class Animal {
	
    public void cry() {

    }
}

public interface Pet {

    void play();
}


public class Cat extends Animal implements Pet {

    public void cry() {
    	System.out.println("냐옹");
    }
    
    public void play() {
    	System.out.println("play!!");
    }
}

 

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

  • 자바 8 이후로 인터페이스는 기본 메소드(Default Method) 를 사용할 수 있게 되었다.
  • 기존에는 인터페이스 내에 있는 메소드를 전부 다 오버라이딩 해야만 했지만, 기본 메소드는 반드시 구현할 필요 없다.
  • 기본 메소드 (Defalut Method) 는 구현부(body) 를 가지게 된다.

 

인터페이스를 구현할 때에는 항상 추상 메소드를 전부 다 오버라이딩 해야만 했다.

하지만 내가 필요한 메소드(기능)만 오버라이딩 하고 싶다면??

 

(기존 방법) :  중간에 인터페이스를 구현하는 Adapter 클래스를 생성한다.

public interface JoinMember {
	
    void preJoin();
    
    void afterJoin();
    
}

 

만약 내가 preJoin 만 구현하고 싶다면? 모든 메소드를 전부 빈 메소드로 정의한다.

public class MemberAdapter implements JoinMember {

    public void preJoin() { // 빈 메소드 정의 }

    
    public void afterJoin() { // 빈 메소드 정의 }
    
    
}

 

MemberAdapter를 상속받아서 필요한 메소드만 오버라이딩 하면 된다!

public class HelloMember extends MemberAdapter {
	
    /* 필요한 기능만 오버라이딩 */
    @Override
    public void preJoin() {
    	System.out.println("hello, member");
    }
}

( 자바 8 이후 default 메소드 사용 가능 ! )

public interface Camera {
    
    void takePhoto();
    
    /* default Method */
    default void takeVideo() {
        System.out.println("take a Video!");
    }
}

public interface MusicPlayer {
    
    void playMusic();
}


public class SmartPhone implements Camera, MusicPlayer{
    
    @Override
    public void takePhoto() {

    }

	// takeVideo 메소드를 구현하지 않아도 된다.

    @Override
    public void playMusic() {

    }
}

 

만약 interface에 동일한 default 메소드가 선언되어 있다면?

 

컴파일 에러가 발생하기 때문에, 무조건 overriding을 해야한다. 

 

public interface Camera {
    
    void takePhoto();
    
    default void takeVideo() {
        System.out.println("take a Video!");
    }
    
    default void print() {
        System.out.println("camera");
    }
}


public interface MusicPlayer {
    
    void playMusic();
    
    default void print() {
        System.out.println("Music");
    }
}


public class SmartPhone implements Camera, MusicPlayer{
    @Override
    public void takePhoto() {

    }

	// print()를 구현하지 않으면?

    @Override
    public void playMusic() {

    }
}

 

동일한 메소드를 오버라이딩(Overriding) 하지 않으면? 아래처럼 컴파일 에러가 발생하게 된다!

 

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

인터페이스의 추상성을 해친다는 이유로 제약을 걸어왔지만, 자바 8 부터는 개발의 유연성을 위해 static 메소드를 선언할 수 있게 되었다.

  • static 메소드는 오버라이딩이 불가!
  • default 나 abstract 메소드는 모두 instance 메소드 처럼 처리된다.
  • default 메소드를 static 메소드로 덮으려 하면 안된다 -> 컴파일 에러!
public interface MusicPlayer {
	static void info() {
    	System.out.println("Music Player!");
    }
}


public class Main {
	public static void main(String[] args){
    	MusicPlayer.info();	// Music Player!
    }
}

 

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

자바 9 이후로 private  메소드 접근제어자도 사용할 수 있게 되었다.

public interface Camera {
	
	default void print() {
    	
        ..
    }
    
    private void info() {
    	
        ..
    }
}

 

인터페이스에서도 default, static, private 기능이 추가되었는데,  추상클래스가 필요가 없어지는 것인가?

  • 상태 존재 여부에 따라서 

인터페이스는 필드에 상수만 선언 가능하고, private String 처럼 선언이 불가능 하다!

 

추상 클래스는 실행 중 변경이 필요할 때, 사용할 수 있다.

public abstract clas AbstractJoinMember implements JoinMember {

    private String message = "hello";		// 이런게 가능
    
    @Override
    public void preJoin() {
    	System.out.println(message);
    }
    
    public void setMessage(String message) {
    	this.message = message;			// 이런게 가능
    }
}

이런 점 때문에 아직 까지도 추상 클래스에도 효용가치가 있다!

 

정리

public interface 인터페이스명 {
    // 상수        : 값을 정해줄테니 제공해주는 값을 변경하지 말고 사용해라.
    타입 상수명 = 값;
    
    // 추상 메소드	: 가이드만 줄테니 구현부는 알아서 구현해라. 
    타입 메소드명(매개변수 ...);
    
    // 디폴트 메소드  : 구현부는 기본적으로 인터페이스에서 제공하지만, 필요하면 오버라이딩해서 재구현해라.
    default 타입 메소드명(매개변수 ...) {
    	// 구현부
    }
    
    // 정적 메소드	 : 인터페이스에서 제공해주는 것으로 무조건 사용. 오버라이딩 불가!
    static 타입 메소드명(매개변수 ...) {
    	// 구현부
    }
}

 

 

 

 

REFERENCES

  • www.notion.so/Java-8-0cc8c251d5374ac882a4f22fa07c4e6a
  • github.com/ByungJun25/study/tree/main/java/whiteship-study/8week#Interface-%EB%A0%88%ED%8D%BC%EB%9F%B0%EC%8A%A4%EB%A5%BC-%ED%86%B5%ED%95%B4-%EA%B5%AC%ED%98%84%EC%B2%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
  • kils-log-of-develop.tistory.com/437
  • leegicheol.github.io/whiteship-live-study/whiteship-live-study-08-interface/
  • www.tcpschool.com/java/java_polymorphism_interface
  • docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html
  • velog.io/@jaden_94/8%EC%A3%BC%EC%B0%A8-%ED%95%AD%ED%95%B4%EC%9D%BC%EC%A7%80#5-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EB%A9%94%EC%86%8C%EB%93%9C-default-method-%EC%9E%90%EB%B0%94-8
반응형
저작자표시 (새창열림)
  1.  
  2. 목표
  3. 학습할 것 (필수)
  4. 추상 클래스와 인터페이스의 차이점
  5. 인터페이스 정의하는 방법
  6. 인터페이스 구현하는 방법
  7. 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
  8. 인터페이스 상속
  9. 인터페이스의 기본 메소드 (Default Method), 자바 8
  10. 인터페이스의 static 메소드, 자바 8
  11. 인터페이스의 private 메소드, 자바 9
  12. 정리
  13.  
  14. REFERENCES
'🌻 JAVA/정리정리정리' 카테고리의 다른 글
  • JAVA - STUDY 9주차 과제 : 예외 처리
  • JAVA - 메소드 시그니처(method Signature)
  • Mac에서 JDK - 환경변수 설정하기
  • JAVA - STUDY 7주차 과제 : 패키지
iseunghan
iseunghan
꾸준하게 열심히..
iseunghan
iseunghan

공지사항

  • 어제보다 나은 오늘이 되기 위해 🔥
  • 분류 전체보기 (262)
    • 💐 Spring (14)
      • 개념 및 이해 (2)
      • Spring 핵심 기술 (24)
      • Spring REST API (8)
      • Spring MVC, DB 접근 기술 (7)
      • Spring Security (23)
      • Spring in Action (1)
    • 🌻 JAVA (84)
      • 자바 ORM 표준 JPA 프로그래밍 (20)
      • 알고리즘, 자료구조 (13)
      • 디자인 패턴 (7)
      • 정리정리정리 (43)
      • JUnit (1)
    • 🔖 Snippets (3)
      • Javascript (3)
    • ⚙️ Devops (22)
      • ⛏ Git (11)
      • 🐳 Docker (6)
      • 🐧 Linux (3)
      • 🌈 Jenkins (1)
      • 📬 Kafka (1)
    • 💬 ETC.. (4)
      • 💻 macOS (2)
    • 🌧️ ORM (2)
      • JPA (2)
    • 🐍 Python (3)
    • 📚 Databases (15)
      • 오라클로 배우는 데이터베이스 개론과 실습(2판) (3)
      • RealMySQL 8.0 (8)
    • 🔥 Computer Science (5)
      • 📡 네트워크 (5)
    • 🏷️ 협업 (1)
    • 📜 코딩테스트 (38)
      • BAEKJOON\수학 1, 수학 2 (8)
      • BAEKJOON\재귀 (5)
      • BAEKJOON\브루트 포스 (3)
      • BAEKJOON\정렬 (1)
      • BAEKJOON\백트래킹 (5)
      • BAEKJOON\BFS, DFS (6)
      • BAEKJOON\이분탐색 (1)
      • BAEKJOON\다이나믹 프로그래밍 (9)
      • BAEKJOON\그리디 알고리즘 (0)
    • ✨ ISEUNGHAN (1)

인기 글

전체
오늘
어제
반응형
hELLO · Designed By 정상우.
iseunghan
JAVA - STUDY 8주차 과제 : 인터페이스
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.