[Java] 인터페이스란?

G·2024년 7월 7일
0

Java

목록 보기
13/21
post-thumbnail

✍️ 인터페이스 (Interface)

✏️ 인터페이스 란?

💡 클래스 사이의 중간매개 역할까지 담당하는 일종의 추상 클래스

  • 인터페이스는 추상 클래스처럼 추상 메서드를 갖지만 추상 클래스보다 추상화 정도가 높습니다. 따라서 추상 클래스와 달리 몸통을 갖춘 일반 메서드 또는 멤버 변수를 구성원으로 가질 수 없습니다.
  • 오직 추상 메서드와 상수만을 멤버로 가질 수 있습니다.



✏️ 작성

  • interface 키워드를 통해 인터페이스를 선언합니다.
  • 인터페이스 접근 제어자로는 public , default 를 사용할 수 있습니다.
  • 모든 멤버 변수는 public static final 이어야 하며, 이는 생략할 수 있습니다.
  • 모든 메서드는 public abstract 이어야 하며, 이는 생략할 수 있습니다.
    단, static 메서드와 default 메서드는 예외(JDK 1.8 이상)



✏️ 상속

  • 인터페이스는 인터페이스로부터만 상속이 가능합니다.
  • 클래스와 달리 다중 상속이 가능합니다.
  • 인터페이스가 인터페이스를 상속받을 때는extends 키워드를 통해 상속합니다.
interface Movable {
	void move (int x, int y);
}

interface Attackable {
	void attack (int z);
}

interface Fightable extends Movable, Attackable {
	void move (int x, int y);
}



✏️ 구현

  • 인터페이스 자체로는 인스턴스를 생성할 수 없습니다.
  • 추상 메서드의 몸통을 만들어주는 클래스를 작성해야 합니다.
  • 클래스가 인터페이스를 구현할 때는 implements 키워드를 사용합니다.
  • 클래스에서 구현하는 인터페이스의 메서드 중 일부만 구현한다면, abstract 를 붙여서 추상 클래스로 선언해야 합니다.
class Unit {
	int currentHR;
    int x;
    int y;
}

abstract class FighterAbs implements Fightable {
	public void move(int x, int y}
}

class Fighter extends Unit implement Fightable {
	public void move(int x, int y) { ... }
    public void attack(Fightable f) { ... }



✏️ 장단점

🎨  장점

  • 다형성 및 추상화를 구현할 수 있습니다.
  • 객체간의 의존성을 줄일 수 있습니다.
  • 개발 시간을 단축시킬 수 있습니다.
  • 표준화가 가능합니다.
  • 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있습니다.
  • 독립적인 프로그래밍이 가능합니다.
  • 변경이 용이하다.

🎨  단점

  • 인터페이스에 구현된 추상메서드를 모두 구현해야 합니다.
  • 메서드 시그니처 변경 시, 변경이 용이하지 않습니다.



✏️ 사용 이유

🎨  다형성

  • 서로 다른 클래스들이 동일한 인터페이스를 구현하게 함으로써, 객체의 종류에 상관 없이 동일한 방식으로 다룰 수 있게 합니다.

🎨  유연성

  • 인터페이스를 사용하면 나중에 구현을 변경하거나 추가할 때 더 유연하게 대응할 수 있습니다.

🎨  의존성 감소

  • 직접 클래스를 의존하게 되면, 그 클래스의 변경사항에 영향을 받을 가능성이 큽니다. 하지만 인터페이스를 사용하면, 해당 인터페이스를 구현한 다른 클래스들로 쉽게 대체 할 수 있습니다.
interface I {
    public void methodB();
}

class B implements I {
    public void methodB() {
        System.out.println("methodB from B");
    }
}

class C implements I {
    public void methodB() {
        System.out.println("methodB from C");
    }
}

class A {
    public void methodA(I i) {
        i.methodB();
    }
}

public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.methodA(new B()); // methodB from B
        a.methodA(new C()); // methodB from C
    }
}

✏️ 변경 용이성에 대한 오해

  • '변경에 용이하다'는 다형성을 통해 다양한 객체를 쉽게 교체할 수 있다는 것을 의미합니다. 이는 인자값의 변경이 아니라, 객체 교체의 용이성을 말합니다.

🎨  객체 변경

  • Client 클래스에서 Shape 인터페이스를 통해 다양한 모양(Shape)을 생성하고 호출할 수 있습니다. 먄약, 새로운 모양을 추가하고 싶다면, Shape 인터페이스를 구현하는 새로운 클래스를 만들면 됩니다.
interface Shape {
    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle: draw()");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle: draw()");
    }
}

public class Client {
    public static void main(String[] args) {
        Shape shape1 = new Circle();
        shape1.draw(); // Circle: draw()

        Shape shape2 = new Rectangle();
        shape2.draw(); // Rectangle: draw()
    }
}

🎨  인자값 변경

  • 만약 메서드의 인자값이 변경된다면, 인터페이스와 구현체 모두 수정해야 합니다.
// Before

interface Calculator {
    int add(int a, int b);
}

class BasicCalculator implements Calculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}

public class Client {
    public static void main(String[] args) {
        Calculator calculator = new BasicCalculator();
        int result = calculator.add(5, 3);
        System.out.println("Result: " + result); // Result: 8
    }
}


// After

interface Calculator {
    int add(int a, int b, int c);
}

class BasicCalculator implements Calculator {
    @Override
    public int add(int a, int b, int c) {
        return a + b + c;
    }
}

public class Client {
    public static void main(String[] args) {
        Calculator calculator = new BasicCalculator();
        int result = calculator.add(5, 3, 8);
        System.out.println("Result: " + result); // Result: 16
    }
}
profile
기!술! 블로그

0개의 댓글