프로그래밍 공부
객체지향 프로그래밍(인터페이스) 본문
인터페이스
자바에서 클래스가 반드시 구현해야 하는 메소드의 청사진을 제공하는 일종의 계약
- 이렇게 보면 설명이 어려운데 쉽게 생각하면 게임기의 버튼을 생각하면 될 것 같다.
같은 버튼이라도 어떤 게임인지에 따라 기능이 다르기 떄문
- 이렇게 보면 설명이 어려운데 쉽게 생각하면 게임기의 버튼을 생각하면 될 것 같다.
인터페이스는 메소드 선언만을 포함하며, 메소드의 구현은 하지 않음
이를 통해 클래스가 특정 기능을 반드시 구현하도록 강제할 수 있다.
자바에서 인터페이스는 다중 상속을 가능하게 하는 주요 도구
특징
- 메소드 선언만 포함: 인터페이스는 메소드의 시그니처(이름, 반환형, 매개변수)만을 선언하며, 메소드 본체는 포함하지 않음.
- 다중 구현 가능: 클래스는 여러 개의 인터페이스를 구현할 수 있어 다중 상속이 가능.
- 상수만 포함: 인터페이스는 필드를 가질 수 있지만, public static final로 선언된 상수만 가질 수 있다.
- 추상 메소드와 기본 메소드: 자바 8 이후로는 인터페이스에 추상 메소드뿐만 아니라, 디폴트 메소드(기본 구현이 있는 메소드)와 정적 메소드를 포함할 수 있음.
사용 목적
- 다형성 구현: 인터페이스를 통해 다형성을 구현할 수 있으며, 같은 인터페이스를 구현하는 클래스들은 동일한 메소드들을 갖게 되어 동일한 방식으로 처리될 수 있음.
- 구현 강제: 인터페이스는 특정 클래스가 반드시 구현해야 하는 메소드들을 명시하여
클래스가 특정 기능을 제공하도록 강제할 수 있다. - 유연한 설계: 인터페이스를 사용하면 코드의 유연성과 재사용성을 높일 수 있음.
구현체가 변경되더라도 인터페이스는 그대로 유지될 수 있기 때문에, 코드의 수정이 최소화됨. - 다중 상속: 클래스는 여러 인터페이스를 구현할 수 있어, 다중 상속의 효과를 얻을 수 있다.
추상 클래스와의 차이점
- 목적: 추상 클래스는 클래스들의 공통된 속성과 메소드를 정의하는 데 사용되고
인터페이스는 클래스가 구현해야 할 계약(메소드 집합)을 정의하는 데 사용. - 구현 여부: 추상 클래스는 일반 메소드를 포함할 수 있지만, 인터페이스는 기본적으로 메소드의 선언만
포함(자바 8 이후 디폴트 메소드와 정적 메소드가 추가됨). - 다중 상속: 인터페이스는 다중 상속을 지원하지만, 추상 클래스는 단일 상속만 지원.
- 목적: 추상 클래스는 클래스들의 공통된 속성과 메소드를 정의하는 데 사용되고
인터페이스 예제 코드
interface Animal { // 추상 메소드 (구현이 필요함) void sound(); // 디폴트 메소드 (기본 구현 제공) default void sleep() { System.out.println("This animal is sleeping."); } // 정적 메소드 (인스턴스화 없이 호출 가능) static void info() { System.out.println("This is an Animal interface."); } } class Dog implements Animal { @Override public void sound() { System.out.println("Bark"); } } class Cat implements Animal { @Override public void sound() { System.out.println("Meow"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog(); dog.sound(); // "Bark" 출력 dog.sleep(); // "This animal is sleeping." 출력 (디폴트 메소드) Cat cat = new Cat(); cat.sound(); // "Meow" 출력 cat.sleep(); // "This animal is sleeping." 출력 (디폴트 메소드) // 인터페이스의 정적 메소드 호출 Animal.info(); // "This is an Animal interface." 출력 } }
다중 상속
인터페이스를 통한 다중 구현(다중 상속과 유사) 예시
// 첫 번째 인터페이스 interface Flyable { void fly(); } // 두 번째 인터페이스 interface Swimmable { void swim(); } // 클래스가 두 인터페이스를 구현 (다중 상속과 유사한 효과) class Duck implements Flyable, Swimmable { @Override public void fly() { System.out.println("The duck is flying."); } @Override public void swim() { System.out.println("The duck is swimming."); } } public class Main { public static void main(String[] args) { Duck duck = new Duck(); // Flyable 인터페이스의 메소드 호출 duck.fly(); // 출력: The duck is flying. // Swimmable 인터페이스의 메소드 호출 duck.swim(); // 출력: The duck is swimming. } }
효과
- 코드 재사용성:
Duck
클래스는Flyable
과Swimmable
인터페이스를 통해 비행과 수영 기능을 모두 재사용할 수 있다. - 유연성: 클래스가 여러 인터페이스를 구현할 수 있으므로, 다양한 기능을 독립적으로 구현하고 조합할 수 있음.
- 다형성: 인터페이스 타입으로 객체를 참조할 수 있어, 다형성을 활용한 유연한 코드 작성이 가능.
- 코드 재사용성:
인터페이스를 사용해 임시 구현후 실제 구현으로 교체하는 예시
이런 인터페이스가 있을때
interface Algorithm { public int run(int n1, n2); }
임시 구현 사용
public class DummyAlgorithm implements Algorithm { @Override public int run(int n1, int n2){ return n1 + n2; } } public class Main { public static void main(String[] args){ Algorithm cal = new DummyAlgorithm(); System.out.println(cal.run(10, 20)); // 출력 30 }
나중에 실제 구현으로 교체하고 싶은 경우
public class RealAlgorithm implements Algorithm { @Override public int run(int n1, int n2){ return n1 * n2; } } public class Main { public static void main(String[] args){ Algorithm cal = new RealAlgorithm(); System.out.println(cal.run(10, 20)); // 출력 200 }
쉽게 설명하면 소통하는 두 클래스 간의 통신 규약을 구현
인터페이스는 확장(상속)이 가능함
다만 확장한 모든 인터페이스의 메서드를 구현해야함
interface inter1{ public void method1(); } interface inter2 extends inter1{ public void method2(); } // 이런식으로 상속받은 모든 언터페이스를 구현해야함 class FullInter implements inter2{ public void method1(){} public void method2(){} }
구현시 모든걸 구현하고 싶지 않으면 추상메서드로 확장하면 됨
추상 클래스는 인터페이스에 정의되어 있는 메소드들의 일부만 구현 할 수 있고 허용이 된다
하지만 추상클래스를 상속받는 구상 클래스는 모든것을 구현해야함interface inter1{ public void method1(); } interface inter2 extends inter1{ public void method2(); } // 이런식으로 추상 클래스로 선언하면 구현하고 싶은 부분만 작성해도 됨 abstract class AbstractInter implements inter2{ public void method1(){} } // 다만 실제 사용할때는 전부 구현해야함 class FullInter extends AbstractInter{ public void method1(){} public void method2(){} }
디폴트 메서드
- 오버라이드 가능
- 일반적으로 인터페이스를 연장할 때 사용
- 만약 인터페이스를 상속받는 클래스가 여러개 있을때 인터페이스를 수정하면 모든 함수가 에러 발생
그런 오류를 방지하기 위해 디폴트를 사용한 후 기본적 구현을 제공 - 협업시 타인의 코드를 망가뜨리지 않을 수 있음
'Programming > JAVA' 카테고리의 다른 글
Array, ArrayLists (0) | 2024.10.08 |
---|---|
객체지향 프로그래밍(추상 메서드, 인터페이스 정리) (0) | 2024.10.08 |
객체지향 프로그래밍(추상 클래스) (0) | 2024.10.08 |
객체지향 프로그래밍(클래스) (0) | 2024.10.08 |
참조 자료형 (0) | 2024.10.08 |
Comments