다형성 (polymorphism)
여러 가지 형태를 가질 수 있는 능력 (하나의 객체가 여러개의 자료형 타입을 가질 수 있는 것)
조상 타입 참조 변수로 자손 타입 객체를 다루는 것
- 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.
조상: TV, 자손: SmartTV
Tv t = new SmartTV(); // OK
SmartTv s = new TV(); // 에러
멤버의 개수가 7가진데 5가지만 참조변수로 사용할 수도 있다.
✔️ 참조변수의 형변환
사용할 수 있는 멤버의 개수를 조절하는 것
- 조상 자손 관계의 참조변수는 서로 형변환 가능하다.
자손타입 -> 조상타입(up-casting) : 형변환 생략가능
조상타입 -> 자손타입(down-casting) : 형변환 생략불가
FireEngine f = new FireEngine();
Car c = (Car) f;
✔️ instanceof 연산자
참조변수의 형변환 가능여부 확인에서 사용. 가능하면 true 반환
- 형 변환 가능 확인 (instanceof 사용해서)
- 형 변환
어떤 타입에 대한 instanceof연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.
✔️ 다형성 장점
매개변수의 다형성
: 메서드의 매개변수로 조상타입의 참조변수를 사용해서 하나의 메소드로 여러 타입의 객체를 받을 수 있다.
여러 종류 객체를 배열로
: 하나의 배열에 여러 종류 객체 저장 가능하다.
Product p1 = new TV();
Product p2 = new Computer();
Product p1 = new Audio();
Product p[] = new Product[3];
p[0] = new TV();
p[1] = new Computer();
p[2] = new Audio();
추상 클래스 (abstract class)
미완성 설계도. 미완성 메서드(추상 메서드)를 갖고 있는 클래스.
abstract class Player {
abstract void play(int pos);
abstract void stop();
}
- 추상 클래스로 인스턴스 생성 불가
- 상속을 통해 추상 메서드를 완성해야 인스턴스 생성 가능
class AudioPlayer extends Player {
void play(int pos) {}
void stop() {}
}
AudioPlayer ap = new AudioPlayer();
Player ap = new AudioPlayer();
✔️ 추상 메서드 (abstract method)
미완성 메서드. 구현부(몸통, {}가 없는 메서드)
abstract 리턴타입 메서드이름();
꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우
추상 클래스 작성
- 여러 클래스에 공통적으로 사용될 수 있는 추상 클래스를 바로 작성한다.
- 기존 클래스의 공통 부분을 뽑아서 추상클래스를 만든다.
추상 클래스를 의미있는 단위로 나눠서 작성하면 내가 원하는대로 상속받아서 개발하기 편하다.
추상화 <- -> 구체화
인터페이스 (interface)
추상 메서드의 집합
구현된 것이 전혀 없는 설계도. 껍데이 (모든 멤버가 public)
- 추상 클래스: 일반 클래스인데 추상 메서드를 가지고 있는 것 (생성자, iv 있을 수 있다)
- 인터페이스: 완전히 추성 메서드만 있는 것
interface 인터페이스 이름 {
public static final 타입 상수이름 = 값;
public abstract 메서드이름(매개변수목록);
}
인터페이스 상속
- 인터페이스의 조상은 인터페이스만 가능 (Object가 최고 조상 아님)
- 다중 상속이 가능하다. (추상메서드는 충돌해도 문제가 없다.)
interface Fightable extends Movable, Attackable {}
인터페이스 구현
: 인터페이스에 정의된 추상 메서드를 완성하는 것
- extends: 추상 클래스는 상속을 통해서 추상 클래스를 완성 (구현)
- implements: 인터페이스는 구현을 통해서 추상 클래스 완성 (구현)
class 클래스이름 implements 인터페이스이름 {
// 인터페이스에 정의된 추상메서드를 모두 구현해야 한다.
}
✔️ 추상 클래스 vs 인터페이스
- 공통점: 추상 메서드를 가지고 있다. 미완성 설계도이다.
- 차이점: 인터페이스는 iv를 가질 수 없다.
✔️ 인터페이스를 이용한 다형성
interface Fightable {
void move(int x, int y);
void attack(Fightable f);
}
class Fighter extends Unit implements Fightable {
public void move(int x, int y) {}
public void attack(Fightable f) {}
}
Unit u = new Fighter();
Fightable f = new Fighter();
f.move(100, 200);
f.attack(new Fighter());
- 인터페이스를 메서드의 리턴 타입으로 지정할 수 있다.
- 반환 타입을 인터페이스로 하면 메서드는 인터페이스를 구현한 객체를 반환해야 된다.
✔️ 장점
- 두 대상(객체) 간의 '연결, 대화, 소통'을 돕는 '중간 역할'을 한다.
- 선언(설계)와 구현을 분리시킬 수 있게 한다.
- 개발 시간을 단축할 수 있다.
- 변경에 유리한 유연한 설계가 가능하다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들을 관계를 맺어줄 수 있다.
예시
class B {
public void method() {
System.out.println("methodInB");
}
}
껍데이와 알맹이가 함께 있어서 유연하지 않고 변경에 불리하다.
그래서 이것을 선언부만 인터페이스로 떼어내서 분리한다.
- 메서드 선언, 추상메서드 (껍데기)
interface I {
public void method();
}
- 메서드 구현 (알맹이)
class B implements I {
public void method() {
System.out.println("methodInB");
}
}
✔️ 디폴트 메서드와 static 메서드
- 인터페이스에 디폴트 메서드, static 메서드 추가 가능 (JDK 1.8부터)
- 인터페이스에 새로운 메서드(추상 메서드)를 추가하기 어려움.
- 그래서 default method
예외사항
interface MyInterface {
void method();
default void newMethod() {}
}
충돌 -> 오버라이딩 하자!
📌 Reference
- 남궁 선, 「자바의 정석」, 도우출판
반응형
'프로젝트 개발 기록 > [개발] java | spring' 카테고리의 다른 글
[Java] 예외처리 (1) | 2022.10.23 |
---|---|
[Java] 알아두면 좋을 것! (JDK, JRE, JVM, build, run) (0) | 2022.10.16 |
[Java] package와 import, 제어자 (1) | 2022.10.11 |
[Java] 상속 (Inheritance), 오버라이딩, super, super() (0) | 2022.10.09 |
댓글