interface 클래스이름{
public static final 타입 상수이름 = 값;
// interface안에 있는 변수는 모두 상수이므로 (public static final)생략 가능
// static int ex = 1;
// final int ex2 = 2;
// int ex3 = 3;
public abstract 메서드이름(매개변수목록);
}
interface Movable{
void move(int x, int y);
}
interface Attackable{
void move(int x, int y);
}
interface Fightable extends Movable, Attackable{} // 다중 상속
class test implements test2{
public void move(int x, int y){
추상클래스에서 받은 메서드 완성시킴
}
}
--------- 추상메서드 2개를 인터페이스하여 1개의 메서드만 완성 시킬경우 ---------
abstract class Fighter implements Fightable{
// 1개는 미완성 이므로 abstract 사용
public void move(int x, int y){ }
(public abstract void attack(){}) // 생략 가능
}
class Fighter extends Unit implements Fightable{
public void move(int x, int y){ }
public void attack(Fightable f){ }
// Fightable인터페이스를 구현한 클래스의 인스턴스만 가능
// (Unit 상속을 받은 클래스는 불가능)
}
// 다중 상속
Unit u = new Fighter(); // 부모 클래스 다형성
Fightable f = new Fighter(); // 인터페이스 클래스 다형성
//
실습
abstract class Unit2{
int x, y;
abstract void move(int x, int y);
void stop(){
System.out.println("멈춥니다.");
}
}
interface Fightable{
void move(int x, int y); // public abstract가 생략됨
void attack(Fightable f); // public abstract가 생략됨
}
class Fighter extends Unit2 implements Fightable{
// 오버라이딩 규칙 : 조상보다 접근제어자가 좁으면 안된다.(조상 메서드가 public 이므로 public 붙여줘야 함)
public void move(int x, int y){
System.out.println("["+x+","+y+"]로 이동");
}
public void attack(Fightable f){
System.out.println(f+"를 공격");
}
Fightable getFightable(){
// Fightable 인터페이스를 구현한 객체만 올수 있다.
Fighter f = new Fighter();
return (Fightable)f;
}
}
public class interfaceTest {
public static void main(String[] args) {
Fighter f = new Fighter();
Fightable f3 = f.getFightable();
// -------- Fightable 다형성 (interface) Unit2 클래스에 있는 stop()메서드 사용 불가
Fightable f2 = new Fighter();
f2.move(100,200);
f2.attack(new Fighter()); // Fighter f2 = new Fighter();
// f.attack(f2);
// --------- Unit 다형성 (상속) Fightable 클래스에 있는 attack()메서드 사용 불가
Unit2 u = new Fighter();
u.move(10,20);
u.stop();
}
}
class B{ interface I{
public void method(){ ... } => public void method();
} }
실습
class A{
public void method(I i){ // 인터페이스 객체를 받음
i.method();
}
}
interface I{ // 인터페이스로 method를 따로 뺌
void method();
}
class B implements I{
public void method(){
System.out.println("B클래스의 메서드");
}
}
class C implements I{
public void method(){
System.out.println("C클래스의 메서드");
}
}
public class interfaceTest2 {
public static void main(String[] args) {
A a = new A();
a.method(new B());
a.method(new C());
}
}
---------------------------- 설명 --------------------------
- 공통 메서드를 인터페이스를 통해 따로 빼냄
- B,C클래스에서 자신에 맞게끔 오버라이딩 함
- A클래스에서는 상황에 맞는 객체를 불러오게 하기 위해 인터페이스 객체를 받음
- 메인 메서드에서 필요한 객체를 a.method(객체); 넣어 필요한 값을 출력함 (new B()와 new C()의 값은 다름)
※ 만약 인터페이스를 사용하지 않으면 A클래스에서 B의 값과 C의 값을 출력할때 각각 작성해줘야함
interface Repairable{} // 관계없는 클래스들을 묶어주기 위한 공통점 인터페이스
class GroundUnit extends Unit{ }
class AirUnit extends Unit{ }
class SCV extends GroundUnit implements Repairable{ ... }
// GrountUnit을 상속받은 클래스
class Tank extends GroundUnit implements Repairable{ ... }
// GrountUnit을 상속받은 클래스
class Dropship extends AirUnit implements Repairable{ ... }
// AirUnit을 상속받은 클래스
void repair(Repairable r){
// Repairable 인터페이스를 사용하는 객체만 입력가능
if(r instanceof Unit){
// Repairable 인터페이스를 사용한 객체중 Unit을 상속 받았는지 확인
Unit u = (Unit) r; // r안의 값을 사용하기 위해 다형성
while(u.hitPoint != u.MAX_HP){
u.hitpoint++;
}
}
}
---------------------------- 설명 --------------------------
- SCV,Tank,Dropship의 부모클래스의 부모클래스는 Unit으로 관계가 있지만 실질적으로
SCV,Tank와 Dropship은 서로 다른 클래스를 상속받아 관계가 없는 클래스다 하지만,
Repairable이란 인터페이스를 공통으로 받게 되면 관계를 맺어줄 수 있다.
- 공통 메서드인 repair(Repairable r)을 만들어 Repairable 인터페이스를 사용하는
객체만이 접근할 수 있도록 하고 그 중에서 Unit을 상속받아 다형성이 가능한지 확인한다
- 다형성이 가능하다면 SCV, Tank, Dropship 메서드안의 값을 사용하기 위해
최상위 클래스를 다형성 시켜 값을 불러올 수 있도록 한다.
interface MyInterface{ interface MyInterface{
void method(); => void method();
void newMeethod(); default void newMethod(){...}
} }
public class Calculator {
NumberGenerator numberGenerator;
//생성자
public Calculator(NumberGenerator numberGenerator) {
this.numberGenerator = numberGenerator;
}
//더하여 출력
public void plus(){
System.out.println(10+ numberGenerator.generate(10));
}
}
public class RandomNumberGenerator implements NumberGenerator{
//NumberGenerator 인터페이스의 메소드 오버라이드
@Override
public int generate(int num) {
num = (int)(Math.random()*10);
return num;
}
}
public class SpecificNumberGenerator implements NumberGenerator{
//NumberGenerator 인터페이스의 메소드 오버라이드
@Override
public int generate(int num) {
return 2000 * num;
}
}
public interface NumberGenerator {
//인터페이스: 메소드 내용이없는 껍데기
//선언만 해줌
int generate(int num);
}
public class Main {
public static void main(String[] args) {
//1.
NumberGenerator randomNumberGenerator = new RandomNumberGenerator();
Calculator randomNumberCalculator = new Calculator(randomNumberGenerator);
randomNumberCalculator.plus();
//2.
Calculator specificNumberCalculator = new Calculator(new SpecificNumberGenerator());
specificNumberCalculator.plus();
}
}