1. Interface[인터페이스]

  1. [설명]

    1. 클래스들이 필수로 구현해야하는 추상 자료형
    2. 객체의 사용방법을 가이드라인하는 것이라 생각하면됨
    3. 추상메서드와 상수로만 이루어져 있음
    4. 구현된 코드가 없기 때문에 당연히 인터페이스로 인스턴스도 사용이 불가함
  2. [특징]

    1. 다중상속이 가능함
      1. 껍데기만 존재하여 클래스 상속시 발생했던 모호함이 없으며 다중 상속이 가능함!
    2. 추상메서드와 상수만 가능함
      1. 구현 소스를 생성할 수 없기에 상수와 추상메서드만 가질 수 있음
    3. 생성자 사용불가함
      1. 객체가 아니므로 생성자를 사용할 수 없음
    4. 메서드 오버라이딩 필수임
      1. 자식클래스는 부모 인터페이스의 추상메서드를 모두 오버라이딩해야함
  3. [사용이유]

    1. [2가지 이유]
      1. 추상클래스를 통해 객체들 간의 네이밍을 통일할 수 있고 소스의 가독성과 유지보수가 향상됨
      2. 확장에 열려있고 변경에는 닫혀있는 객체간 결합도(코드의 종속성)를 낮춘 유연한 방식의 개발이 가능함
    2. [이유설명]
      1. 코드와 인터페이스로 생성된 객체들을 중간에 중계해주는 역할을 함
      2. 개발코드가 먼저 인터페이스의 메서드를 호출시 인터페이스는 객체의 메서드를 호출시켜주는 형식임
      3. 인터페이스로 구현된 객체는 인터페이스에서 정의된 메서드와 동일한 메서드 이름, 매개 타입, 리턴타입을 가진 실체 메서드를 필수로 가지고 있어야함
      4. 이런 과정을 통해 클래스 간의 결합도(코드 종속성)를 낮춘 효율적인 프로그래밍을 할 수 있음
    3. [낮춘 효율적인 프로그래밍?]
      1. 코드의 종속성은 각각의 메서드 간의 결합도를 의미하며 인터페이스를 활용하면 한 메서드를 수정하였을 때, 다른 메서드도 수정해야하는 상황을 줄여준다는 의미임
      2. 인터페이스로 추상메서드를 지정하면 메서드의 input값과 output값이 고정되어 있다면, public abstract String animalName(String name)이라는 메서드는 input값, output값 모두 String으로 고정되고 메서드를 구현하는 객체에서 아무리 수정해도 input값과 output값은 String이기 때문에 변경에 대한 영향도가 작음
      3. 인터페이스는 변경에 강하며, 확장에는 열려있으나 변경에는 닫혀있음
  4. [사용법]

    1. 인터페이스를 선언시 interface라는 키워드만 붙여주면 됨

    2. 인터페이스를 만들면 implements라는 키워드를 통해 객체들을 구현하는 용도로만 사용이 가능함

    3. 구체적인 대상을 생성할 수 없고 오로지 상수와 추상메서드만 사용이 가능함

    4. 메서드는 추상클래스에서 껍데기만 생성하고 상속하는 자식 클래스에서 오버라이딩하여 사용함

    5. [예제]

      // 인터페이스
      public interface Animal {
      	public static final String name = "동물";
      
      	public abstract void cry();
      	public abstract void eat();
      	public abstract void run();
      }
      
      // 인터페이스에는 static,final로 생성할 수 있는
      // 상수와 abstract로 생성할 수 있는 추상 메서드만
      // 가질 수 있음
      
      // 자식 클래스1
      public class Dog implements Animal {
      	@Override
      	public void cry() {
      		System.out.println("왈왈!");
      	}
      	@Override
      	public void eat() {
      		System.out.println("와구와구!");
      	}
      }
      
      // Dog 클래스를 생성해 Animal 인터페이스를
      // implements 키워드로 구현하고 인터페이스의
      // 추상메서드들을 모두 재정의 함
      
      // 자식 클래스2
      public class Tiger implements Animal {
      	public void cry() {
      		System.out.println("어흥!");
      	}
      
      	@Override
      	public void eat() {
      		System.out.println("주왁주왁!");
      	}
      }
      
      // Tiger 클래스도 동일함
      // 인터페이스의 추상메서드들을 오버라이드함
      
      // 출력 클래스
      public class AnimalTest {
      	public static void main(String[] args) {
      		
      		// 참조타입, 참조변수를 사용하기 위해
      		// 인스턴스(객체)를 생성해줌
      		Dog dog = new Dog();
      		Tiger tiger = new Tiger();
      
      		// 각 클래스들은 호출하고자하는 메서드를
      		// 호출하여 출력함
      		dog.cry(); // 왈왈
      		dog.eat(); // 와구와구!
      
      		tiger.cry(); // 어흥!
      		tiger.eat(); // 주왁주왁!
      	}
      }
      
  5. [인터페이스끼리 상속]

    1. 인터페이스끼리도 상속을 통해서 확장을 시켜나갈 수 있음

    2. 하위 인터페이스에서 네이밍을 강제하여 객체간의 통일성을 추구할 수 있음

    3. 인터페이스로 객체를 구현할 때는 implements라는 키워드를 사용하지만 인터페이스끼리 상속을 할때는 클래스와 마찬가지로 extends 키워드를 사용함!

    4. [예제]

      // class 끼리 상속
      class
        ↑ [extends]
      class
      
      // class가 interface를 상속
      interface
        ↑ [implements]
      class
      
      // interface끼리 상속
      interface
         ↑ [extends]
      interface