ultra_dev
이것이 자바다 CH 7-2(상속) 본문
☑️ 클래스 타입 변환
:클래스의 타입 변환은 상속 관계에 있는 클래스 사이에서 발생한다.
- 📋자동타입변환
부모타입 변수 = 자식타입객체;
-> 자식 타입 객체가 부모 타입으로 자동타입변환 이루어짐
만약 Cat이 Animal 상속 시,
Cat cat = new Cat();
Animal animal = cat;
또는
Animal animal = new cat();
-> cat과 animal 변수는 타입만 다를뿐 동일한 cat 객체 참조
cat == animal
→ 바로 위 부모가 아니더라도 상속 계층에서 상위타입이라면 자동타입 변환이 일어남
→ 부모 타입으로 자동 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근 가능
- 비록 변수는 자식 객체 참조하지만 접근 가능한 멤버는 부모 클래스 멤버로 한정!
- But 자식 클래스에서 오버라딩된 메소드가 있다면 부모 메소드가 아닌 오버라이딩된 메소드가 호출됨 → 다형성과 관계
class Parent{
void method1(){...}
void method2(){...}
class child extends Parent{
void method2(){오버라이딩!!!!}
void method3(){...}
------------------------------------------------------------------------------------
//child객체 생성 후 , Parent 변수에 대입해서 자동 타입 변환시
Child child = new Child();
Parent parent = child;
parent.method1(); -> OK 호출 가능
parent.method2(); -> Child 클래스의 오버라이딩된 메소드 호출
parent.method3(); -> 호출 불가!!!
- 📋 강제타입변환
:자식 타입은 부모 타입으로 자동변환되지만 반대로 부모타입은 자식타입으로 자동변환 안됨!
→ 강제타입변환 필요
자식타입 변수 = (자식타입) 부모타입객체;
->무조건 가능한 것 아님!!
-> 자식 객체가 맨위처럼 부모 타입으로 자동 타입변환된 이후 다시 자식 타입으로 변환할 때만
강제타입변환 사용 가능
✏️ 사용 이유 : 자식 객체가 부모 타입으로 자동 변환 시, 부모 타입으로 선언된 필드와 메소드만 사용 가능한 제한사항이 생김
→ 따라서 자식 타입에 선언된 필드와 메소드를 다시 사용하고 싶다면 강제 타입변환을 통해 다시 자식 타입으로 변환 하는 것
☑️ 다형성
: 사용 방법은 동일하지만 다른 결과가 나오는 성질
ex)
한국 타이어, 금호 타이어가 타이어 상속하고 있고 타이어의 메소드를 각자 오버라이딩 하고 있다면
타이어 메소드 호출시 오버라이딩된 메소드가 호출 된다.
다형성을 구현하기 위해서는 자동타입변환과 메소드 재정의가 필요
→ 위 예시에서 한국타이어와 금호타이어는 타이어 타입(부모)로 자동 타입 변환 가능하고, 타이어 메소드 오버라이딩하고 있음
- 필드 다형성
:필드 타입은 동일하지만 대입 객체가 달라져서 실행 결과가 다양하게 나올 수 있음
public class Car{
public Tire tire;
public void run(){
tire.roll();
}
}
------------------------------------------------------------------------------
//Car객체 생성
Car myCar = new Car();
//한국타이어 장착
myCar.tire = new HankookTire();
//금호타이어 장착
myCar.tire = new KumhoTire();
-> 금호타이어와 한국타이어를 Tire 필드에 대입! 자동타입변환이 되기 때문에 가능
→ Car 클래스의 run메소드는 이제 한국타이어와 금호타이어의 오버라이딩된 메소드 호출
→ 필드의 다형성
- 매개변수 다형성
:메소드가 클래스 타입의 매개변수 가지는 경우, 동일한 타입의 객체를 제공하는 것이 정석이지만, 자식 객체를 제공할 수 도 있다 → 다형성
public class Driver{
public void drive(Vehicle vehicle) {
vehicle.run();
}
}
-------------------------------------------------------------------------------
Driver driver = new Driver();
Vehicle vehicle = new Vehicle();
driver.drive(vehicle);
-> drive()메소드 호출시 이렇게 vehicle 객체를 제공하는 것이 정석이지만 자동타입변환으로 인해
Vehicle의 자식 객체도 제공할 수 있다.
Driver driver = new Driver();
Bus bus = new Bus();
driver.drive(bus); -> Bus객체의 run()호출
-> 자동타입변환이 발생됨 (Vehicle vehicle = bus;)
→ 어떤 자식 객체가 제공되느냐에 따라 drive()의 실행 결과가 달라짐 → 매개변수의 다형성
☑️ 객체 타입 확인
: instanceof 연산자
boolean result = 객체 instanceof 타입;
-> instanceof 좌항에는 객체, 우항에는 타입
-> 좌항의 객체가 우항의 타입이면 true 아니면 false
→ 강제타입변환전에 매개값의 타입여부 확인할 때 주로 사용
→ 특정 타입이 아니면 강제타입변환을 할 수 없기 때문
public void method(Parent parent) {
if(parent instanceof Child) { <- parent 매개변수가 참조하는 객체가 Child타입인지 확인
Child child = (Child) parent; <- 맞으면 강제타입변환
}
}
Java 12부터는 강제타입변환 수식 써줄 필요 없이 밑에와 같이 간단하게 사용가능
if(parent instanceof Child child) {}
java12부터는 연산의 결과가 true일 경우,
바로 우측 타입 변수를 사용할 수 있기 때문에 강제타입변환 필요 없음
☑️ 추상 클래스
: 추상 = 실체 간에 공통되는 특성을 추출 한 것
객체를 생성할 수 있는 클래스 = 실체클래스
이 클래스들의 공통 필드, 메소드를 추출해서 선언한 클래스 = 추상 클래스
→ 추상 클래스는 실체 클래스의 부모 역할을 한다
→ 따라서 실체 클래스는 추상 클래스를 상속해서 공통적인 필드, 메소드 물려 받을 수 있다.
💥 추상 클래스는 실체 클래스의 공통 필드, 메소드를 추출해서 만들었기 때문에
new 연산자를 사용해서 객체를 직접 생성할 수 없다.
- 추상 클래스는 실체 클래스를 만들기 위한 부모 클래스로만 쓰인다
→ 즉, 추상 클래스는 extends 뒤에만 올 수 있다!!!
public abstract class 클래스명{} <- 추상클래스 선언, 클래스선언시 abstarct 키워드 붙히면 됨
→ 추상 클래스도 필드, 메소드 선언 가능
📌 자식 객체 생성시 super()로 추상 클래스 생성자가 호출되기 때문에 생성자 반드시 필요!
☑️ 추상 메소드와 재정의
: 추상 클래스 작성시, 메소드 선언부(리턴타입, 메소드명, 매개변수)만 동일하고 안에 실행 내용은 자식클래스마다 달라야 하는 경우 많음
ex)Animal 추상 클래스에서 sound() 메소드 선언 시, Dog 클래스는 “멍멍” Cat 클래스는 “야옹” 소리가 나오게 하는 경우
이런 경우를 위해 추상 클래스는 추상 메소드 선언 가능
일반 메소드와 차이점은 abstarct 키워드가 붙고 메소드 실행 내용인 중괄호{}가 없다!
→ 즉 추상 메소드는 자식 클래스의 공통 메소드라는 것만 정의할 뿐, 실행 내용은 가지지 않는다!
public abstract class Animal{
abstract void sound();
}
→ 따라서 추상메소드는 자식 클래스에서 반드시 오버라딩해서 실행내용을 채워야 한다.
☑️ 봉인된 클래스
: 원래 final 클래스 제외한 모든 클래스는 부모 클래스 가능
→ Java15부터는 무분별한 자식 클래스 생성 방지 위해 봉인된(sealed) 클래스 도입
public sealed class person permits Employee, Manager {...}
→ sealed 키워드 사용 + permits 키ㅝ드 뒤에 상속 가능한 자식 클래스 지정
→ 봉인된 person 클래스 상속 받은 Employee와 Manager 클래스는 final 또는 non-sealed 키워드 혹은 sealed 키워드 선언해야 한다.
public final class Employee extends Person {...}
public non-sealed class Manager extends Person{...}
final 은 말 그대로 더 이상 상속 불가
non-sealed는 봉인 해제한다는 뜻 따라서 Manager 클래스는 또 자식 클래스 만들 수 있음.
'이것이 자바다' 카테고리의 다른 글
이것이 자바다 CH 9(중첩 선언과 익명 객체) (0) | 2023.01.13 |
---|---|
이것이 자바다 CH 8(인터페이스) (0) | 2023.01.13 |
이것이 자바다 CH 7-1(상속) (0) | 2023.01.13 |
이것이 자바다 CH 6-2(클래스) (0) | 2023.01.13 |
이것이 자바다 CH6-1(클래스) (0) | 2023.01.13 |