-
[자바] 인터페이스자바 2022. 8. 5. 21:38728x90
- 일종의 추상클래스이다. ( 추상 클래스 보다 추상화가 더 되어 있다. )
- 오직 추상 메서드와 상수만 멤버로 갖는다
어떤 클래스가 있고 인터페이스 사용시 그 클래스는 반드시 인터페이스에 있는 메소드를 사용하게끔 강제한다.
interface I { public void z(); // 구현부 (몸통) 이 없어야 한다 } class A implements I { public void z(){} // 구현은 여기서 한다. }
인터페이스 규칙
1. 하나의 클래스는 복수개의 인터페이스 구현 가능
interface I1 { public void x(); // 구현 ㄴ } interface I1 { public void z(); } class A implements I1, I2 { public void x() {} // 구현필수 public void z() {} // 구현필수 }
2. 인터페이스도 상속이 된다
interface I3 { public void x(); // 구현 ㄴ } interface I4 extends I3 { public void z(); } class A implements I4 { public void x() {} // 구현필수 public void z() {} // 구현필수 }
3. 인터페이스의 멤버는 public 이여야만 한다
인터페이스 작성방식
interface 인터페이스이름 { public static final 타입 상수이름 = 값; public abstract 메서드이름(매개변수 목록); }
- 모든 멤버변수는 public static final ( 생략가능 ) - 접근제어자 public 명심
- 모든 메서드는 public abstract ( 생략가능 ) - 접근제어자 public 명심- 인터페이스는 다중 상속이 가능하다.
인터페이스 구현
- 인터페이스는 자체로 인스턴스를 생성할 수 없다.
추상 클래스가 상속을 통해 추상 메서드를 완성하듯 implements를 통해 클래스 작성
class 클래스 이름 implements 인터페이스이름 { } class Fighter implements Fightable { public void move(int x, int y) { /* */ } public void attack(Unit u) { /* */ } }
만일, 인터페이스의 메서드 중 일부만 구현하면 abstract 붙여줘야 한다.
abstract class Fighter implements Fightable { public void move(int x, int y) { /* */ } }
상속과 구현을 동시에 할 수 있다.
class Fighter extends Unit implements Fightable { public void move(int x, int y) { /* */ } public void attack(Unit u) { /* */ } }
인터페이스를 이용한 다형성
인터페이스도 이를 구현한 클래스의 조상이라 할 수 있으므로 해당 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조가능하고, 인터페이스의 타입으로 형변환도 가능하다.
인터페이스 Fightable을 클래스 Fighter가 구현했을때
Fightable f = new Fighter(); // Fightable 이라는 인터페이스 // Fighter 이라는 클래스
메서드의 매개변수의 타입도 가능
void attack(Fightable f) { }
인터페이스 타입의 매개변수가 갖는 의미는 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야한다는것이다
Fiahtable method() { Fighter f = new Fighter(); return f; // 위의 두줄을 윗말대로 줄여보면 // return new Fighter(); // 인스턴스를 반환하고 있다 }
class Fighter extends Unit implements Fightable { void attack(Fightable f) { } }
정말 중요한것!
Fightable method() { Fighter f = new Fighter(); return f; }
리턴 타입이 인터 페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.
interface Parseable { public static void parse(String fileName); } class ParserManager { // 리턴타입이 Parseable 인터페이스이다. public static void main(String[] args) { if( type.equals("XML")) { return new XMLParser(); } else { Parseable p = new HTMLParseable(); return p; } } } class XMLParser implements Parseable { public void parse(String fileName) { System.out.println(fileName); } } class HTMLParser implements Parseable { public void parse(String fileName) { System.out.println(fileName); } } class ParserTest { public static void main(String[] args) { Parseable parser = ParserManager.getParser("XML"); parser.parse("xml"); parser = ParserManager.getParser("HTML"); parser.parse("html"); } ]
getParser 매서드는 매개변수로 넘겨받는 type에 따라 값이 XMLParser 인스턴스 또는 HTMLParser 인스턴스 반환한다
이렇게 하면, 프로그램 자체를 변경하지 않고, 서버측의 변경만으로 사용자가 새로 개전된 프로그램을 사용할 수 있다.
인터페이스 이해
직접적인 관계
A( User ) -> B ( Provider ) : 직접적인 관계 , B가 바뀌면 A도 바뀌어야함
class A { public void method(B b) { b.methodB(); } } class B { public void method() { System.out.println("method b"); } } class InterfaceTest { public static void main(String[] args) { A a = new A(); a.methodA(new B()); } }
간접적인 관계로 바꾸기 위해서는 인터페이스를 통해 클래스 B의 선언과 구현 분리 필요
간접적으로 'A-I-B' 관계 : A는 인터페이스의 영향만 직접적으로 받는다 ( B의 영향을 받지 않는다.)
class A { public void method(I i) { // 이 부분이 중요 i.methodB(); // 이 부분이 중요 } } interface I { public abstract void methodB(); } class B implements I { public void method() { System.out.println("interface method b"); } } class InterfaceTest { public static void main(String[] args) { A a = new A(); a.methodA(new B()); } }
인스턴스를 직접 생성하지 않고, getInstance() 라는 메서드를 통해 제공 받는다
나중에 다른 클래스의 인스턴스로 변경되어도 A클래스의 변경없이 getInstance()만 변경하면 된다는 장점이 있다
class InterfaceTest { public static void main(String[] args) { A a = new A(); a.methodA(); } } class A { void method() { I i = InstanceManager.getInstance(); i.methodB(); System.out.println(i.toString()); } } interface I { public abstract void methodB(); } class B implements I { public void method() { System.out.println("interface method b"); } public String toString() { return "class B" } } class InstanceManager { public static I getInstace() { return new B(); // 다른 인스턴스로 바꾸려면 여기만 바꾸면 된다 } }
인터페이스 I 타입의 참조변수 i로도 Object 클래스에 정의된 메서들을 호출 가능하다 ( toString() 이런 메서드 )
'자바' 카테고리의 다른 글
[자바] 참조 (0) 2022.08.06 [자바] 다형성 (0) 2022.08.06 [자바] final (0) 2022.08.05 [자바] abstract 추상 (0) 2022.08.05 [자바] 접근제어자 (0) 2022.08.05