//////
Search

다형성, 인터페이스 by 장서현

태그
2022/09/28 05:05
사람
최종 편집 일시
2022/09/28 05:08

13 - 다형성

1. 다형성이란?

객체들의 타입이 다르면 똑같은 메시지가 전달되더라도 서로 다른 동작을 하는것이다.
예제를 통해 이해하는 다형성의 개념이 필요한 이유와 활용의 가치
다형성 예제

2. 메서드 오버라이딩

오버라이딩이란? → 조상 클래스로부터 상속 받은 메서드의 내용을 상속 받는 클래스에 맞게 변경하는 것
메서드 오버라이딩의 조건
1.
선언부가 같아야 함(메서드 이름, 매개변수, 리턴 타입)
2.
조상 클래스의 메서드보다 범위가 넓거나 같아야 함
3.
조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없음
오버라이딩 예제1
오버라이딩 예제2
오버라이딩된 메서드를 인스턴스 외부에서 호출하는 방법은 없음
인스턴스 내부에서는 키워드 super를 통해 호출 가능 (참조변수)
오버라이딩과 오버로딩의 차이
오버라이딩: 부모 클래스에게서 상속 받은 메서드를 재정의하는 것
오버로딩: 같은 클래스 내부 혹은 상속 관계에 있는 클래스에서 메소드 이름은 같지만 매개변수의 타입과 개수가 다른 메소드들을 여러개 만드는 것

3. 업 캐스팅과 다운 캐스팅

업 캐스팅: 자식 클래스의 객체가 부모 클래스의 타입으로 형변환 되는 것
자바에서 자식 클래스는 부모 클래스의 멤버를 상속 받기 때문에, 자식 클래스 객체는 부모 클래스 멤버를 모두 갖는다.
따라서, 자식 클래스 객체를 부모 클래스가 가리킬 수 있는 것이다.
다만, 부모 클래스의 객체로 자식 클래스의 멤버에 접근하지 못한다.
부모 클래스의 객체로는 부모 클래스의 멤버에만 접근할 수 있다.
다운 캐스팅: 업 캐스팅 된 객체를 다시 부모 클래스 타입의 객체로 형변환하는 것
부모 클래스 타입의 객체를 자식 클래스 타입의 객체로 가리키는 것
다형성 적용으로 잃어버린 특성을 복구 시키기 위해 원래 상태로 되돌리는 것
업 캐스팅과 달리 명시적으로 타입 변환을 지정해야한다.
Person p = new Student(); Student s = (Student)p //다운 캐스팅
Java
복사
업 캐스팅과 다운 캐스팅 예제

4. 다형성의 활용

다형성 사용시 유지 보수가 쉽고 재사용성이 증가한다.

5. instanceof 연산자

부모 클래스를 상속 받은 자식 클래스가 여러 개 존재하는 경우, 부모 클래스의 객체가 가리키는 진짜 클래스 타입을 구분하는 데 어려움이 있다. ⇒ 캐스팅 가능 여부를 확인하기 위해, 또 참조변수가 참조하는 객체의 실제 타입을 체크하는데 사용한다.
instanceof는 boolean 타입으로, 가리키는 객체가 해당 클래스 타입의 객체이면 true를 아니면 false를 반환한다. ⇒ 연산 결과가 true일 때 해당 타입으로 형변환이 가능
instanceof는 클래스에만 적용할 수 있다. (클래스 타입을 작성하는 부분에 Primitive 타입 )
instanceof 예제

14 - 인터페이스

추상 클래스

public abstract class Animal { public abstract void move(); }
Java
복사
추상 메서드가 1개 이상 있을 때, class앞에 abstract가 붙는다.
추상 클래스는 객체 생성이 안된다.
추상클래스의 메서드를 사용하려면
자손이 추상클래스를 상속 받는다.
메서드를 반드시 오버라이딩한다. ⇒ 하지 않으면 컴파일 오류

추상 메서드

public abstract void move();
Java
복사
내용 구현이 없는 메서드

인터페이스의 역할

상속 관계가 아닌, 클래스 간 유사성을 인코딩하는 것
객체의 사용 방법을 정의한 타입이라고 할 수 있다.
인터페이스는 다형성을 구현하는데에 도움이 되며 매우 중요한 역할을 한다.
단일 상속만 지원하는 자바에서 다중 상속의 효과를 낼 수 있는 방법에 사용된다.
서로 관계 없는 클래스들에게 관계를 맺어줄 수 있다. (컴퓨터 입/출력장치 & 운영체제가 그 예시)

인터페이스 선언

interface 인터페이스_이름 {...} interface Printable { public abstract void print(String doc); } class SPrinterDriver implements Printable { @Override ...; }
Java
복사
class 이름 작명하는 것과 비슷하다.
인터페이스는 상수와 메서드만을 구성요소로 가진다.
데이터를 저장하는 필드는 가질 수 없다.
객체와 생성자를 생성할 수 없다.
자바 8버전부터 디폴트 메서드와 정적 메서드도 선언이 가능하다.

인터페이스 구성 요소

1.
상수 필드
a.
상수는 public static final 타입 상수명 = 값으로 선언
b.
무조건 초기화 해야한다.
2.
추상 메서드
a.
인터페이스의 추상 메서드는 public abstract의 특성을 가지기 때문에 생략을 해도 컴파일 과정에서 자동으로 붙게 된다.
3.
디폴트 메서드
a.
클래스 인스턴스 메서드와 동일 (객체의 메서드라고 생각하면 된다.)
b.
public 특성을 갖기 때문에 생략해도 컴파일 과정에서 붙게 된다.
4.
정적 메소드
a.
public 특성을 갖기때문에 생략해도 컴파일 과정에서 붙게 된다.
b.
선언한 인터페이스 이름으로 바로 호출할 수 있다.
interface Name { static void function1() {.....} } main() { Name.function1 //이렇게 바로 호출이 가능하다. }
Java
복사

인터페이스 구현

인터페이스의 추상 메서드를 구현하는 클래스를 구현 클래스라고 한다.
구현 클래스로 생성한 객체는 구현 객체라고 한다.
public class 구현클래스명 implements 인터페이스명 {....}
Java
복사
구현 클래스에서 인터페이스의 추상 메서드들에 대한 실체 메서드를 작성할 때는 public보다 낮은 접근 제한자를 사용할 수 없다.
추상 메서드를 오버라이딩하지 않으면 구현 클래스는 추상 클래스가 된다.
따라서 abstract를 붙여줘야 한다.

인터페이스 추상 메서드 사용

인터페이스의 추상 메서드를 사용하기 위해서는 인터페이스 타입의 변수에 구현 객체를 대입해야 한다.
인터페이스 변수 = new 인터페이스() { 추상 메서드 오버라이딩 }
Java
복사
인터페이스 추상 메서드를 사용하기 위해 일회성 클래스를 만드는 것은 비효율적이다.
구현 클래스를 만들지 않고 위 같이 구현 객체를 바로 만들고 대입할 수 있고, 이것을 익명 구현 객체라고 한다.
익명 구현 객체를 생성하면 컴파일 시 자동으로 .class파일이 생성된다.
인터페이스 - 추상 메서드 예제

디폴트 메서드 사용

디폴트 메서드는 인스턴스 메서드이기 때문에 구현 객체가 있어야 사용이 가능하다.
즉 인터페이스 변수를 가지고 디폴트 메서드를 호출할 수 없다.

정적 메소드 사용

인터페이스 타입으로 바로 호출이 가능하다.
ex) Interface명.정적 메서드

디폴트 메서드를 인터페이스에 추가하는 이유

인터페이스를 확장시키고 싶지만 추상 메서드를 추가할 경우 여러 구현 클래스에서 오류가 난다.
추상 메서드를 오버라이딩하지 않을 시, 컴파일 오류가 발생하기 때문이다.
이런 문제로 디폴트 메서드를 추가하여 문제없이 확장시키기 위해 디폴트 메서드를 사용한다.