공부/JAVA
[JAVA]다형성
도토리까꿍v
2024. 4. 13. 23:04
#핵심 요약
- 다형성(Polymorphism)
- 한 객체가 여러 가지 타입을 가질 수 있는 것
- 부모클래스 타입의 참조 변수로 자식클래스 인스턴스를 생성
- instanceof 연산자
- 실제 참조하고 있는 인스턴스의 타입을 확인할 수 있는 연산자
#소스코드
다형성과 instanceof 예제
// Java 프로그래밍 - 다형성
class Person {
public void print() {
System.out.println("Person.print");
}
}
class Student extends Person {
public void print() {
System.out.println("Student.print");
} //오버라이딩 된 함수
public void print2() {
System.out.println("Student.print2");
}
}
class CollegeStudent extends Person {
public void print() {
System.out.println("CollegeStudent.print");
}
}
public class Main {
public static void main(String[] args) {
// 1. 다형성
System.out.println("== 다형성 ==");
Person p1 = new Person();
Student s1 = new Student();
Person p2 = new Student(); //다형성 구현
// Student s2 = new Person(); //이렇게는 되지 않는다.
p1.print(); //Person.print
s1.print(); //Student.print
s1.print2(); //Student.print2
p2.print(); //Student.print
// p2.print2(); //사용불가함, 오버라이딩 된 print1() 만 접근 가능함
Person p3 = new CollegeStudent();
// CollegeStudent c1 = new Student(); //자식클래스끼리 같은 부모를 상속받았더라도 이렇게는 불가하다.
p3.print(); //CollegeStudent.print
// 2. 타입 변환
System.out.println("== 타입 변환 ==");
Person pp1 = null;
Student ss1 = null;
Person pp2 = new Person();
Student ss2 = new Student();
Person pp3 = new Student(); // 업캐스팅 : 자식클래스의 객체가 부모클래스의 객체로 형변환 된 것을 '업캐스팅' 이라고 한다.
pp1 = pp2; //Person = Person
pp1 = ss2; //Person = Student
ss1 = ss2; //Student = Student
// ss1 = (Student)pp2; //Student = (Student)Person (다운캐스팅 불가)
ss1 = (Student)pp3; //Student = (Student)업캐스팅된Person -> 다운캐스팅 : 같은 부모 타입으로 업캐스팅 된 객체를 다운캐스팅하는 것은 가능하다.
//불가한 경우
CollegeStudent cc1;
CollegeStudent cc2 = new CollegeStudent();
// ss1 = (Student) cc2; //Student = (Student)CollegeStudent -> 불가
// cc1 = (CollegeStudent) ss2; //CollegeStudent = (CollegeStudent)Student 불가
// 3. instanceof
System.out.println("== instanceof ==");
Person pe1 = new Person();
Student st1 = new Student();
Person pe2 = new Student(); //업캐스팅
Person pe3 = new CollegeStudent(); //업캐스팅
System.out.println("== instance of ==");
System.out.println(pe1 instanceof Person); //true
System.out.println(pe1 instanceof Student); //false
System.out.println(st1 instanceof Student); //true
System.out.println(st1 instanceof Person); //true
System.out.println(pe2 instanceof Person); //true
System.out.println(pe2 instanceof Student); //true
System.out.println(pe3 instanceof Person); //true
System.out.println(pe3 instanceof CollegeStudent); //true
if (pe1 instanceof Student) { //아래 코드는 실행되지 않는다.
Student stu1 = (Student) pe1;
}
if (st1 instanceof Person) { //아래 코드는 실행된다.
Person per1 = (Person)st1;
}
}
}
#소스코드2
다형성 연습문제
// Practice
// 아래의 클래스와 상속 관계에서 다형성을 이용하여
// Car 객체를 통해 아래와 같이 출력될 수 있도록 Test code 부분을 구현해보세요.
// 빵빵!
// 위이잉!
// 삐뽀삐뽀!
class Car {
Car(){}
public void horn() {
System.out.println("빵빵!");
}
}
class FireTruck extends Car {
public void horn() {
System.out.println("위이잉!");
}
}
class Ambulance extends Car {
public void horn() {
System.out.println("삐뽀삐뽀!");
}
}
public class Practice {
public static void main(String[] args) {
// Test code
Car car = new Car();
car.horn(); //빵빵!
car = new FireTruck();
car.horn(); //위이잉!
car = new Ambulance();
car.horn(); //삐뽀삐뽀!
//위 Test code를 아래와 같이 표현할수도 있다.
//★★★ 타입 한개로 자식 클래스들을 다 가리킬 수 있기 때문에 아래처럼 배열로 만들어 표현 가능하다. -> 다형성의 장점 중 하나
Car car2[] = {new Car(), new FireTruck(), new Ambulance()};
for (Car item: car2) {
item.horn();
}
}
}
#소스코드2 - 설명 1
아래 처럼 타입 한 개로 배열을 만들어 여러 개의 자식클래스를 가리킬 수 있다.
그 밖의 다형성을 사용하는 이유를 알아보니..
- 위 예제의 경우 새로운 '자동차 종류' 를 추가하는 경우
- 상속과 메서드 재정의를 활용하여 확장성 있는 프로그램을 만들 수 있다. (그렇지 않을 경우 수많은 분기처리로 구현해야하며 코드의 유지보수가 어려워진다.)
- 상위 클래스에서는 공통적인 부분을 제공, 하위 클래스에서는 각 클래스에 맞는 기능 구현
- 여러 클래스를 하나의 타입(상위 클래스)으로 핸들링 할 수 있다.