자바 인터페이스 구현 예제 - jaba inteopeiseu guhyeon yeje

자바 인터페이스를 만들고 사용하는 방법에 대해 알아 본다.  대규모 프로젝트에서는 수많은 개발자들이 개발을 하게 된다.  소스 코드의 난잡화 방지라고 해야할까... 분류를 하자면 대분류라고 치고, 번역기를 개발한다고 하면, 어떤 개발자는 영어, 어떤 개발자는 한글을 개발한다고 치면, 대분류 차원에서는 번역이라는 큰 틀에서 개발을 하지만 서로 다르게 구현하게 된다. 이럴경우 개발자마다 클래스명, 메소드명이 다른 현상이 생기고 나중에 유지보수가 힘들어지게 된다. 이를 방지하기 위해  implements할 인터페이스를 만든다. 또한 자바는 C언어처럼 다중 상속을 클래스단에서는 지원하지 않는다. 하지만 인터페이스를 사용하면 다중 상속이 가능하다. 

■인터페이스 생성하기

인터페이스는 본문 즉, 코드 내용은 없고, 메소드 선언만 있다. 세탁기 프로그램을 만들어 보자.

package edu.sample; public interface WashingMachine { public void startButtonPressed(); public void pauseButtonPressed(); public void stopButtonPressed(); public int changeSpeed(int speed); }package edu.sample; public interface dryCouse { public void dry(); }

인터페이스를 사용해보자

package edu.sample; public class LGWashingMachine implements WashingMachine{ @Override public void startButtonPressed() { System.out.println("세탁기가 빨래를 시작하였습니다."); } @Override public void stopButtonPressed() { System.out.println("세탁기가 빨래를 중지하였습니다."); } @Override public void pauseButtonPressed() { System.out.println("세탁기가 빨래를 일시 중지하였습니다."); } @Override public int changeSpeed(int speed) { int rtnSpeed = 0; switch(speed) { case 1: rtnSpeed = 20; break; case 2: rtnSpeed = 50; break; case 3: rtnSpeed = 100; break; } return rtnSpeed; } }

implements를 사용하여 LGWashingMachine 클래스 선언시 인터페이스 사용을 선언한다. 인터페이스로 선언했던 메소드를 오버라이드 하여 메소드 본문에 들어갈 코드를 구현하면 된다.

인터페이스 테스트

package edu.sample; public class TestWashingMachine { public static void main(String[] args) { LGWashingMachine washinMachine = new LGWashingMachine(); washinMachine.startButtonPressed(); System.out.println("세탁기의 속도는 " + washinMachine.changeSpeed(3)); } }

■ 인터페이스 다중상속 예제

package edu.sample; public class LGWashingMachine implements WashingMachine, dryCouse{ @Override public void startButtonPressed() { System.out.println("세탁기가 빨래를 시작하였습니다."); } @Override public void stopButtonPressed() { System.out.println("세탁기가 빨래를 중지하였습니다."); } @Override public void pauseButtonPressed() { System.out.println("세탁기가 빨래를 일시 중지하였습니다."); } @Override public int changeSpeed(int speed) { int rtnSpeed = 0; switch(speed) { case 1: rtnSpeed = 20; break; case 2: rtnSpeed = 50; break; case 3: rtnSpeed = 100; break; } return rtnSpeed; } @Override public void dry() { System.out.println("세탁기 완료되어 건조하기 시작하였습니다."); } }

인터페이스는 공용 컴포넌트나 유틸 개발에 아주 효과적이다. 

쿠팡 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음

인터페이스의 개념

인터페이는 일종의 추상클래스이긴 하나 멤버의 주류가 추상메서드이다.

다른 의미로는 객체사용 설명서 라고도 한다.

실제로 구현된 것은 아무것도 없는 설계도라고 보면 된다.

인터페이스의 멤버

 -상수 - 부수적 개념

 -추상메서드 -인터페이스의 본질

 -정적 메서드(JDK1.8)

 -디폴트 메서드(JDK1.8)

생성자가 없다.  하여, 인스턴스를 만들수 없다.

클래스 작성에 도움을 준다.

표준을 제시하여, 그 규칙에 맞게끔 구현하도록 한다.

인터페이스 작성(선언)

class대신 interface로 사용하는 것 외 , 클래스  작성과 동일하다.

하지만, 구성요소는 추상 메서드와 상수가 있으며 JDK1.8부터

정적 메서드, 디폴트 메서드가 추가되었다.

상수는 static final속성을 지니고 있으며, 추상 메서드는 abstact속성을 

가진다. 또한 생략가능(컴파일러가 알아서 추가해줌)

인터페이스도 클래스와 동일하게 상속이 가능하다.(다중상속 가능)

-~able => 인터페이스로 유추

-object와 같은 최고 조상이 없다.

인터페이스 구현

인터페이스를 구현 한다는 것은 클래스를 상소하는 것과 동일하다고 생각하자. 하여,

인터페이스도 일종의 조상이다.(다형성의 개념이 적용됨)

단.,extends를 사용하지말고 implements를 사용한다.

구현클래스는 반드시 인터페이스에 선언되어 있는 추상 메서드를 재정의 해야 한다.

상속과 동시에 구현도 가능하다.

인터페이스 예제

Creature.java

package kr.co.kihd.interfacee; //인터페이스의 본질은 추상메서드임. public interface Creature { //인터페이스에서 static final은 부수적 개념 int MAX = 10; //static final 생략가능하다. 컴파일시에 컴파일러가 붙여준다. public void method(); //abstract 생략이 가능하다. 컴파일시에 컴파일러가 붙여준다. }

Member.java

package kr.co.kihd.interfacee; //Creature인터페이스를 구현한 클래스 public class Member implements Creature{ @Override public void method() { System.out.println("인터페이스 Creature를 구현한 Member의 method() 호출됨."); } public void method1() { System.out.println("Member 클래스에 있는 멤버메서드이다."); } }

Person.java

package kr.co.kihd.interfacee; public class Person implements Creature{ @Override public void method() { System.out.println("인터페이스 Creature를 구현한 Member의 method() 호출됨."); } public void method2(){ System.out.println("Person 클래스에 있는 멤버메서드이다."); } }

CreatureTest.java

package kr.co.kihd.interfacee; public class CreatureTest { public static void main(String[] args) { Member member = new Member(); member.method(); member.method1(); System.out.println(); //인터페이스도 일종의 조상이다. 다형성 개념이 적용된다. Creature creature = new Member(); //인터페이스 필드의 다형성 creature.method(); System.out.println(); //원래 타입을 벗어나지 못하므로 Member클래스의 멤버메서드는 호출불가. //creature.method1(); Person person = new Person(); person.method(); person.method2(); creature = new Person(); creature.method(); //상수접근시 인터페이스명.상수명으로 접근함. System.out.println(Creature.MAX); } }

인터페이스의 다형성

인터페이스 타입의 참조변수로 인터페이스를 구현한 클래스의 인스턴스 참조 가능

인터페이스를 매개변수 타입으로 설정할 수가 있다. 단, 매개변수로 쓸 수 있는 것은 

인터페이스를 구현한 클래스만 올 수가 있다.(중요)

인터페이스를 리턴 타입으로 설정할 수가 있다. 단,  리턴타입으로 올 수 있는 것은

인터페이스를 구현한 클래스만 올 수가 있다.(중요)

인터페이스의 장점

개발시간이 상당히 단축된다.

-인터페이스만 만들어지면, 메서드의 선언부를 이용하여 개발하는 쪽과 구현클래스를

작성하는 쪽 이렇게 독립적으로 프로그래밍 가능하다.

표준화가 가능하다.(컬랙션 프레임워크를 배우면 더욱 이해가 빠르다)

-인터페이스를 만든다는 것은 구현 클래스에서 모두 메서드를 구현해야 하므로 

보다 일관된 개발이 이루어져 정형화가 이루어진다.

서로 관계없는 클래스를 간접적 관계를 만들어 줄 수가 있다.

ex) List계열, Set계열, Map계열 등

인터페이스의 이해

인터페이스는 두대상 사이의 중간에서 소통, 대화를 하게끔 하는 역할을 한다.

ex 버튼. 윈도우 등

아울러, 메서드의 선언과 분리를 가능하게 한다.

리모컨 예제

package kr.co.kihd.interfacee2; public interface Remotecontrol { //상수 (static final) int MAX_VOLUMN = 10; int MIN_VOLUMN = 0; //추상메서드 3개 선언 (abstract) public void turnOn(); //정의부만 있어야함 public void turnOff(); public void setVolume(int volume); } package kr.co.kihd.interfacee2; public class Audio implements Remotecontrol{ private int volume; @Override public void turnOn() { System.out.println("Audio를 켭니다."); } @Override public void turnOff() { System.out.println("Audio를 끕니다."); } @Override public void setVolume(int volume) { //볼륨이 0~10사이에서만 움직일 것으로 프로그래밍함. if(volume > Remotecontrol.MAX_VOLUMN) { System.out.println("Audio 볼륨의 최대치 값은 10입니다."); this.volume = Remotecontrol.MAX_VOLUMN; }else if(volume < Remotecontrol.MIN_VOLUMN){ System.out.println("Audio 볼륨의 최소치 값은 0입니다."); this.volume = Remotecontrol.MIN_VOLUMN; }else { this.volume = volume; } System.out.println("현재 Audio 볼륨 : " + this.volume); } } package kr.co.kihd.interfacee2; public class Television implements Remotecontrol{ private int volume; @Override public void turnOn() { System.out.println("TV를 켭니다."); } @Override public void turnOff() { System.out.println("TV를 끕니다."); } @Override public void setVolume(int volume) { //볼륨 0~10사이 값으로 유지 if(volume > Remotecontrol.MAX_VOLUMN) { System.out.println("TV 볼륨의 최대치 값은 10입니다."); this.volume = Remotecontrol.MAX_VOLUMN; }else if(volume < Remotecontrol.MIN_VOLUMN) { System.out.println("TV 볼륨의 최소치 값은 10입니다."); this.volume = Remotecontrol.MIN_VOLUMN; }else { this.volume = volume; } System.out.println("TV에 현제 볼륨 : " + this.volume); } } package kr.co.kihd.interfacee2; public class RemoteTest { public static void main(String[] args) { //인터페이스도 일종의 조상, 그래서 (참조변수)필드의 다형성이 허용된다. Remotecontrol rControl = new Television(); rControl.turnOn(); rControl.setVolume(15); rControl.setVolume(-100); rControl.turnOff(); System.out.println(); rControl = new Audio(); rControl.turnOn(); rControl.setVolume(15); rControl.setVolume(-50); rControl.turnOff(); } }

독립 클래스 (인터페이스 매개변수의 다형성)

직접 객체를 매개변수로 생성하여 넘기는 방법

package kr.co.kihd.interfacee3; public interface Vehiclable { //추상메서드 3개 선언 public void run(); public void stop(); public void setSpeed(int speed); } package kr.co.kihd.interfacee3; public class Taxi implements Vehiclable{ private int speed; @Override public void run() { System.out.println("택시가 "+this.speed+"Km로 달립니다."); } @Override public void stop() { System.out.println("택시가 멈춥니다."); } @Override public void setSpeed(int speed) { if(speed < 0) { System.out.println("속도는 음수일리가 없죠!"); return; } this.speed = speed; } } package kr.co.kihd.interfacee3; public class Bus implements Vehiclable{ private int speed; @Override public void run() { System.out.println("버스가 "+this.speed+"Km로 달립니다."); } @Override public void stop() { System.out.println("버스가 멈춥니다."); } @Override public void setSpeed(int speed) { if(speed < 0) { System.out.println("속도가 음수일리가 없군요"); return; } this.speed = speed; } } package kr.co.kihd.interfacee3; //독립 클래스 (인터페이스 매개변수의 다형성) public class Driver { //new Texi()이거나 new Bus()만 들어올 수 있음. //위 2개의 클래스가 Vehiclable인터페이스를 구현했기 때문에 들어올수 있음. public void drive(Vehiclable vehiclable) { vehiclable.run(); } public void stop(Vehiclable vehiclable) { vehiclable.stop(); } //인터페이스(Vehiclable)가 리턴타입, 매개변수(다형성) 타입임. //즉 리턴타입도 구현클래스가 와야하며, 매개변수 타입도 역시 구현클래스가 와야함. public Vehiclable newCarMethod(Vehiclable vehiclable) { //텍시의 인스턴스 이면 ~ if(vehiclable instanceof Taxi) { Taxi taxi = (Taxi)vehiclable; //다운캐스팅 return taxi; } else if(vehiclable instanceof Bus) { Bus bus = (Bus)vehiclable; //다운캐스팅 return bus; } return null; } } package kr.co.kihd.interfacee3; public class AICar { } package kr.co.kihd.interfacee3; public class vehicableTest { public static void main(String[] args) { Driver driver = new Driver(); Bus bus = new Bus(); Taxi taxi = new Taxi(); bus.setSpeed(-50); bus.setSpeed(80); driver.drive(bus); //직접 객체를 생성하여 참조변수로 넘김 driver.stop(bus); System.out.println(); //직접 객체를 매개변수로 생성하여 넘기는 방법도 있음. driver.drive(new Taxi()); driver.drive(new Bus()); // driver.drive(new AICar()); //상속받지 않은것들은 들어갈수 없다. System.out.println(); Vehiclable vehiclable = driver.newCarMethod(new Taxi()); vehiclable.run(); vehiclable.stop(); System.out.println(); vehiclable = driver.newCarMethod(new Bus()); vehiclable.run(); vehiclable.stop(); } }

default 메서드 

인터페이스에 추상메서드를 추가 혹은 수정,삭제가 이루어진다면,. 과연어 떻게 될까? 그렇다. 해당 인터페이스를 구현한 클래스들은 다 컴파일 예외가 발생할 것이다 . 

구현부가 있는 디폴트 메서드가 등장하여, 필요하다면 재정의를 해서 사용하면 될 것이다.

정적(static)메서드

원래, 정적메서드는 인스턴스와는 별개이므로. 멤버로 등장하는데 걸림돌은 전혀 없었지만, 자바를 좀더 배우기 쉽게 하기 위해서, 단지 규칙을 지키기 위했던 것이다 . JDK1.8에서 새로 추가된 인터페이스의 새로운 멤버이다.

package kr.co.kihd.interfacee4; public interface Myinterface { int MAX_NUM = 100; //static final 상수 public void method(); //추상메서드 선언(본질) //JDK1.8부터 추가된 멤버 default void dMethod() { System.out.println("MyInterface의 디폴트 메서드 호출"); } static void sMethod() { System.out.println("MyInterface의 정적 메서드 호출"); } } package kr.co.kihd.interfacee4; public class DefaultStaticClass implements Myinterface{ @Override public void method() { System.out.println(DefaultStaticClass.MAX_NUM); System.out.println("MyInterface를 구현한 DefaultStaticClass의 메서드 호출"); } //구현클래스들에게 전혀 영향을 끼치지 않고, 디폴트메서드가 필요한 구현클래스에서만 //해당된 오버라이딩을 해서 사용하면 된다. @Override public void dMethod() { System.out.println("MyInterface의 default메서드의 오버라이딩한 메서드 호출"); } } package kr.co.kihd.interfacee4; public class DefaultStaticTest { public static void main(String[] args) { Myinterface myinterface = new DefaultStaticClass(); myinterface.dMethod(); myinterface.method(); //인터페이스의 적적메서드 호출하는 방법 동일함 //(인터페이스명.정적메서드 호출) Myinterface.sMethod(); } }

Toplist

최신 우편물

태그