2021-06-24 강의록_상속(인터페이스)

MIN.DI·2021년 6월 24일
0

강의록

목록 보기
18/54

인터페이스 interface

인터페이스를 사용하면 코드를 객체에 종속되지 않게(loose coupling. 약한 결합) 사용할 수 있다.
코드가 객체에 강하게 종속된 형태를 tight coupling(강한 결합) 되었다고 함.

Tightly Coupled(클래스를 직접 사용) <-> Loosely Coupled(인터페이스 사용)

  • 인터페이스 접근제한자는 public, default. 두 개만 가능. (클래스와 동일)
  • 인터페이스 구성 멤버
interface 인터페이스명{
    // 1. (static final) 상수
    타입 상수명 =;			//static final로 선언
    
    // 2. 추상메소드
    타입메소드명(매개변수, ...);		//규격 (시그니처)
    
    ///////////////////////// 자바 7까지는 위의 두 가지만 인터페이스의 멤버로 가능했으나,
    ///////////////////////// 자바 8 이후 아래 두 가지가 추가됨.
    
    // 3. 디폴트 메소드
    public deault 타입 메소드명 (매개변수, ...){...} 
    
    // 4. 정적 메소드
    public static 타입 메소드명(매개변수){...}	//clazz 객체 >> 메소드영역에 생성
    
} //end interface

상수는 static final 로만 가능. 그냥 final은 불가능
->> new로 새로운 객체 생성할 수 없으니까! 무조건 static final

상수필드 선언

  • 인터페이스는 상수 필드만 선언 가능 (데이터 저장 x)
  • 인터페이스에 선언된 필드는 모두 public static final
    (부분적으로든, 전체적으로 생략하든 자동적으로 컴파일 과정에서 붙음)
    ->그래도 가능하면 명시적으로 작성할 것. 생략 노노!!
  • 상수명은 대문자로 작성 (서로 다른 단어로 구성되었을 경우 언더바 _ 로 연결)
  • 선언과 동시에 초기값 지정해야 함 (static {} 블록 작성(초기화) 불가)
    왜? 인터페이스에는 객체를 생성할 수 없으므로 static initializer 의 개념이 없으니까.
public static final int MAX_VOLUME = 10;	
public static final int MIN_VOLUE = 0;

추상메소드 선언

  • 메소드의 규격이자, 자식 타입에서 반드시 재정의(override. 다형성 2) 해야하는 강제성을 부여한다.
  • 인터페이스를 통해 호출된 메소드는 최종적으로 객체에서 실행
  • 인터페이스의 메소드는 기본적으로 실행블록 없는(시그니처만 있는) 추상메소드로 선언
  • public abstract를 생략하더라도 자동적으로 컴파일 과정에서 붙는다.
    ->이것도 생략하지 말고 명시적으로 작성할 것.
public abstract void turnOn();
public abstract void turnOff();
public abstract void setVolume(int volume);

디폴트 메소드 선언

  • 자바 8에서 추가된 인터페이스의 새로운 멤버
    [public] default 리턴타입 메소드명(매개변수, ...) {...}
  • 실행 블록을 가지고 있는 메소드
  • default 가지고 있는 메소드
  • 기본적으로 public 접근제한 ( 생략하더라도 컴파일 과정에서 자동으로 붙음)
  • 이 인터페이스를 implements 하고있는
    인스턴스메소드란 객체 없이는 존재할 수 없다. 누군가의 어떤 객체의 멤버가 되어야 함.
    그 누군가가 누구냐? 이 인터페이스를 implements하는 구현클래스(implementation class) 타입의 객체의 인스턴스 메소드가 된다.
    원래 인터페이스의 성격과는 맞지 않은 이 기능을 왜 도입했냐?
    기능의 확장 때문.
    인터페이스의 추상메소드가 a b c 있을 때, implementation class 에 a b c 를 오버라이드해서 객체를 생성했다.
    후에 인터페이스에 d라는 기능을 추가하게 되면, 이 인터페이스를 모두 구현하지 못했기 때문에 오류가 발생함.
    그럼 구현클래스에 직접 기능을 추가하는 수 밖에 없음.
    그래서 생긴게 디폴트 메소드, static 메소드임.
    기존에 있던 인터페이스로는 기능 확장이 매우 어렵기 때문에.. 어거지로 추가한 기능.
    인터페이스도 타입이니까 static메소드도 인터페이스의 소속이 맞긴 맞다.
    하지만 인터페이스를 implements하는 구현클래스의 소속이 되어야 함
    방법은 두가지가 있다. 강제성 부여하지 않고, 마치 인스턴스 메소드를 원래 가지고 있던것처럼 디폴트 메소드를 임포트해서 쓸건지
    아니면 static method를 만들어서 인터페이스명.method 이런식으로 사용할 수 있게 할 것인가?
    자식타입은 어쨌든 객체이므로 사실은 인스턴스메소드가 맞다 (디폴트메소드) -> 이게 원칙.
    근데 static을 붙이는 이유는 모든 자식타입의 객체가 공유할만한 기능, 행위를 추가할때는 static 키워드를 붙임.
    아무튼 디폴트메소드는 인터페이스의 개념이랑 좀 맞지 않음. static은 안이상

정적 메소드 선언

[public] static 리턴타입 메소드명(매개변수, ...){...}


추상메소드의 실체 메소드 작성 방법

  • 메소드의 선언부 정확하게 일치해야 함
  • 인터페이스의 모든 추상 메소드를 재정의 하는 실체 메소드 작성해야 함
    일부만 재정의 할 경우, 추상클래스로 선언 + abstract 키워드 붙임

익명 구현 객체

  • 명시적인 구현 클래스 작성 생략하고 바로 구현객체를 얻는 방법
  • 이름 없는 구현클래스 선언과 동시에 객체 생성
인터페이스 변수 = new 인터페이스() {
	// 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
   };

인터페이스에는 생성자가 없으므로 매개변수 신경 X. 그냥 소괄호 () 만 작성하면 됨.

  • 추가적으로 필드와 메소드 선언 가능하나, 익명객체 안에서만 사용
  • 인터페이스 변수로 접근 불가

인터페이스 다중상속

다중상속은 extends 키워드 사용 (implements 키워드 아님!)

public interface IC
	extends IA, IB{
    
    ;;
} //end interface    

인터페이스 a b c 가 있는데, c가 인터페이스 a, b 를 다중상속 받고있을 때
구현클래스 d가 인터페이스 c를 상속받을 때
d 에서는 a, b, c 의 abstract method를 모두 overriding해야 한다.

public class CImpl		//구현클래스는 관례상 Impl을 붙임
	implements IC { 	//impelements IA, IB, IC 로 작성해도 똑같다. 단, 이 경우 인터페이스간에는 implement가 일어나지 않음.
   ;;
} //end class
  • extends, implements 동시사용
public class CImpl		
	extends Parent			//클래스를 상속도 받고
	implements IA, IB, IC {		//인터페이스를 다중상속 받는것은 당연히 가능하고, 이런식으로 클래스를 선언하는 경우가 다수임
    
   		 ;;
}    

인터페이스는 추상클래스에 있는 추상메소드와 동일하게 반드시 오버라이딩 하도록 강제성을 갖는것은 같지만,
인터페이스의 원래 역할은 객체 사용 설명서!! 이다.
어떤 객체가 받든 같은 규격을 사용하도록 함.
근데 추상클래스는 규격으로서의 메소드, 필드도 사용할 수 있지만, 그 외의 기능도 많이 가질 수 있다.
진짜 규격다운 규격은 인터페이스임.
...?? 추상클래스랑 인터페이스 차이 다시 확인하기***

profile
내가 보려고 쓰는 블로그

0개의 댓글

관련 채용 정보