지난주부터 자주 발각되는 내 모습.
복습을 안 하니 내용이 확실하게 들어오지 않는다.
필히 복습하도록.
다형성
다양한 객체 이용해서 다양한 실행결과가 나오도록 하는 성질.
메소드 재정의와 타입 변환으로 구현 가능
클래스도 상속 관계에 있는 클래스 사이에서 타입변환이 발생함
자동타입변환
클래스 E와 클래스 B는 상속 관계가 아니어서 자동 타입 변환 X
클래스 B와 클래스 C도 동일한 이유임
부모 타입으로 자동 변환된 후엔 자식 멤버 접근 X
부모 클래스에 선언된 필드, 메소드만 접근 O
단, 자식 클래스에서 메소드 재정의가 발생한 경우 자식 클래스의 메소드가 호출됨. -> 다형성과 관련된 성질
자식 클래스인 Child에서 method2()가 재정의 되어서 자식 메소드가 호출됨.
Child는 자동 타입 변환 되었기 때문에 자동타입변환 특성 상 부모 멤버만 사용 가능하기 때문에 method3은 호출할 수 없다.
다형성 구현을 위해 자동 타입 변환을 행한다.
객체 지향 프로그래밍에서 객체는 유기적인 관계. 이 객체들은 다른 객체로도 교체될 수 있어야 함. (다양한 자식 객체를 저장할 수 있음)
다형성을 구현하는 기술적 조건
필드
maxRotation: 최대 회전수
accumulatedRotation: 누적 회전수, 타이어가 1번 회전하면 1씩 증가됨
location: 타이어의 위치, 앞왼쪽/앞오른쪽/뒤왼쪽/뒤오른쪽
생성자
Tire 클래스는 location과 maxRotation를 매개값으로 필드 초기화
메소드
최대 회전수에 도달 시 타이어 펑크나는 것을 가정함
boolean roll():
타이어 1회 회전시켜서 누적 회전수 1회씩 증가(++accumulatedRotation;
) 시키는 메소드.
누적 회전수가 최대 회전수보다 작으면 남은 회전수 출력, 그게 아닌 최대 회전수가 되면 펑크 출력.
리턴: 정상회전 -> true / 펑크 -> flase
필드
4개의 타이어
Tire 객체 생성 시 location과 maxRotation을 생성자 매개값으로 지정 (frontLeftTire
의 위치와 최대 회전수는 각각 "앞왼쪽", 6회전)
메소드
int run()
4개의 타이어 1회전 시키기 위해 Tire 객체의 roll()
메소드를 각각 호출.
만약 타이어가 펑크(false)일 경우 stop()메소드 실행하고 해당 타이어 번호(int)를 리턴.
void stop()
펑크나면 실행되는 자동차 멈추는 메소드
Car 객체 생성
for문
5번 반복하면서 run() 메소드 호출.
run()의 리턴값: 펑크난 타이어 번호. problemLocation변수의 값이 됨.
정상 0 | 앞왼쪽 1 | 앞오른쪽 2 | 뒤왼쪽 3 | 뒤오른쪽 4
switch문
problemLocation의 변수값에 따라 Car객체의 타이어를 HankookTire와 KumhoTire로 교체
자동 타입 변환(15, 20, 25, 30라인)
Car 객체의 Tire 필드에 HankookTire, KumhoTire 객체를 대입. 자동 타입 변환 후에 Car 객체의 run() 메소드 호출 시 자식 클래스(HankookTire, KumhoTire)에서 재정의된 roll() 메소드가 호출됨.
메소드 호출 시에도 자동 타입 변환이 발생함.
매개값 다양화를 위한 매개 변수에 자식 객체 지정
매개변수 타입이 클래스일 경우
-> 해당 클래스의 객체, 자식 객체까지도 매개값으로 사용 가능.
즉, 매개값으로 제공되는 자식 객체에 따라 메소드의 실행결과가 다양해질 수 있음.
drive()메소드에서 Vehicle 타입의 매개값을 받아서 run()메소드 호출
자식 클래스는 Vehicle 클래스를 상속 받아 run() 메소드 재정의.
Vehicle vehicle = bus
Vehicle vehicle = taxi
부모 타입을 자식 타입으로 변환하는 것. 무조건 가능한 건 아님
자식 -> 부모 타입으로 자동 변환 후 다시 부모 -> 자식 타입으로 변환할 때 강제 타입 변환 가능
자식타입 변수 = (자식타입) 부모타입)
자동 타입 변환 시 부모 필드와 메소드만 사용 가능.
만약 자식 필드, 메소드를 사용 해야한다면 강제 타입 변환을 해서 자식 타입으로 변환한 다음 자식 필드, 메소드를 사용함.
Child 클래스에 있는 field2
필드와 method3()
메소드 사용을 위해 Parent 타입으로 자동 타입 변환 되었던 것을 Child 타입으로 강제 타입 변환을 함.
(강제 타입 변환 전에는 Child 클래스에서 선언된 필드와 메소드 사용 X)
instanceof 연산자
boolean result = 좌항(객체) instanceof 우항(타입)
좌항 객체가 우항의 인스턴스(우항의 타입으로 객체가 생성)이면 true, 아니면 flase 리턴
Parent 객체를 매개값으로 전달했을 때 method2()에서 "ClassCastException" 예외 발생. 예외 발생 시 프로그램은 즉시 종료됨.
method2는 instanceof 연산자로 객체 타입을 조사하지 않고 무조건 변환하려고 했음.
강제 타입 변환 시 꼭 instanceof 연산자로 변환시킬 타입의 객체인지 조사하여 프로그램 종료를 막아야함.