[Java]인터페이스

정석용·2023년 4월 10일
0

Java

목록 보기
8/15
post-thumbnail

인터페이스

자식 클래스가 여러 부모 클래스를 상속받을수 있다면, 다양한 동작을 수행할 수 있다는 장점을 가지게 될 것입니다. 하지만 클래스로 다중 상속을 할 경우 모호성 등 여러가지 문제가 발생할 수 있어 자바에서는 클래스를 통한 다중 상속은 지원하지 않는다.

하지만 자바에선 인터페이스를 통해 다중 상속을 지원한다.

인터페이스란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미한다.

자바에서 추상 클래스는 추상 메소드뿐만 아니라 생성자, 필드, 일반 메소드도 포함할 수 있다. 하지만 인터페이스는 오로지 메소드와 상수만을 포함할 수 있다.

인터페이스 선언
인터페이스를 선언할 때에는 접근 제어자와 함께interface 키워드를 사용하면 된다.

EX.

접근제어자 interface 인터페이스이름 {
    public static final 타입 상수이름 = 값;
    ...
    public abstract 메소드이름(매개변수목록);
    ...
}

단, 클래스와는 달리 인터페이스의 모든 필드는 public static final이어야 하며, 모든 메소드는 public abstract이어야 한다.
(제어자는 생략 가능, 컴파일 시 자동 추가)

인터페이스 구현
인터페이스는 추상 클래스와 마찬가지로 자신이 직접 인스턴스를 생성할 수는 없다.
따라서 인터페이스가 포함하고 있는 추상 메소드를 구현해 줄 클래스를 작성해야만 한다.

EX.

class 클래스이름 implements 인터페이스이름 { ... }

만약 모든 추상 메소드를 구현하지 않는다면, abstract 키워드를 사용하여 추상 클래스로 선언해야 한다.

++
자바에서는 다음과 같이 상속과 구현을 동시에 가능

class 클래스이름 extend 상위클래스이름 implements 인터페이스이름 { ... }

EX.다중 상속

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();
    }
}

클래스를 이용한 다중 상속의 문제점
같은 cry() 가지고 있는 클래스가 여러개 있는 경우 출력시 어느 메소드인지 구분할 수 없는 모호성을 지니게 되어 자바에서는 클래스를 이용한 다중 상속을 지원하지 않는다.

class Animal { 
    public void cry() {
        System.out.println("짖기!");
    }
}
 
class Cat extends Animal {
    public void cry() {
        System.out.println("냐옹냐옹!");
    }
}
 
class Dog extends Animal {
    public void cry() {
        System.out.println("멍멍!");
    }
}
 
① class MyPet extends Cat, Dog {}
 
public class Polymorphism {
    public static void main(String[] args) {
        MyPet p = new MyPet();
②      p.cry();
    }
}

하지만 인터페이스를 이용하여 다중 상속을 하게되면 위와 같은 메소드 호출의 모호성을 방지할 수 있다.

인터페이스의 장점

  • 대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화가 가능
  • 클래스의 작성과 인터페이스의 구현을 동시에 진행할 수 있으므로, 개발 시간을 단축할 수 있다.
  • 클래스와 클래스 간의 관계를 인터페이스로 연결하면, 클래스마다 독립적인 프로그래밍이 가능.

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

인터페이스 타입으로 객체를 생성할 수 있으며 해당 객체에 구현 클래스로 인스턴스화 할 수 있다.

인터페이스 타입으로 선언한 객체는 구현 클래스 내에서 생성한 메서드, 필드를 사용할 수 없다.

인터페이스의 메소드

인터페이스의 default 메소드

인터페이스가 dafault 키워드로 선언되면 메소드가 구현될 수 있다. 또한 이를 구현하는 클래는 dafault 메소드를 오버라이딩 할 수 있다. Java 8 이후부터 default 메소드를 사용하면 메서드 구현부를 가질 수 있다.

EX.

public interface calculator{
	dafault int exec(int i, int j){
    	retrun i + j;
        }
}
public class mycal{
	public static void main(string[] atgs){
    	claculator cal = new my mycal();
        system.out.println(value);
        }
}

인터페이스가 변경 되면, 인터페이스를 구현하는 모든 클래스들이 해당 메소드를 구현해야 하는 문제가 있다. 이런 문제를 해결하기 위하여 인터페이스에 메소드를 구현해 놓을 수 있도록 하였다.

static 메소드

Java 8 부터 생겨난 static 메소드는 인터페이스를 이용하여 간단한 기능을 가지는 유탈리티 성 인터페이스를 만들 수 있다.

  • 상속 불가능.
  • 인터페이스의 상수와 같은 형식으로 쓰인다.
  • interface이름.static메소드이름 으로 사용.
    public interface Calculator {
        public int plus(int i, int j);
        public int multiple(int i, int j);
        default int exec(int i, int j){
            return i + j;
        }
        public static int exec2(int i, int j){   //static 메소드 
            return i * j;
        }
    }

    //인터페이스에서 정의한 static메소드는 반드시 인터페이스명.메소드 형식으로 호출해야한다.  

    public class MyCalculatorExam {
        public static void main(String[] args){
            Calculator cal = new MyCalculator();
            int value = cal.exec(5, 10);
            System.out.println(value);

            int value2 = Calculator.exec2(5, 10);  //static메소드 호출 
            System.out.println(value2);
        }
    }

인터페이스에 static 메소드를 선언함으로써, 인터페이스를 이용하여 간단한 기능을 가지는 유틸리티성 인터페이스를 만들 수 있다.

인터페이스의 private 메소드

인터페이스의 메소드는 public이다. java9 부터는 private를 사용함으로써 외부에 공개하지 않게 하며 코드의 중복을 피하고 interface에 대한 캡슐화를 유지할 수 있게 한다.

  • private, private static 사용이 가능. 하지만 각각 호출 가능한 메서드가 다름.

private : private, abstract, default, static 메서드 호출 가능
private static : static, private static 메서드만 호출 가능

래퍼런스
http://www.tcpschool.com/java/java_polymorphism_interface
https://youn12.tistory.com/31
https://school.programmers.co.kr/learn/courses/5/lessons/241

profile
오늘도 성장중

0개의 댓글