Binary World

JAVA CLASS : 인터페이스(Interface) 본문

개발자의 길/JAVA

JAVA CLASS : 인터페이스(Interface)

모쿠 2017. 1. 4. 13:24

<인터페이스>


* 여러 명이서 코드를 작성할 때 서로 간의 규약만 정의하여 작성된 코드를 컴파일 할 수 있게 다리 역할을 해주는 역할을 인터페이스가 해준다.

* 클래스와 상속의 차이

- 상속은 다중 상속이 불가능하지만, 구현(인터페이스)는 다중 구현이 가능하다.

- 상속 : IS-A 관계가 성립할 때

   스마트TV는 TV다. (SmartTV is a TV.) (o)

   class SmartTv Extends BasicTV {...}

- 구현(인터페이스): HAS-A 관계가 성립할 때

   TV는 리모콘을 가지고 있다. (TV has a remote control.)

   class BasicTV implements RemoteControl { ... }


* Java 8 이전 버전의 인터페이스

 인터페이스(interface) : 

 1. 모든 메소드는 public abstract로 선언

   -> public abstract 수식어는 생략 가능 

 2. 모든 멤버 변수는 public static final로 선언

   -> public static final 수식어는 생략 가능

 3. 인터페이스를 선언할 때는 interface 키워드를 사용

 4. 인터페이스를 구현(상속)하는 클래스는 implements 키워드를 사용

 5. 클래스는 다중 상속이 불가능

    (예) class Child extends Parent1, Parent2

 인터페이스를 구현하는 숫자는 제한이 없음.

    (예) class Child implements Inter1, Inter2, ... (O)


Java 8 버전부터 바뀐 인터페이스:

 인터페이스가 가질 수 있는 멤버들:

 1. public static final 필드(멤버 변수) - Java 7 버전과 동일

 2. public abstract 메소드 - Java 7 버전과 동일

 3. default 메소드:

    - 본체(body)가 구현되어 있는 메소드

    - default 키워드를 사용해서 선언

    - 인스턴스가 생성되어야만 사용할 수 있는 메소드

 4. static 메소드:

    - 본체(body)가 구현되어 있는 메소드

    - static 키워드 사용, 인스턴스 생성 없이 사용 가능한 메소드



<프로그램 코드>


1. 인터페이스의 기본 사용


* DatabaseQuery.java (인터페이스 변수와 메소드 선언)


package edu.java.interface01;


public interface DatabaseQuery {

// 인터페이스의 멤버 변수: public static final

public static final int DATABASE_VERSION = 1;

// 인터페이스의 메소드: public abstract 

public abstract int insert(String id, String pw);

// abstract 생략이 가능


} // end interface DatabaseQuery 



* DummyImple.java


package edu.java.interface01;


// UI 팀에서 임시로 테스트하기 위한 용도로 사용할 클래스

// 인터페이스를 구현할 때는 implements 키워드

public class DummyImple implements DatabaseQuery{


@Override

public int insert(String id, String pw) {

// 임시 테스트 용

return 0;

}

} // end class DummyImple 



* Main01.java


package edu.java.interface01;


import java.util.Scanner;


// UI 팀에서 작성할 UI 클래스

public class Main01 {


public static void main(String[] args) {

// UI

System.out.println("DB 버전: " + DatabaseQuery.DATABASE_VERSION);


// 사용자로부터 id, pw를 입력받음

// 입력받은 데이터를 DB팀이 작성할 insert(id, pw) 메소드를 호출함

Scanner sc = new Scanner(System.in);

System.out.println("아이디 입력>");

String id = sc.nextLine();

System.out.println("비밀번호 입력>");

String pw = sc.nextLine();

sc.close();


// DummyImple db = new DummyImple();

// DatabaseQuery db = new DummyImple(); // Interface를 상속받음, 다형성

DatabaseQuery db = new OracleDatabaseQuery();

int result = db.insert(id, pw);

if (result > 0) {

System.out.println("INSERT 성공");

} else {

System.out.println("INSERT 실패");


}


} // end main()


} // end class Main01 



* OracleDatabaseQuery.java


package edu.java.interface01;


// DB팀에서 실제로 구현하는 클래스

public class OracleDatabaseQuery implements DatabaseQuery {


@Override

public int insert(String id, String pw) {

System.out.println("오라클 DB 연결");

System.out.println("SQL 문장 작성/실행");

System.out.println("SQL 실행 결과 처리");

return 1;

}




* 출력화면


DB 버전: 1

아이디 입력>

aa

비밀번호 입력>

bb

오라클 DB 연결

SQL 문장 작성/실행

SQL 실행 결과 처리

INSERT 성공




2. default 메소드 사용


* TestIntf.java (인터페이스)


package edu.java.interface02;


public interface TestIntf {

// 1. public static final 멤버 변수(필드)

public static final int MAX = 100;

// 2. public abstract 메소드

public abstract int insert(String id, String pw);

// 3. default 메소드

public default void connect() {

System.out.println("DB 연결 성공");

}

// 4. static 메소드

public static void createDB() {

System.out.println("DB 생성 성공");

}


} // end interface TestIntf 



* TestImple.java (인터페이스 구현(상속)


package edu.java.interface02;


public class TestImple implements TestIntf{

@Override

public int insert(String id, String pw) {

System.out.println("DB INSERT 실행");

return 0;

}



* Main02.java (메인 클래스)


package edu.java.interface02;


public class Main02 {


public static void main(String[] args) {

// 인터페이스의 상수 사용

// 인터페이스.상수이름

System.out.println(TestIntf.MAX);

// 인터페이스의 static 메소드 사용:

// 인터페이스.메소드 이름

TestIntf.createDB();

// 인터페이스를 구현하는 클래스의 인스턴스 생성

TestImple test = new TestImple();

test.connect();

// 추상 메소드(public abstract 메소드) 사용

test.insert("guest", "guest");


} // end main()


} // end class Main02 



* 출력화면


100

DB 생성 성공

DB 연결 성공

DB INSERT 실행 



3. 인터페이스의 다중 상속


* Main03.java


package edu.java.interface03;


// 클래스는 다중 상속이 불가능하지만, 인터페이스는 여러개를 구현하는 것이 가능

interface Test1 {

public abstract void Test1();

} // end interface Test1


interface Test2 {

public abstract void Test2();

} // end interface Test2


class TestImple implements Test1, Test2 {


@Override

public void Test2() {

System.out.println("테스트2");


}


@Override

public void Test1() {

System.out.println("테스트1");


}


} // end TestImple


public class Main03 {

public static void main(String[] args) {

// TestImple 클래스의 인스턴스 생성

TestImple imple1 = new TestImple();

imple1.Test1();

imple1.Test2();

Test1 imple2 = new TestImple();

imple2.Test1();

((Test2) imple2).Test2(); // test2는 사용할 수없기 때문에 강제 형변환을 통해서 사용


} // end main()


} // end class Main03 



* 출력화면


테스트1

테스트2

테스트1

테스트2 

 


4. 인터페이스의 상속


* ParentIntf.java (부모 인터페이스)


package edu.java.interface04;


public interface ParentIntf {

public abstract void test1();


} // end interface ParentIntf 



* ChildIntf.java (자식 인터페이스)


package edu.java.interface04;


// 인터페이스는 다른 인터페이스를 상속하는 것이 가능


public interface ChildIntf extends ParentIntf {

public abstract void test2();


} // end interface ChildIntf 



* Main04


package edu.java.interface04;


// 상속받는 인터페이스의 구현(implementation)

// 부모 인터페이스를 구현하는 클래스

class TestImple1 implements ParentIntf{


@Override

public void test1() {

System.out.println("부모 인터페이스 메소드 1");

}

} // end class TestImple1


// 자식 인터페이스를 구현하는 클래스

class TestImple2 implements ChildIntf{


@Override

public void test1() {

System.out.println("부모 인터페이스 메소드 2");

}


@Override

public void test2() {

System.out.println("자식 인터페이스 메소드 2");

}

}

public class Main04{


public static void main(String[] args) {

TestImple1 imple1 = new TestImple1();

imple1.test1();

TestImple2 imple2 = new TestImple2();

imple2.test1();

imple2.test2();


} // end main()


} // end class Main04 



* 출력화면


부모 인터페이스 메소드 1

부모 인터페이스 메소드 2

자식 인터페이스 메소드 2 



5. 다중 인터페이스 선언 및 인터페이스 타입의 배열 선언


* Audio.java (오디오의 간단한 기능)


package edu.java.interface06;


// Audio has a RemoteControl

public class Audio implements RemoteControl {


@Override

public void turnOn() {

System.out.println("Audio start");

}


@Override

public void turnOff() {

System.out.println("Audio end");


}


} 



* BasicTv.java (TV의 간단한 기능)


package edu.java.interface06;


// BasicTv has a RemoteControl

public class BasicTv implements RemoteControl {


@Override

public void turnOn() {

System.out.println("TV 켜짐");

}


@Override

public void turnOff() {

System.out.println("TV 끔");

}


} // end class BasicTv 



* RemoteControl.java (리모콘 기능)


package edu.java.interface06;


public interface RemoteControl {


public abstract void turnOn();

public abstract void turnOff();

}



* Main06.java


package edu.java.interface06;


public class Main06 {


public static void main(String[] args) {

// BasicTv 클래스의 인스턴스 생성

BasicTv tv1 = new BasicTv();

tv1.turnOn();

tv1.turnOff();

// Audio 클래스의 인스턴스 생성

Audio audio1 = new Audio();

audio1.turnOn();

audio1.turnOff();

System.out.println();

//다형성

RemoteControl rc1 = new BasicTv();

rc1.turnOn();

rc1.turnOff();

RemoteControl rc2 = new Audio();

rc2.turnOn();

rc2.turnOff();

// 인터페이스 타입의 배열

RemoteControl[] rc = new RemoteControl[2];

rc[0] = tv1;

rc[1] = audio1;

} // end main()


} // end class Main06 



* 출력화면 


TV 켜짐

TV 끔

Audio start

Audio end


TV 켜짐

TV 끔

Audio start

Audio end 


Comments