-
[java] 인터페이스java 2023. 1. 17. 22:40
인터페이스는 개발코드와 객체가 서로 통신하는 접점 역할을 한다.
개발 코드가 인터페이스의 추상 메소드를 호출하면, 인터페이스의 추상 메소드는 각 객체의 재정의된 실체메소드를 호출한다.
이때 각 객체는 인터페이스의 구현객체라고 하고, 구현 객체를 생성하는 클래스를 구현 클래스라고 한다.
이를 통해 개발 코드는 각 객체들의 내부 구조를 알 필요 없고, 인터페이스의 메소드만 알고 있으면 되어 다형성이 실현된다.- 보통 중요 클래스를 작성하는 입장이라면 , 클래스의 구현체와 상관없이 인터페이스를 기준으로 중요 클래스를 작성해야한다.
- 인터페이스는 단독파일로 저장하는것이 일반적인 방법이다.
- 인터페이스를 통해, 개발코드를 수정하지 않고 사용하는 객체를 변경할 수 있다.
- 인터페이스는 여러개의 객체들과 사용이 가능하므로 어떤 객체를 사용하느냐에 따라 리턴값이 다를 수있다. 따라서 개발코드 측면에서 코드 변경없이 실행 내용과 리턴값을 다양화할 수 있다. -> 다형성 실현
- 인터페이스는 기본적으로는 필드와 추상메소드로 구성되어있고, 객체로 생성할 수 없기 때문에 생성자를 가질 수 없다.
- 인터페이스는 ~.java 형태의 소스 파일로 작성되고 컴파일러를 통해 ~.class 형태로 컴파일되기때문에 물리적 형태는 클래스와 동일하다.
인터페이스의 구조
interface 인터페이스이름 { //상수 public int MAX_VOLUME = 10; int LEG_COUNT = 4; //추상 메소드 String getFood(); //디폴트 메소드 default void printFood(){ System.out.printf(getFood()); } //스태틱메소드 static int speed(){ return LEG_COUNT *30; } }
인터페이스 이름
영어 대소문자를 구분하고, 첫 글자는 대문자로 나머지는 소문자로 작성한다.
상수 필드 - [public static final] 타입 상수이름 = 값;
인터페이스는 객체 사용방법을 정의한 것으로 실행 시 데이터를 저장하는 인스턴스나 정적필드를 선언할 수 없다.
상수필드는 가능한데, 상수는 인터페이스에 고정된 값으로 실행 시에 데이터를 바꿀 수 없다.
상수는 public static final로 선언한다. 생략하더라도 컴파일 과정에서 자동으로 붙는다.
상수이름은 대문자로 작성하고 반드시 선언과 동시에 초기값을 지정해야한다.
추상메소드 - [public abstract] 리턴타입 메소드이름(매개변수, ...);
인터페이스를 통해 호출된 메소드는 최종적으로 객체에서 실행된다. 그렇기 때문에 인터페이스의 메소드는 실행 블록이 필요없는 추상메소드로 선언한다. 추상메소드는 모두 public abstract의 특성을 갖는다. 생략하더라도 컴파일 과정에서 자동으로 붙는다.
디폴트메소드
인터페이스의 메소드는 구현체를 갖지 못하지만, 디폴트 메소드를 사용하면 실제 구현된 형태의 메소드(실체메소드)를 가질 수 있다.
디폴트 메소드는 해당 인터페이스를 사용하는 구현 클래스들이 실체 메소드를 만들지 않아도 바로 사용가능하다.
구현 클래스
구현 클래스는, 구현 객체를 생성하는 클래스이다.
인터페이스 타입으로 사용할 수 있음을 알리기 위해 클래스 선언부에 implements 키워드를 추가하고, 인터페이스 이름을 명시한다.
그리고 인터페이스에 선언된 추상메소드의 실체 메소드를 선언한다.
이때 실체 메소드는 무조건 public이여야한다. 이유는 추상 메소드는 기본적으로 Public형태를 갖기때문에 이보다 더 낮은 접근 제한을 둘 수 없다.
public class Television implements RemoteControl{ //RemoteControl인터페이스를 사용하는 Television 구현 클래스 private int volume; public void turnOn(){ //turnOn() 추상 메소드의 실체 메소드 System.out.println("TV를 켭니다."); } }
인터페이스 사용 예제
https://lee-ding.tistory.com/94
인터페이스 사용법
전 포스팅과 이어지는 내용임 https://lee-ding.tistory.com/13 [java] 인터페이스 인터페이스는 개발코드와 객체가 서로 통신하는 접점 역할을 한다. 개발 코드가 인터페이스의 추상 메소드를 호출하면,
lee-ding.tistory.com
인터페이스를 사용한 예시
interface Predator{ } class Animal{ String name; void setName(String name) { this.name = name; } } class Tiger extends Animal implements Predator{ } class Lion extends Animal implements Predator{ } class ZooKeeper{ void feed(Predator predator){ System.out.println("feed apple"); } } public class Sample { public static void main(String[] args) { ZooKeeper zookeeper = new ZooKeeper(); Tiger tiger = new Tiger(); Lion lion = new Lion(); zookeeper.feed(tiger); zookeeper.feed(lion); } }
tiger lion은 각각 Tiger Lion의 객체이기도 하지만 Predator 인터페이스의 객체이기도 하기 떄문에 Predator자료형의 타입으로도 사용할 수 있다.
인터페이스의 메소드
인터페이스 내부에 추상메소드는 메소드의 이름과 입출력정의만있고 내용은 없는 메소드이다.
추상메소드는 자식 클래스에서 재정의되어(실체메소드) 실행 내용을 결정해야한다.
interface Predator{ String getFood(); // 추상 메소드 } class Animal{ String name; void setName(String name) { this.name = name; } } class Tiger extends Animal implements Predator{//구현클래스 public String getFood(){//실체 메소드 return "apple"; } } class Lion extends Animal implements Predator{ public String getFood(){ return "banana"; } } class ZooKeeper{ void feed(Predator predator){ System.out.println("feed "+predator.getFood()); } } public class Sample { public static void main(String[] args) { ZooKeeper zookeeper = new ZooKeeper(); Tiger tiger = new Tiger(); Lion lion = new Lion(); zookeeper.feed(tiger); zookeeper.feed(lion); } }
개발코드가 인터페이스 메소드를 호출-> 인터페이스는 객체의 메소드를 호출하는 구조 이기때문에,
객체는(인터페이스를 구현) 인터페이스에서 정의된 추상메소드와 동일한 이름,매개타입,리턴타입을 가진 실체 메소드를 가지고 있어야한다.
이러한 객체를 인터페이스의 구현 객체라고 하고 구현 객체를 생성하는 클래스를 구현 클래스라고 한다,
개발코드 : zookeeper.feed(tiger) -> tiger.getFood() //인터페이스의 추상메소드호출함
인터페이스 : interface Predator // 자신과 IS-A관계에 있는 구현클래스에서 실체메소드를 호출함
추상메소드 : String getFood()
실체메소드 : Lion, Tiger클래스 내부에 있는 getFood()메소드 , 무조건 public선언
구현클래스 : Lion, Tiger 클래스
구현객체 : Tiger객체-"apple"을리턴하는 , Lion객체-"banana"를 리턴하는
인터페이스는 왜 필요한가?
- 객체가 한 개 이상의 자료형을 갖게하는 다형성을 구현하기 위해서이다.
- 인터페이스는 메소드를 반드시 구현해야하는 강제성을 갖는다.
- 개발코드가 인터페이스의 메소드를 호출하면-> 인터페이스는 객체의 메소드를 호출시킨다,
- 그렇기때문에 개발코드는 객체의 내부구조를 알필요가없고 인터페이스의 메소드만 알고있으면된다.
- 인터페이스의 존재를 통해 의존적인 클래스들을 독립적인 클래스로 만들어줄수있다.
- 예를 들어 상속을 사용할경우 동물들 종류에 따라 다른 모이를 주는 메소드를 여러개 구현해야한다. 그러나 인터페이스를 사용할경우 메 소드를 여러개 구현할필요가없고 단한개의 모이를 주는 메소드로 구현이 가능해진다.
'java' 카테고리의 다른 글
[java] 추상클래스 (0) 2023.01.17 [java] 인터페이스의 다형성과 다중상속 (0) 2023.01.17 [java] 생성자(Constructor) (0) 2023.01.17 [java] 상속 (0) 2023.01.16 [java] call by value vs call by reference (0) 2023.01.16