참조변수의 형변환
▶ 조상 자손관계의 참조변수는 서로 형변환 가능
class Car {}
class FireEngine extends Car { }
class Ambulance extends Car { }
FireEngine , Ambulance 가 있는데 둘다 car의 자손이다. 아래의 그림으로 보면 이러한 상속관계를 볼 수 있다. 형변환의 특성으로 조상 자손 관계의 참조변수는 서로 형변환이 가능하다. 그렇기 때문에 Car 클래스의 자손들은 조상 자손 관계가 충족되기 때문에 형변환이 가능하다, 하지만 형제들끼리는 형변환이 가능하지 않다.
class Car {
String color;
int door;
void drive(){ //운전하는 기능
System.out.println("drive~");
}
void stop() { //멈추는 기능
System.out.println("stop~");
}
}
class FireEngine ectends Car { //소방차
void water() { //물을 뿌리는 기능
System.out.println("water");
}
}
FireEngine f = new FireEngine();
Car c = (Car)f; // 조상인 Car 타입으로 형변환
FireEngine f2 = (FireEngine)c; //자손인 FireEngine 타입으로 형변환
Ambulance a = (Ambulance)f; //에러 상속관계가 아닌 클래스간의 형변환 불가
위의 코드를 보면 FireEngine 객체와 타입이일치한다. 멤버변수 5개가 있으며 전부 사용이 가능하다.
아래의 메모리 구조형태로 존재한다.
조상클래스 멤버를 상속받기때문에 5개의 멤버가 있는 것을 볼 수 있다.
두 번째 코드를 보면 Car타입의 참조변수 c 가 있고 참조변수 f 값을 대입한다.
같은 객체를 가리키게 되고 타입이 다르기 때문에 형변환을 하는 것을 볼 수 있다. Car 와 FireEngine의 관계는 부모자식의 관계가 되기 때문에 형변환이 가능하다.
참조변수 c 는 멤버가 4개이기 때문에 void water() 메서드를 제외한 4개의 멤버만 사용이 가능하다.
똑같은 주소를 가리키고 있는 것이지만 FireEngine 타입의 f참조변수는 5개 ,Car타입의 참조변수 c는 4개의 멤버 사용이 된다. 이렇게 5개에서 4개로 줄일 수 있고 다시 3번째 코드에서처럼 5개로 늘릴 수 있다. 형변환은 사용하는 멤버개수를 증가, 감소를 할 수 있으나 형제 관계에서는 형변환이 불가능하다.
사용하는 이유
- 객체지향의 유연성을 제공
- 다형적 매개변수
- 하나의 배열로 여러 종류의 객체를 다룰 수 있다
정리
- 사용할 수 있는 멤버의 갯수를 형변환을 통해 조절한다.
- 조상-자손 관계에서 서로 형변환 가능하다.
- Upcasting, Downcasting 구분 말고 형변환 타입을 생략하지 않으면 된다.
- instanceof 연산자를 통해 형변환 가능 여부를 알 수 있다.(boolean)
- 컴파일에서 통과 될 수도 있지만 런타임에서 ClassCastException 터질 수도 있다
추상클래스(abstract)
▶ 추상 메서드가 있는 클래스
▶ 클래스 안에 추상메서드 단 하나라도 있으면 추상클래스
클래스, 메서드 이름 앞에 abstract 키워드를 갖고 있다.
추상메서드에는 선언부는 있지만, 구현부 { } 가 없다.
추상메서드는 미완성이라 인스턴스 생성 불가.
다른 클래스가 이 추상메서드를 extends 해서 상속한다.
모두 구현하지 않고 일부만 구현하는 경우, 컴파일 에러 발생.
작성 방법
기존 클래스들에서 공통 부분을 골라서 추상화 한다.
하나의 추상클래스 보다 의미있는 단계별로 여러개 만들어 놓는다.
클래스는 명사, 메서드는 동사
사용하는 이유
- 상속받아 오버라이드할 자손클래스들이 각각 다르게 구현 될 경우
- 클래스들의 변경/관리에 용이
인터페이스(interface)
▶ 추상메서드들의 집합
▶ 구현된 것이 없는 설계도. 모든 멤버가 public인 껍데기
인터페이스의 조상은 인터페이스만 가능
다중 인터페이스 상속이 가능하다
클래스에서 implements로 구현한다.
추상메서드와 다르게 iv(필드값, 생성자, 인스턴스 메서드)가 없다
인터페이스를 이용한 다형성
- 인터페이스를 메서드의 리턴타입으로 지정할 수 있다.
- 해당 인터페이스를 구현한 클래스의 인스턴스를 리턴
- 해당 인터페이스를 구현해야 타입 일치가 가능하니까 인터페이스의 default 메서드 새롭게 interface에 메서드를 추가 할 경우, 이미 설계와 구현이 완료된 클래스들의 숫자 만큼 다시 override해서 구현해야한다.
대신에 interface 내에 default 키워드를 가진 iv 메서드를 선언할 수 있다.
예외적인 경우이고 만약 충돌이 나는 경우 개발자가 직접 override하면 된다.
사용하는 이유
- extends와 implements를 통한 다중 상속같은 효과
- 선언과 구현을 분리시킬 수 있다
- 의존관계가 Interface를 바라보게 만들어서 내용이 바뀌어도 코드의 변경이 없다
- interface가 큰 틀이 되어 개발 시간을 단축할 수 있다.
- 표준화가 가능하다(ex: JDBC)
- 서로 관계없는 클래스들과 인터페이스로 새로운 관계를 만들 수 있다.
'객체지향' 카테고리의 다른 글
인터페이스 (0) | 2021.11.08 |
---|---|
다형성 (0) | 2021.11.08 |
[상속] 제어자, static , final (0) | 2021.11.06 |
[상속] 참조변수 super, 생성자 super() (0) | 2021.11.05 |
[상속] 오버라이딩 (0) | 2021.11.05 |