12. 인터페이스

2023. 3. 27. 17:49Lang/Java

728x90
반응형

1. 인터페이스 란

  • 일종의 추상 클래스

  • 추상메서드와 상수만을 멤버로 가질 수 있다

    • 일반메서드나 멤버변수를 가질 수 없다
    • 메서드 목록만을 가지고 있다
    • 뼈대로만 구성
  • 상속받을 클래스가 구현해야 할 기능을 나열

  • 일종의 약속, 최소한의 계약

    interface 인터페이스명{}

  • 모든 멤버변수는 public static final, 생략가능

  • 모든 메서드는 public abstract, 생략가능

2. 인터페이스 구현

  • 상속받을 클래스에서

    class 클래스명 implements 인터페이스명{}

    • extends를 쓰지않고 implements를 쓴다.
interface IAnimal{
    public abstract void sound();
    void display(); //접근제한자 생략 가능
}

//IAnimal 인터페이스를 구현하는 자식 클래스
class Cat implements IAnimal{
    public void sound() {
        System.out.println("야옹");
    }
    public void display() {
        System.out.println("cat메서드");
    }
}

//IAnimal의 display를 구현하지 않아 추상클래스
abstract class Dog implements IAnimal{
    public void sound() {
        System.out.println("멍멍");
    }
}

class Cow implements IAnimal{
    public void sound() {
        System.out.println("음메");
    }
    /*
    void display() { //error : 부모메서드를 오버라이딩 할 때 접근제한자는 부모보다 같거나 넓어야 한다
        System.out.println("Cow 메서드");
    }*/
    public void display() {
        System.out.println("Cow메서드");
    }

}

public class InterfaceTest {

    public static void main(String[] args) {
        // IAnimal an = new IAnimal(); // error 인터페이스는 객체 생성 불가
        Cat c = new Cat();
        c.sound();
        c.display();

        // Dog d = new Dog(); // error 추상클래스 객체 생성 불가

        IAnimal an = new Cow();
        an.sound();
        an.display();

    }
}
  • 인터페이스의 구현과 부모클래스의 상속 동시 가능

    class child extneds fater implements interface{}

class Tv{
    public void onTv() {
        System.out.println("전원 on");
    }
}
interface Computer{
    public void dataReceive();
}

//상속과 구현을 동시에
class IPTv extends Tv implements Computer{
    public void dataReceive() {
        System.out.println("영상 데이터 수신 중");
    }
    public void powerOn() {
        dataReceive();
        onTv();
    }
}

public class IpTvTest {

    public static void main(String[] args) {
        IPTv t = new IPTv();
        t.powerOn();
    }
}

3. 인터페이스 상속

  • 인터페이스는 인터페이스만 상속받을 수 있다
  • 다중 상속 가능
interface Movable{}
interface Attackable{}
interface Fightable extends Movable, Attackable{}
  • 하나의 클래스가 여러개의 인터페이스를 구현할 수 있다
interface TV{}
interface Computer{}
class IPTV implements TV, Computer{}
interface Tv2{
    public void onTv();
}
interface Computer2{
    public void dataReceive();
}

//인터페이스 다중 상속 가능
class IPTv2 implements Tv2, Computer2{
    public void dataReceive() {
        System.out.println("영상 데이터 수신 중");
    }
    public void onTv() {
        System.out.println("tv영상 출력");
    }
    public void powerOn() {
        dataReceive();
        onTv();
    }
}

public class IpTvTest2 {

    public static void main(String[] args) {
        IPTv2 t = new IPTv2();
        t.powerOn();
    }
}
  • 종합
interface Attackable{
    /**
     * 지정된 대상을 공격하는 기능
     * @param u
     */
    public abstract void attack(Unit u);
}

interface Movable{
    /**
     * 지정된 위치로 이동하는 기능
     * @param x
     * @param y
     */
    void move(int x, int y);
}

//인터페이스끼리의 상속 - extends 사용, 다중상속 가능
interface Fightable extends Attackable, Movable{

}

abstract class Unit{
    protected int x, y; //위치
    protected int currentHP; //체력

    Unit(int x, int y, int currentHP){
        this.x = x;
        this.y = y;
        this.currentHP = currentHP;
    }
}

class Fighter extends Unit implements Fightable{
    public Fighter(int x, int y, int currentHP) {
        super(x,y,currentHP);
    }
    public void move(int x, int y) {
        this.x = x;
        this.y = y;
        System.out.println(x+","+y+"위치로 이동");
    }
    public void attack(Unit u) {
        System.out.println(u.x+","+u.y+"위치의"+u.currentHP+"체력 유닛 공격");
    }
}

public class UnitTest {

    public static void main(String[] args) {
        Fighter f = new Fighter(10,25,350);
        f.move(30,40);

        f.attack(new Fighter(30,40,240));
        f.move(70, 80);
        f.attack(new Fighter(70,80,100));
    }
}

4. 인터페이스의 장점

  • 표준화가 가능하다

    • 인터페이스를 기본 틀로, 일관되고 정형화된 프로그램의 개발 가능
  • 관계없는 클래스들에게 관계를 맺어줄 수 있다

    • 상속관계도 아닌, 같은 조상을 가지고 있지 않은 클래스도 인터페이스를 통해 공통적으로 구현, 관계 형성 가능
  • 독립적인 프로그래밍 가능

    • 클래스 간 직접적인 관계를 인터페이스를 통해 간접적인 관계로 변경
    • 클래스의 변경이 다른 클래스에게 영향을 미치지 않도록 독립적인 프로그래밍 가능
  • ex) 직접적인 관계

/*
 * 직접적인 관계의 두 클래스 A,B
 * 단점 : 한쪽이 provider 되면 다른쪽도 변경
 */
class A{
    /*
    public void methodA(B b) {
        b.methodB();
    }*/
    public void methodA(C c) {
        c.methodC();
    }
}
class B{
    public void methodB() {
        System.out.println("B클래스 메서드");
    }
}
class C{
    public void methodC() {
        System.out.println("C 클래스 메서드");
    }
}

public class InterfaceTest2 {

    public static void main(String[] args) {
        A a = new A();
        //메서드A 호출
        //a.methodA(new B());

        //c클래스를 추가해 c를 호출하고 싶은 경우
        //a클래스의 메서드 구현부를 변경해주어야 한다
        a.methodA(new C());
    }
}
  • ex) 간접적인 관계
/*
 * 간접적인 관계의 두 클래스 (A-I-B)
 * 클래스 A가 클래스 B를 직접 호출하지 않고 인터페이스를 매개체로 하는 경우
 * 클래스A는 인터페이스 I하고만 직접적인 관계에 있기 때문에 클래스B의 변경에
 * 영향을 받지 않는다
 */

interface I{
    void method();
}
class AA{
    public void methodA(I i) {
        i.method();
    }
}
class BB implements I{
    public void method() {
        System.out.println("B클래스 메서드");
    }
}
class CC implements I{
    public void method() {
        System.out.println("C클래스 메서드");
    }
}
public class InterfaceTest3 {

    public static void main(String[] args) {
        AA a = new AA();
        //methodA()호출
        a.methodA(new BB());

        //c클래스를 추가해 c를 호출하고 싶은 경우
        //a클래스의 메서드 구현부를 변경할 필요 없다
        a.methodA(new CC());
    }
}

5. 인터페이스 기반의 상수 표현

  • 인터페이스 내 변수는 무조건 public static final로 선언되는 특성을 활용
interface Week{
    int MON=1, THE=2, WED=3, THU=4, FRI=5, SAT=6, SUN=7;
} // 인터페이스 활용

class Week2 {
    public static final int MON=1;
    public static final int TUE=2;
    public static final int WED=3;
    public static final int THU=4;
    public static final int FRI=5;
    public static final int SAT=6;
    public static final int SUN=7;
} // 클래스로 선언할 경우

public class InterfaceConst {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("요일 선택:1.월 ~ 7.일");
        int type = sc.nextInt();

        switch(type) {
        case Week.MON :
            System.out.println("주간회의");
            break;
        case Week.THE :
            System.out.println("프로젝트 기획 회의");
            break;
        case Week.WED :
            System.out.println("진행사항 보고");
            break;
        case Week.THU :
            System.out.println("사내 축구");
            break;
        case Week.FRI :
            System.out.println("프로젝트 마감");
            break;
        case Week.SAT :
            System.out.println("가족");
            break;
        case Week.SUN :
            System.out.println("휴일");
            break;        
        }
    }
}
728x90
반응형

'Lang > Java' 카테고리의 다른 글

14. 예외  (0) 2023.03.27
13. 패키지  (0) 2023.03.27
11. 추상  (0) 2023.03.27
10. 다형성  (0) 2023.03.27
9. 상속  (0) 2023.03.27