0. 학습할 것
- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스의 기본 메소드 (Default Method), 자바 8
- 인터페이스의 static 메소드, 자바 8
- 인터페이스의 private 메소드, 자바 9
1. 인터페이스 정의하는 방법
- 인터페이스는 내부의 모든 필드(변수)가 public static final 로 정의됨
- 인터페이스의 static, default메서드를 제외한 모든 메서드는 public abstract 로 정의됨
- 인터페이스는 다중상속을 지원한다.
- 인터페이스는 동일한 목적하에 동일한 기능을 수행하게끔 강제하는것이 역할이자 개념
- 인터페이스는 "Inteface" 키워드를 통해 선언할 수 있으며, "implements" 키워드를 통해 일반 클래스에서 인터페이스를 구현할 수 있다.
- 인터페이스는 추상클래스처럼 추상메소드를 갖지만 추상클래스보다 추상화 정도가 높아서 추상클래스와 달리 일반 메소드 또는 멤버변수를 구성원으로 가질 수 없다.
- 오직 추상메소드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않는다.
- 인터페이스는 객체로 생성할 수 없기 때문에 생성자를 가질 수 없다.
interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
public abstract 메소드이름(매개변수);
}
인터페이스의 장점
- 개발 시간 단축
인터페이스가 작성되면 이를 사용해서 프로그램을 작성하는 것이 가능하다.
다른 개발자들이 각각의 부분을 완성할 때까지 기다리지 않고 서로 규약만 정해두어 각자의 부분만 따로 나눠서 작성된 코드를 컴파일 할 수 있다. - 표준화 가능
프로젝트에 사용되는 기본 틀을 인터페이스로 작성한 다음, 개발자들에게 인터페이스를 구현하여 프로그램을 작성하도록 하면 보다 일관되고 정형화된 프로그램의 개발이 가능하다. (자바의 다형성을 극대화 하여 코드의 수정을 줄이고 유지보수성을 높인다) - 서로 관계없는 클래스들 간의 관계를 맺을 수 있음
하나의 인터페이스를 공통적으로 구현하도록 하여 관계를 맺어 줄 수 있다. - 독립적인 프로그래밍이 가능
인터페이스를 이용하면 클래스의 선언과 구현을 분리시킬 수 있기 때문에 실제 구현에 독립적인 프로그램을 작성하는 것이 가능.
인터페이스는 추상 클래스와 같이 추상 메소드를 가지므로 추상 클래스와 매우 흡사하다.
인터페이스는 추상 클래스와 같이 인스턴스를 생성할 수 없고, 상속받은 클래스에서 구현한 뒤 자깃 클래스를 인스턴스화 하여 사용한다.
추상클래스와 인터페이스의 차이점
https://whitehairhan.tistory.com/226?category=936095
추상클래스는 "is-a : ~는 ~이다" 의 개념이다.
인터페이스는 "has-a : ~는 ~를 할 수 있다." 의 개념이다.
2. 인터페이스를 구현하는 방법
개발 코드가 인터페이스 메소드를 호출하면 인터페이스는 객체의 메소드를 호출한다.
객체는 인터페이스에서 정의된 추상 메소드와 동일한 메소드 이름, 매개 타입, 리턴 타입을 가진 메소드를 가지고 있어야 한다.
이러한 객체를 인터페이스 구현 객체라고 하며, 구현 객체를 생성하는 클래스를 구현 클래스라고 한다.
인터페이스를 구현하려면 implements 키워드 사용한다.
public class classname implements 인터페이스
다음 예제는 인터페이스를 구현하는 예제이다.
interface Animal {
public abstract void cry();
}
class Cat implements Animal {
public void cry() {
System.out.println("냐옹냐옹!");
}
}
class Dog implements Animal {
public void cry() {
System.out.println("멍멍!");
}
}
public class Polymorphism03 {
public static void main(String[] args) {
Cat c = new Cat();
Dog d = new Dog();
c.cry();
d.cry();
}
}
출처: http://www.tcpschool.com/java/java_polymorphism_interface
// 출력
냐옹냐옹!
멍멍!
인터페이스를 구현할 때 주의할 점
- 인터페이스의 모든 메서드는 public 접근제어를 가진다.
- 구현 클래스에서 메서드를 오버라이딩 할 때, 오버라이딩 메서드 접근 제어 범위가 조상보다 좁아서는 안된다.
interface Animal { // 인터페이스의 모든 메서드는 public abstract이다.
void cry(); // public abstract가 생략됨
}
class Cat implements Animal{
// 오버라이딩 규칙: 조상(public)보다 접근제어자 범위가 좁으면 안된다.
public void cry(){ // public 안쓰면 default가 되므로 컴파일 에러 발생
System.out.println("야옹");
}
}
3. 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
interface : Animal
public interface Animal {
public abstract void cry();
}
class : Dog
public class Dog implements Animal{
@Override
public void cry() {
System.out.println("멍멍!");
}
public void name() {
System.out.println("Milk");
}
}
class : Cat
public class Cat implements Animal{
@Override
public void cry() {
System.out.println("야옹");
}
public void name() {
System.out.println("cream");
}
}
class : Main
public class Main {
public static void main(String[] args) {
Animal dog1 = new Dog();
Animal cat1 = new Cat();
Dog dog2 = new Dog();
Cat cat2 = new Cat();
dog1.cry();
cat1.cry();
// dog1.name() // error!
// cat1.name() // error!
((Dog)dog1).name();
((Cat)cat1).name();
dog2.cry();
cat2.cry();
dog2.name();
cat2.name();
}
}
/* 출력
멍멍!
야옹
milk
cream
멍멍!
야옹
milk
cream
*/
그렇다면 왜 사용하는 것일까?
(추후에 추가)
4. 인터페이스 상속
자바에서는 클래스의 다중상속이 금지되어 있다.
하지만 인터페이스는 다중상속이 가능하다.
그 이유는 인터페이스에 존재하는 추상 메서드의 선언부(head)만 존재하기 때문에 충돌 가능성이 없기 때문이다.
다음과 같이 다중 상속이 가능하다.
interface Animal { public abstract void cry(); }
interface Pet { public abstract void play(); }
class Cat implements Animal, Pet {
public void cry() {
System.out.println("냐옹냐옹!");
}
public void play() {
System.out.println("쥐 잡기 놀이하자~!");
}
}
class Dog implements Animal, Pet {
public void cry() {
System.out.println("멍멍!");
}
public void play() {
System.out.println("산책가자~!");
}
}
public class Polymorphism04 {
public static void main(String[] args) {
Cat c = new Cat();
Dog d = new Dog();
c.cry();
c.play();
d.cry();
d.play();
}
}
출처: http://www.tcpschool.com/java/java_polymorphism_interface
실행결과
냐옹냐옹!
나비야~ 쥐 잡기 놀이하자~!
멍멍!
바둑아~ 산책가자~!
5. 인터페이스의 기본 메소드 (Default Method), 자바 8
- 자바 8 이전 인터페이스가 가질 수 있는 메서드는 추상메서드 뿐이였음 (해당 인터페이스를 구현한 클래스에서는 메서드의 body를 항상 완성해야만 쓸 수 있었음)
- 이 때 문제점이 발생하는데 인터페이스의 구현 클래스들이 메서드 구현 코드를 작성할 때, 클래스마다 인터페이스의 구현 메서드를 body에 새롭게 작성해 주어야 한다.
- 이 문제를 해결하기 위해 자바 8에서 디폴트 메소드를 허용하였고 기존 인터페이스를 확장해서 새로운 기능을 추가하기 위함의 목적임.
- default 메서드는 인터페이스 내부에 존재할 수 있는 구현메서드이다.
- 인터페이스를 implements 하면 메서드 구현없이 바로 사용할 수 있다.
- 클래스의 인스턴스 메소드와 형태는 동일
- 인터페이스에 선언되지만 사실은 객체 (구현 객체)가 가지고 있는 인스턴스 메소드
interface TestInterface {
// 이미 구현된 default 메서드
default void showMethod() {
System.out.println("디폴트 메서드");
}
}
class TestClass implements TestInterface {
public static void main(String args[]) {
TestClass testClass = new TestClass();
testClass.showMethod(); // 디폴트 메서드 호출
}
}
/* 실행결과
디폴트 메서드
*/
6. 인터페이스의 static 메소드, 자바 8
인터페이스의 static 메서드는 인터페이스 내에서 이미 body를 구현한 메서드이다.
하지만 구현 클래스에서 오버라이딩하여 사용할 수 없다. (즉, 재정의 할 수 없다)
public class TestClass {
public static void main(String[] args) {
Calculator calculator = new Calculator();
// calculator.print(100);
Calculator.print(100);
// 인터페이스의 static 메서드는 반드시 인터페이스 이름.메소드 형식으로 호출해야함.
}
}
public interface Calculator {
default int multi(int x, int y){
return x*y;
}
static void print(int value){
System.out.println(value);
}
}
static메서드를 사용할 때 class이름.메소드로 호출하는 것이 아닌 interface이름.메소드로 호출해야 한다.
7. 인터페이스의 private 메소드, 자바 9
인터페이스 내부에서 private 메서드를 사용 할 수 있다.
자바 8에서 나온 default ,static method 는 기본적으로 접근 지정자가 public만 가능 했기 때문에 캡슐화를 하지 못했다.
인터페이스 내부에 private을 만듦으로써, 외부에 공개하지 않으면서 코드 중복을 피할 수 있다.
Java8의 default method와 static method는 여전히 불편하게 만든다.
단지 특정 기능을 처리하는 내부 method일 뿐인데도, 외부에 공개되는public method로 만들어야하기 때문이다.
interface를 구현하는 다른 interface 혹은 class가 해당 method에 엑세스 하거나 상속할 수 있는 것을 원하지 않아도,
그렇게 될 수 있는 것이다.
java9 에서는 위와 같은 사항으로 인해 private method와 private static method라는 새로운 기능을 제공해준다.
→코드의 중복을 피하고 interface에 대한 캡슐화를 유지 할 수 있게 되었다.
- 인용: https://dev-coco.tistory.com/13
Animal interface
public interface Animal {
void animalMethod();
default void defaultAnimalMethod(){
System.out.println("Default Animal Method");
privateAnimalMethod();
privateStaticAnimalMethod();
}
private void privateAnimalMethod(){
System.out.println("private animal method");
}
private static void privateStaticAnimalMethod(){
System.out.println("private static car method");
}
}
DefaultAnimal Class
public class DefaultAnimal implements Animal{
@Override
public void animalMethod(){
System.out.println("animal method by DefaultAnimal");
}
}
MainTest Class
public class MainTest {
public static void main(String[] args) {
DefaultAnimal defaultAnimal = new DefaultAnimal();
defaultAnimal.animalMethod();
defaultAnimal.defaultAnimalMethod();
}
}
출력
animal method by DefaultAnimal
Default Animal Method
private animal method
private static car method
참고 및 인용
https://dev-coco.tistory.com/13
https://www.notion.so/4b0cf3f6ff7549adb2951e27519fc0e6
https://yadon079.github.io/2021/java%20study%20halle/week-08
https://www.notion.so/8-0cc8c251d5374ac882a4f22fa07c4e6a
https://ahnyezi.github.io/java/javastudy-8-interface/
'Language > Java-Weekly-study' 카테고리의 다른 글
[Java] W10: 자바 멀티쓰레드 프로그래밍 (0) | 2022.07.31 |
---|---|
[Java] W09: 자바 예외 처리 (0) | 2022.07.13 |
[Java] W07: 자바 패키지 (0) | 2022.07.10 |
[Java] W06: 자바 상속 (0) | 2022.06.26 |
[Java] W05: 자바 클래스 (0) | 2022.06.19 |