
인터페이스는 상수형 필드와 추상 메소드만을 포함할 수 있는 추상 클래스의 변형체입니다.
메소드의 통일성을 부여하기 위해 추상 메소드만 따로 모아놓은 것으로, 인터페이스를 상속받는 클래스는 해당 인터페이스 내에 정의된 모든 추상 메소드를 구현해야 합니다.
인터페이스의 특징은 다음과 같습니다:
1. 모든 인터페이스의 메소드는 묵시적으로 public이고 abstract입니다.
2. 변수는 묵시적으로 public static final입니다.
3. 객체 생성은 불가능하나 참조형 변수로는 사용할 수 있습니다.
interface Printable { public void print(String doc); // 추상 메소드 }
인터페이스는 메소드의 몸체를 갖지 않기 때문에 인스턴스 생성이 불가능하지만 참조 변수 선언은 가능합니다.
class Printer implements Printable { @Override public void print(String doc) { System.out.println(doc); } }
인터페이스를 구현하는 클래스는 해당 인터페이스의 모든 추상 메소드를 구현해야 하며, 구현된 메소드와 추상 메소드 사이에도 메소드 오버라이딩 관계가 성립하기 때문에 @Override 어노테이션을 사용할 수 있습니다.
클래스는 다른 클래스를 상속하면서 동시에 여러 인터페이스를 구현할 수 있습니다.
class Robot extends Machine implements Movable, Runnable { // ... }
위 코드에서 Robot 클래스는 Machine 클래스를 상속받으면서, Movable과 Runnable 인터페이스를 구현하고 있습니다. 이렇게 둘 이상의 인터페이스를 구현할 수 있습니다.
기존에 정의된 인터페이스에 새로운 메소드를 추가하면, 이를 구현하는 모든 클래스에서 오류가 발생합니다. 이를 해결하기 위해 디폴트 메소드를 사용할 수 있습니다.
interface Printable { default void printCMYK(String doc) { // 디폴트 메소드 } }
기존 클래스는 디폴트 메소드가 추가되더라도 코드 수정 없이 사용할 수 있습니다.
인터페이스에도 static 메소드를 정의할 수 있으며, 클래스의 static 메소드 호출 방법과 동일하게 호출할 수 있습니다.
interface Printable { static void printLine(String str) { System.out.println(str); } default void print(String doc) { printLine(doc); // 인터페이스의 static 메소드 호출 } }
추상 클래스는 몸체가 없는 메소드를 포함한 클래스를 말합니다. 추상 클래스는 인스턴스를 생성할 수 없지만, 참조 변수로는 사용할 수 있습니다.
public abstract class House { public void methodOne() { System.out.println("method one"); } public abstract void methodTwo(); // 추상 메소드 }
몸체({})가 없는 메소드를 추상 메소드라고 하며, 상속 시 반드시 오버라이딩해야 하는 메소드입니다.
public abstract void methodTwo(); // 추상 메소드
package j.Interface.ex2; public interface Shape { double calculateArea(); // 추상 메소드로 정의 }
package j.Interface.ex2; public class Circle implements Shape { private double radius; public Circle(double radius) { this.radius = radius; } @Override public double calculateArea() { return Math.PI * radius * radius; } }
package j.Interface.ex2; public class Rectangle implements Shape { private double width; private double height; public Rectangle(double width, double height) { this.width = width; this.height = height; } @Override public double calculateArea() { return width * height; } }
package j.Interface.ex2; public class Run { public static void main(String[] args) { Shape[] shapes = new Shape[2]; shapes[0] = new Circle(5); shapes[1] = new Rectangle(3, 4); for(Shape shape : shapes) { System.out.println("도형의 넓이 : " + shape.calculateArea()); } } }
Shape 인터페이스를 구현한 Circle과 Rectangle 클래스를 정의하고, 각 클래스에서 calculateArea 메소드를 구현했습니다. Run 클래스에서 이들을 사용하여 도형의 넓이를 계산합니다.