인터페이스(Interface) : 현재에 존재하는 대상을 클래스보다 추상적으로 표현하기 위한 자료형 (참조형)
인터페이스는 클래스에게 상수필드 또는 추상메소드를 상속
인터페이스는 다른 인터페이스 상속 가능 (다중상속)
인터페이스 선언하여 클래스가 상속받아 사용하는 이유
public interface Wolf {
//인터페이스는 추상메소드만 선언되므로 public abstract 제한자 생략 가능
void cryLoudly(); //인터페이스는 상수필드 또는 추상메소드만 선언 가능
void fastWalk(); } //추상메소드
public class Human {
public void speak() {
System.out.println("[인간] 대화할 수 있는 능력");
}
public void walk() {
System.out.println("[인간] 두 발로 걸을 수 있는 능력");
}
public void smile() {
System.out.println("[인간] 활짝 웃을 수 있는 능력"); }}
public class WolfHuman extends Human implements Wolf {
@Override //추상메소드 오버라이드 선언
public void cryLoudly() {
System.out.println("[늑대]큰 소리로 울부짖을 수 있는 능력");
}
@Override
public void fastWalk() {
System.out.println("[늑대]네발로 빠르게 달릴 수 있는 능력");
}
public void change() {
System.out.println("[늑대인간]변신할 수 있는 능력"); }}
public class WolfHumanApp {
public static void main(String[] args) {
WolfHuman wolfHuman=new WolfHuman();
wolfHuman.speak();
wolfHuman.walk();
wolfHuman.smile();
wolfHuman.change();
wolfHuman.cryLoudly();
wolfHuman.fastWalk();
//부모클래스로 참조변수를 생성하여 자식클래스의 객체 저장
// → 참조변수는 기본적으로 부모클래스의 메소드만 호출 가능
Human human=new WolfHuman();
human.speak();
human.walk();
human.smile();
//명시적 객체 형변환을 이용하여 참조변수로 자식클래스의 메소드 호출
((WolfHuman)human).change();
//인터페이스(Wolf)로 참조변수를 저장하여 자식클래스의 객체(WolfHuman) 저장 가능
//Wolf wolf=new WolfHuman();
//자식클래스가 같은 클래스와 인터페이스는 명시적 객체 형변환을 이용하여
//자식클래스의 객체를 공유하여 사용 가능
Wolf wolf=(Wolf)human;
//묵시적 객체 형변환(오버라이드)에 의해 자동으로 자식클래스의 메소드 호출
wolf.cryLoudly();
wolf.fastWalk(); }}
public interface Boat {
void navigate(); }
public interface Car {
void run();}
public interface BoatCar extends Boat,Car {
void floating(); }
public class BoatCarReal implements BoatCar {
@Override
public void navigate() {
System.out.println("바다를 향해하는 능력");
}
@Override
public void run() {
System.out.println("땅위를 달리는 능력");
}
@Override
public void floating() {
System.out.println("공중에 떠 있는 능력"); }}
public class BoatCarRealApp {
public static void main(String[] args) {
//상속받은 모든 인터페이스로 참조변수를 생성하여 자식클래스의 객체 저장 가능
//→ 묵시적 객체 형변환에 의해 오버라이드 선언된 자식클래스의 메소드 호출
BoatCar boatCar=new BoatCarReal();
boatCar.floating();
boatCar.navigate();
boatCar.run(); }}
//자식클래스의 메소드를 호출하기 위해서는 명시적 객체 형변환 필요
//Boat boatCar=new BoatCarReal();
//Car boatCar=new BoatCarReal();
//((BoatCarReal)boatCar).run();
public interface Jdbc {
void insert(); //추상메소드 선언
void update();
void delete();
void select(); }
public class JdbcMysql implements Jdbc {
@Override //추상메소드 오버라이드 선언
public void insert() {
System.out.println("[mysql]학생정보를 삽입하는 메소드");
}
@Override
public void update() {
System.out.println("[mysql]학생정보를 변경하는 메소드");
}
@Override
public void delete() {
System.out.println("[mysql]학생정보를 삭제하는 메소드");
}
@Override
public void select() {
System.out.println("[mysql]학생정보를 검색하는 메소드"); }}
public class JdbcOracle implements Jdbc {
@Override //추상메소드 오버라이드 선언
public void insert() {
System.out.println("[oracle]학생정보를 삽입하는 메소드");
}
@Override
public void update() {
System.out.println("[oracle]학생정보를 변경하는 메소드");
}
@Override
public void delete() {
System.out.println("[oracle]학생정보를 삭제하는 메소드");
}
@Override
public void select() {
System.out.println("[oracle]학생정보를 검색하는 메소드"); }}
public class JdbcApp {
public static void main(String[] args) {
/* 자식클래스 참조변수에 객체 저장할 경우
JdbcMysql mysql=new JdbcMysql();
mysql.insert();
mysql.update();
mysql.delete();
mysql.select();
//시스템 변경에 의해 클래스(mysql로) 교체시 메소드 호출 명령 변경
// → 객체간의 결합도가 높기 때문에 유지보수의 효율성 감소
JdbcOracle oracle=new JdbcOracle();
oracle.insert();
oracle.update();
oracle.delete();
oracle.select();
*/
//객체간의 결합도를 낮추기 위해 참조변수는 인터페이스를 이용하여 선언
//Jdbc jdbc=new JdbcMysql();
//시스템 변경에 의해 클래스 교체시 메소드 호출 명령 미변경
// → 객체간의 결합도를 낮춰 유지보수의 효율성 증가
Jdbc jdbc=new JdbcOracle();
//참조변수로 인터페이스의 추상메소드를 호출하면 묵시적 객체 형변환에 의해
//참조변수에 저장된 자식클래스 객체의 메소드를 참조하여 호출
jdbc.insert();
jdbc.update();
jdbc.delete();
jdbc.select(); }}
public interface Printable {
void print(); //추상메소드 : 자식클래스에서 반드시 오버라이드 선언
default void scan() {
System.out.println("[에러]스캔 기능을 제공하지 않습니다."); }}
public class PrintSingle implements Printable { //Printable 인터페이스 상속
@Override //추상메소드 오버라이드
public void print() {
System.out.println("[프린트]문서를 출력합니다."); }}
public class PrintMulti implements Printable {//Printable 인터페이스 상속
@Override //추상메소드 오버라이드
public void print() {
System.out.println("[복합기]문서를 출력합니다.");
}
@Override //기본메소드 오버라이드
public void scan() {
System.out.println("[복합기]문서를 스캔합니다."); }
public class PrintableApp {
public static void main(String[] args) {
//기본메소드를 사용하기 위해서는 참조변수를 인터페이스로 선언
Printable printOne=new PrintSingle();
printOne.print();
printOne.scan(); //부모 인터페이스의 기본메소드 호출
Printable printTwo=new PrintMulti();
printTwo.print();
printTwo.scan(); }} //오버라이드된 메소드 호출
public interface InterfaceOne {
int INSERT=1,UPDATE=2,DELETE=3,SELECT=4;}
public interface InterfaceTwo {
int ADD=1,MODIFY=2,REMOVE=3,SEARCH=4;}
public class InterfaceApp {
public static void main(String[] args) {
//인터페이스에 선언된 상수필드값 출력 (필드에 저장된 값이 제공되어 출력)
System.out.println("삽입 = "+InterfaceOne.INSERT);//삽입 = 1
System.out.println("변경 = "+InterfaceOne.UPDATE);
System.out.println("삭제 = "+InterfaceOne.DELETE);
System.out.println("검색 = "+InterfaceOne.SELECT);
System.out.println("삽입 = "+InterfaceTwo.ADD);//삽입 = 1
System.out.println("변경 = "+InterfaceTwo.MODIFY);
System.out.println("삭제 = "+InterfaceTwo.REMOVE);
System.out.println("검색 = "+InterfaceTwo.SEARCH);
//상수필드에 저장된 값과 동일한 자료형(원시형)의 변수를 생성하여 상수 저장 가능
int choice=InterfaceOne.INSERT; //int choice=1;
System.out.println("선택 = "+choice);
switch (choice) {
//case InterfaceOne.INSERT:
case InterfaceTwo.ADD:
System.out.println("# 학생정보를 삽입합니다. #");
break;
case InterfaceOne.UPDATE:
System.out.println("# 학생정보를 변경합니다. #");
break;
case InterfaceOne.DELETE:
System.out.println("# 학생정보를 삭제합니다. #");
break;
case InterfaceOne.SELECT:
System.out.println("# 학생정보를 검색합니다. #");
break; }}}
열거형 (Enumerate) : 상수만을 선언하기 위한 자료형(참조형)
열거형의 상수필드에는 0부터 1씩 증가되는 저장값이 기본값으로 자동 저
열거형에 선언된 상수필드값 출력 시 상수의 이름이 제공되어 출력
열거형에 선언된 상수를 저장하기 위해서는 반드시 열거형을 이용하여 변수 선언
public enum EnumOne {
INSERT, UPDATE, DELETE, SELECT; } //상수필드 선언
public enum EnumTwo {
ADD, MODIFY, REMOVE, SEARCH; } //상수필드 선언
public class EnumApp {
public static void main(String[] args) {
//열거형에 선언된 상수필드값 출력 (상수의 이름이 제공되어 출력)
// → 프로그램에서 상수가 값을 대표하는 이름으로 사용 가능
System.out.println("삽입 = "+EnumOne.INSERT);//삽입 = INSERT
System.out.println("변경 = "+EnumOne.UPDATE);
System.out.println("삭제 = "+EnumOne.DELETE);
System.out.println("검색 = "+EnumOne.SELECT);
System.out.println("삽입 = "+EnumTwo.ADD); //삽입 = ADD
System.out.println("변경 = "+EnumTwo.MODIFY);
System.out.println("삭제 = "+EnumTwo.REMOVE);
System.out.println("검색 = "+EnumTwo.SEARCH);
//열거형에 선언된 상수를 저장하기 위해서는 반드시 열거형을 이용하여 변수 선언
// → 상수가 선언된 열거형을 하나의 자료형으로 사용 가능
//int choice=EnumOne.INSERT;//에러 발생
EnumOne choice=EnumOne.INSERT;//EnumOne 자료형에 선언된 상수만 저장 가능한 변수
System.out.println("선택 = "+choice); //선택=INSERT
//나열형으로 선언된 참조변수에 비교값은 같은 자료형의 상수만 사용하여 비교 가능
switch (choice) {
case INSERT:
//case ADD: EnumOne 자료형에 선언된 상수만 저장 가능하기 때문에 에러발생
System.out.println("# 학생정보를 삽입합니다. #");
break;
case UPDATE:
System.out.println("# 학생정보를 변경합니다. #");
break;
case DELETE:
System.out.println("# 학생정보를 삭제합니다. #");
break;
case SELECT:
System.out.println("# 학생정보를 검색합니다. #");
break; }}}
public enum Compass {
//EAST, WEST, SOUTH, NORTH; :매개변수 없으므로 기본생성자 제공
//매개변수가 선언된 생성자를 이용하여 상수필드 선언
EAST("동"),WEST("서"),SOUTH("남"),NORTH("북");//필드, 생성자 선언 필수
//상수필드의 자료형 또는 상수필드에 저장되는 값을 변경하기 위해서는 필드 선언
// → 필드에 저장된 값을 이용하여 상수필드값을 변경하기 위해 반드시 생성자 선언
private final String value; //상수필드를 표현하기 위한 대표필드
//private final 제한자로 선언된 대표필드에 초기값을 설정하기 위한 생성자
// → 생성자를 반드시 은닉화 선언
// → 매개변수로 전달값을 대표필드에 저장 (상수필드 초기화)
private Compass(String value) {
this.value=value;
}
//대표필드에 대한 Getter 메소드 (상수필드에 저장된 값을 반환하는 메소드)
public String getValue() {
return value; }}
public class CompassApp {
public static void main(String[] args) {
//상수필드값 출력 - 상수필드명을 제공받아 출력
System.out.println("동쪽 = "+Compass.EAST);//동쪽 = EAST
System.out.println("서쪽 = "+Compass.WEST);
System.out.println("남쪽 = "+Compass.SOUTH);
System.out.println("북쪽 = "+Compass.NORTH);
//대표필드값을 반환받아 출력 (상수필드에 저장된 값을 제공받아 출력)
System.out.println("동쪽 = "+Compass.EAST.getValue());//동쪽 = 동
System.out.println("서쪽 = "+Compass.WEST.getValue());
System.out.println("남쪽 = "+Compass.SOUTH.getValue());
System.out.println("북쪽 = "+Compass.NORTH.getValue());
//EnumType.values() : 열거형에 선언된 모든 상수필드를 배열로 변환하는 메소드
for(Compass compass:Compass.values()) {
//EnumType.ordinal() : 상수필드를 구분하기 위한 첨자를 반환하는 메소드
System.out.println(compass+"="+compass.getValue()+":"+compass.ordinal());
}}} //EAST=동:0 , WEST=서:1 ···