Let's kick it
[혼공자]5주차 - chap08 본문
- 기본 숙제
Q. 인터페이스는 클래스를 선언할 때 어떻게 선언될 수 있는지 정리하기
인터페이스는 interface 키워드를 사용해 선언한다. 구성 멤버로는 상수 필드, 추상 메소드를 가질 수 있는데 상수 필드는 자동으로 public static final이 되고, 추상 메소드는 자동으로 public abstract이 된다. 인터페이스를 구현하는 클래스는 implements 키워드를 사용하고 이를 구현 클래스라 한다. 구현 클래스는 인터페이스의 추상 메소드에 대한 실체 메소드를 가져야 하며, 이 클래스의 객체를 구현 객체라고 한다. 한 클래스는 여러 개의 인터페이스를 구현할 수 있으며, 이를 다중 인터페이스 구현이라고 한다. 또한 인터페이스는 다른 인터페이스를 상속할 수 있으며 이때 extends 키워드를 사용한다.
- 추가 숙제
p.443 (09-1) 확인 문제 3번 풀어보기
🤔 인터페이스 생각하니 API가 생각나 찾아보니 역시 인터페이스가 맞았다. API(application programing interface) 프로그램 개발에 자주 사용되는 클래스 및 인터페이스 모음. 라이브러리라고도 부른다.
8 - 1 인터페이스(interface)
- 자바에서 인터페이스는 객체의 사용방법을 정의한 타입이다. 인터페이스를 통해 다양한 객체를 동일한 사용방법으로 이용가능하다.
- 인터페이스는 개발코드와 객체가 서로 통신하는 접점 역할을 한다. 개발 코드가 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출시킨다. 그렇기 때문에 개발 코드는 객체의 내부 구조를 알 필요가 없고 인터페이스의 메소드만 알고 있으면 된다.
- 개발 코드가 직접 객체의 메소드를 호출하면 간단한데 왜 중간에 인터페이스를 두는 이유는 개발 코드를 수정하지 않고 사용하는 객체를 변경할 수 있도록 하기 위해서이다.
- 인터페이스는 하나의 객체가 아니라 여러 객체들과 사용이 가능하므로 어떤 객체를 사용하느냐에 따라 실행 내용과 리턴값이 다를 수 있다. 따라서 개발 코드 측면에서는 코드 변경 없이 실행 내용과 리턴값을 다양화할 수 있다는 장점을 가지게 된다.
- 인터페이스 선언
- 인터페이스는 '~.java' 형태의 소스 파일로 작성되고 (javac) 컴파일러를 통해 '~.class' 형태로 컴파일되기 때문에 물리적 형태는 클래스와 동일. 그러나 소스 작성 시 선언방법은 다르다. 인터페이스 선언은 class 키워드 대신 interface 키워드 사용.
[public] interface 인터페이스이름 {...};
- 인터페이스 이름은 클래스 이름작성과 동일. 첫 글자는 대문자로 나머지는 소문자로 작성하는 것이 관례. public 접근 제한은 다른 패키지에서도 인터페이스를 사용할 수 있게 해 준다.
- 클래스는 필드, 생성자, 메소드를 구성멤버로 가지는데 비해, 인터페이스는 상수 필드와 추상 메소드만을 구성멤버로 가진다. 인터페이스는 객체로 생성할 수 없으니 생성자를 가질 수 없다.
interface 인터페이스이름 {
//상수
타입 상수이름 = 값;
//추상메소드
타입 메소드이름(매개변수, ...);
}
- 인터페이스는 객체 사용 방법을 정의한 것이므로 실행 시 데이터를 저장할 수 있는 인스턴스 또는 정적 필드를 선언할 수 없다. 그러나 상수 필드(constant field)는 선언이 가능한데, 상수는 인터페이스에 고정된 값으로 실행 시에 데이터를 바꿀 수 없다. public static final 특성을 갖는데 생략하더라도 컴파일 과정에서 자동으로 붙게 된다.
- 상수 이름은 대문자로 작성하되, 서로 다른 단어로 구성되어 있다면 언더바(_)로 연결하는 것이 관례이고, 인터페이스 상수는 반드시 선언과 동시에 초기값을 지정해 줘야 한다.
- 인터페이스를 통해 호출된 메소드는 최종적으로 객체에서 실행된다. 그렇기에 인터페이스의 메소드는 실행 블록이 없는 추상 메소드로 선언한다. 추상 메소드는 리턴 타입, 메소드 이름, 매개 변수만 기술되고 중괄호{}를 붙이지 않는 메소드를 말한다. 인터페이스에 선언된 추상 메소드는 모두 public abstract의 특성을 갖기 때문에 생략하더라도 컴파일 과정에서 자동으로 붙게 된다.
-인터페이스 구현
개발자 코드에서 인터페이스 메소드를 호출하면 인터페이스는 객체의 메소드를 호출한다. 객체는 인터페이스에서 정의된 추상 메소드와 동일한 메소드 이름, 매개타입, 리턴 타입을 가진 실체 메소드를 가지고 있어야 한다. 이러한 객체를 인터페이스 구현(implement) 객체라 하고, 구현 객체를 생성하는 클래스를 구현클래스라고 한다.
- 구현 클래스
보통의 클래스와 동일한데, 인터페이스 타입으로 사용할 수 있음을 알려주기 위해 클래스 선언부에 implements 키워드를 추가하고 인터페이스 이름을 명시해야 한다. 그리고 인터페이스에 선언된 추상 메소드의 실체 메소드를 선언해야 한다.
- 구현 클래스가 작성되면 new 연산자로 객체를 생성할 수 있다. 인터페이스로 구현 객체를 사용하려면 인터페이스 변수를 선언하고 구현 객체를 대입해야 한다. 인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입될 경우 구현 객체의 번지를 저장해야 한다.
인터페이스 변수;
변수 = 구현객체;
//or
인터페이스 변수 = 구현객체;
주석 글과 같이 구현 객체가 인터페이스 변수에 대입된다는 걸 이해하기 위한 내용이므로(타입 변환의 가능성을 보여주기 위한 코드이므로) 경고인 The value of the local variable rc is not used. 를 그냥 지나가도 되지만 변수를 선언만 하고 사용하지 않아 경고가 뜨는 것이므로 클로드의 예시로 변수 선언한 것을 사용하는 예를 넣어주었다.
객체는 다수의 인터페이스 타입으로 사용할 수 있다. 인터페이스 A와 인터페이스 B가 객체의 메소드를 호출할 수 있으려면 객체는 이 두 인터페이스를 모두 구현해야 한다. 다중 인터페이스 구현 클래스는 다음과 같이 작성해야 한다.
public class 구현클래스이름 implements 인터페이스A, 인터페이스B {
//인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
//인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
}
- 인터페이스 사용
인터페이스로 구현 객체를 사용하는 방법 : 클래스를 선언할 때 인터페이스 필드, 생성자 또는 메소드의 매개변수, 생성자 또는 메소드의 로컬 변수로 선언될 수 있다.
- 인터페이스가 필드 타입으로 사용될 경우, 필드에 구현 객체를 대입할 수 있다.
- 인터페이스가 생성자의 매개변수 타입으로 사용될 경우, new 연산자로 객체를 생성할 때 구현 객체를 생성자의 매개값으로 대입할 수 있다.
- 인터페이스가 로컬 변수 타입으로 사용될 경우, 변수에 구현 객체를 대입할 수 있다.
- 인터페이스가 메소드의 매개변수타입으로 사용될 경우, 메소드 호출 시 구현 객체를 매개값으로 대입할 수 있다.
- 구현 객체가 인터페이스가 타입에 대입되면 인터페이스에 선언된 추상 메소드를 개발 코드에서 사용할 수 있다.
17번 라인에서 경고문이 떠서 의도를 명확히 하기 위해 주석을 달고 경고를 무시하기 위해 어노테이션을 사용했다.
- 확인 문제 3번
main() 메소드에서 printSound()를 호출할 때 구현 객체를 생성자의 매개값으로 대입해 실행된다.
8 - 2 인터페이스의 타입 변환과 다형성
- 자동 타입 변환(promotion) : 구현 객체가 인터페이스 변수에 대입되는 것.
인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 역시 인터페이스 타입으로 자동 타입 변환할 수 있다. 자동 타입 변환을 이용하면 필드의 다형성과 매개 변수의 다형성을 구현할 수 있다. 필드와 매개 변수의 타입을 인터페이스로 선언하면 다양한 구현 객체를 대입해 실행결과를 다양하게 만들 수 있기 때문이다.
Car의 run()의 메소드를 수정하지 않아도 필드 타입에 다른 구현 객체를 대입해 다양한 roll()의 메소드 실행결과를 얻을 수 있는 것이 필드의 다형성이다.
매개변수를 인터페이스 타입으로 선언하고 호출할 때에는 구현 객체를 대입한다. 매개 변수의 타입이 인터페이스일 경우 어떠한 구현 객체도 매개값으로 사용할 수 있고, 어떤 구현 객체가 제공되느냐에 따라 메소드의 실행결과는 다양해질 수 있다. 이것이 인터페이스의 매개변수의 다형성이다.
- 다형성 : 상속은 같은 종류의 하위 클래스를 만드는 기술이고, 인터페이스는 사용 방법이 동일한 클래스를 만드는 기술이라는 개념의 차이는 있지만 둘 다 다형성을 구현하는 방법은 비슷하다. 재정의 와 타입 변환 기능 제공.
- 강제 타입 변환(casting) : 인터페이스에 대입된 구현 객체를 다시 원래 구현 클래스 타입으로 변환하는 것. 구현 객체가 인터페이스 타입으로 변환하면 인터페이스에 선언된 메소드만 사용가능하다는 제약사항이 따른다. 하지만 구현 객체에 선언된 필드와 메소드가 사용해야 할 경우도 발생하기 때문에 강제 타입 변환한다.
- instanceof 연산자 : 강제 타입 변환을 하기 전에 변환이 가능한지 조사할 때 사용. 상속에서는 자식 클래스 타입인지, 인터페이스에서는 구현 클래스 타입인지 확일할 때 사용한다. 인터페이스 타입으로 자동 타입 변환된 매개값을 메소드 내에서 다시 구현 클래스 타입으로 강제 타입 변환해야 한다면 반드시 매개값이 어떤 객체인지 연산자로 확인하고 안전하게 강제 타입 변환을 해야 한다.
이 코드 실행하기 위해 import문을 추가하면서 이전 패키지에 사용한 클래스의 메소드 사용하려해도 계속 경고문이 떠서 이 책의 소스코드 파일 들어가서 확인해보니 추가로 만들어서 사용하신것보고 import문 사용하는 것 포기하고 추가해 만들었습니다. 주석은 제가 조금만 지나도 까먹기도 하고 확실히 이해하고 싶어서 클로드의 도움을 받아 작성했습니다.
- 인터페이스 상속 : 클래스는 다중 상속을 지원하지 않지만, 인터페이스는 다중 상속 허용한다. extends 키워드 뒤 인터페이스 나열하면 된다.
- 8 - 2. 확인 문제
1 - 2. 부모 클래스가 인터페이스를 구현하면 자식 클래스로부터 생성된 객체를 인터페이스 타입으로 자동 타입 변환될 수 없다.(x)
-> 인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환할 수 있다. 하지만 나는 인터페이스 상속 생각해서 상위 인터페이스로 타입 변환되면 상위 인터페이스에 선언된 메소드만 사용 가능하기 때문에 아니라 생각했음. 문제 제대로 이해하고 풀기
3. 구현 클래스를 작성하는 코드 문제임
oracle이나 mysql객체를 매개값으로 받기 위해 dbwork()메소드를 만들어 추상메소드를 실체 메소드로 만든 것을 한번에 실행하기 위해 메소드 안에 모두 넣어주었고, main() 메소드 부분에서 호출을 받으면 매개값으로 받고 타입 매개 변수에 들어가 실행된다. 내 해석이 맞는지 확인하기!
'혼공학습단12기' 카테고리의 다른 글
[혼공자]6주차 - chap10 (0) | 2024.08.15 |
---|---|
[혼공자]4주차 - chap07 (0) | 2024.07.28 |
[혼공자]3주차 - chap06 (0) | 2024.07.21 |
[혼공자]2주차 - chap04 (0) | 2024.07.13 |
[혼공자]1주차 - chap01 ~ 03 (0) | 2024.07.07 |