대학교

자바 - (10) 타입 변환과 다형성

매 석 2023. 11. 24. 17:10
반응형

다형성

사용 방법은 동일하지만 다양한 객체를 활용해 여러 실행결과가 나오도록 하는 성질이다.

출처 : 혼자 공부하는 자바

메소드 재정의는 Override로 저번 포스팅에서 다루었고 이번 포스팅에서는

타입 변환에 대해 다루려고 한다.

 

자동 타입 변환

출처 : 혼자 공부하는 자바

위와 같이 ( 부모타입 변수 = 자식타입;)과 같은 형태를 사용하면 자동 타입 변환이 일어난다.

당연히 부모로부터 상속받은 것이 자식이기에 자동 타입 변환이 일어난다.

추가로 바로 위 부모가 아니더라도 상속 계층에서 상위 타입인 경우도 자동 타입 변환이 가능하다.

출처 : 혼자 공부하는 자바

부모 타입으로 자동 타입 변환 이후에는 부모 클래스에 선언된 필드 및 메소드만 접근 가능하다.

예외적으로 메소드가 자식 클래스에서 재정의된 경우 자식 클래스의 메소드가 대신 호출된다.

출처 : 혼자 공부하는 자바

 

다형성

- 필드의 다형성

필드 타입을 부모 타입으로 선언할 경우이다.

출처 : 혼자 공부하는 자바

부모인 car 필드의 값에 자식인 HankookTire와 같은 자식 객체가 저장되는 형태를 말한다.

- 매개 변수의 다형성

매개 변수를 부모 타입으로 선언하는 효과를 가진다.

메소드 호출 시 매개값으로 부모 객체 및 모든 자식 객체를 제공할 수 있다.

출처 : 혼자 공부하는 자바

Driver에는 부모 매개 변수가 기본으로 지정되어있지만, 이의 자식 객체인 Bus를 넣어 자동 타입 변환이

발생하는 것을 확인할 수 있다.

 

강제 타입 변환

부모 타입을 자식 타입으로 변환하는 것을 말한다.

강제, 자동 타입 변환은 이전에 다루었던 형변환을 생각하면 쉽다.

출처 : 혼자 공부하는 자바

부모 타입일 때는 자식 객체의 메소드와 필드에 접근이 불가하지만,

강제 타입 변환을 사용해 다시 자식 객체로 타입을 변환하면 다시 사용이 가능하다.

하지만 타입을 확인하지 않고 강제 타입을 변환하면 ClassCastException이 발생할 수 있다.

이를 위해서는 instanceof 연산자를 활용하면 된다.

출처 : 혼자 공부하는 자바

위와 같이 ( 객체 instanceof 타입)을 통해 해당 객체가 해당 타입이 맞으면 true 아니면 false라는

반환 값을 통해 if문으로 강제 타입 변환을 할 지 고려하여 오류를 피할 수 있다.

 

실습 문제

 

Person, Student, StudentWorker 클래스를 만들고, 각각 speak() 메소드를 정의하여 자식클래스에서 재정의 하도록 함. 아래 출력과 같이 speak() 결과가 출력되도록 함.

(1) Person 클래스는 이름과 나이를 필드로, speak()를 메소드로 가짐. 출력예처럼 “감자바” 를 객체로 선언함. (2) Student 클래스는 studentNo를 필드로, speak()를 재정의 하며, study() 메소드도 가짐. 출력예처럼 “김영희”를 객체로 선언함.

(3) StudentWorker 클래스는 salary를 필드로 갖고 speak()를 재정의 하며 work() 메소드도 가짐. 출력예처럼 “배철수”를 객체로 선언함.

(4) 필드 형변환: Person pAny를 선언하여 Student 및 StudentWorker 클래스 객체를 대입 한 후, speak()를 실행함

(5) 메소드 형변환: static 메소드 personSpeak(Person p)를 정의하여 p.speak()를 수행하도 록 하고, 그 메소드를 호출하면서 세 가지 클래스의 객체들을 전달함.

(6) 출력예:

제 이름은 감자바 나이는 30살입니다.

제 이름은 김영희 나이는 20살입니다.

== 그리고 학번은 123456 입니다.

== 자바를 열심히 공부합니다.

제 이름은 배철수 나이는 22살입니다.

== 그리고 학번은 234567 입니다.

== 그리고 월급은 200만원입니다.

== 열심히 알바도 합니다.

---- 필드 다형성 테스트 ----

제 이름은 김영희 나이는 20살입니다.

== 그리고 학번은 123456 입니다.

제 이름은 배철수 나이는 22살입니다.

== 그리고 학번은 234567 입니다.

== 그리고 월급은 200만원입니다.

---- 메소드 다형성 테스트 ----

제 이름은 감자바 나이는 30살입니다.

제 이름은 김영희 나이는 20살입니다.

== 그리고 학번은 123456 입니다.

제 이름은 배철수 나이는 22살입니다.

== 그리고 학번은 234567 입니다.

== 그리고 월급은 200만원입니다.

정답 코드 :

package task76;

public class PersonExam {

	static void personSpeak(Person p) {
		p.speak();
	}
	
	public static void main(String[] args) {
		Person p = new Person("감자바",30);
		p.speak();
		Student p2 = new Student("김영희",20,123456);
		p2.speak();
		p2.study();
		StudentWorker p3 = new StudentWorker("배철수",22,234567,200);
		p3.speak();
		p3.work();
		
		System.out.println("\n---필드 다형성 테스트 ---");
		Person pAny;
		pAny = p2;
		pAny.speak();
		pAny = p3;
		pAny.speak();
		
		System.out.println("\n---메소드 다형성 테스트 ---");
		personSpeak(p);
		personSpeak(p2);
		personSpeak(p3);
		
	}

}

class Person {
	private String name;
	private int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	void speak() {
		System.out.printf("제 이름은 %s 나이는 %d살입니다.\n",name,age);
	}
}

class Student extends Person{
	private int studentNo;
	
	public Student(String name, int age, int studentNo) {
		super(name, age);
		this.studentNo = studentNo;
	}

	@Override
	void speak() {
		super.speak();
		System.out.printf("== 그리고 학번은 %d 입니다.\n",studentNo);
	}
	void study() {
		System.out.println("== 자바를 열심히 공부합니다.");
	}
	
}

class StudentWorker extends Student{
	private int salary;
	public StudentWorker(String name, int age, int studentNo, int salary) {
		super(name, age, studentNo);
		this.salary = salary;
	}
	@Override
	void speak() {
		super.speak();
		System.out.printf("== 그리고 월급은 %d만원입니다.\n",salary);
	}
	void work() {
		System.out.println("== 열심히 알바도 합니다.");
	}
	
	
}