다형성(Polymorphism)
하나의 레퍼런스 타입 객체가 여러 다른 타입을 수용할 수 있도록 하는 것을 다형성이라고 한다.
다형성은 상속관계과 인터페이스에서 주로 사용되고 효율적으로 프로그램을 만들 수 있도록 도움을 주면서 자바에서 매우 중요한 개념 중 하나이다.
레퍼런스 타입 -> 변수에 객체를 가리키는 참조(주소)값이 저장
- 다형성은 상속(인터페이스) 관계에서 상위타입의 참조변수로 하위타입의 객체를 다룰 수 있도록 한다.
- 만약 상위 타입으로 형변환 했을 경우 하위에서 생성한 메서드는 사용이 불가하다. (오버라이딩한 메서드는 가능)
- 하위클래스를 상위클래스로 형변환 할 경우 자동으로 캐스팅된다.
- 반대로 상위클래스에서 하위클래스로 형변환 할 경우 강제로 캐스팅 해주어야 한다.
캐스팅 연산이 가능한지 판단하고자 할 때에는 instanceof 키워드는 사용한다.
obj2(타입을 검사할 객체) instanceof obj1(타입명)
- 예제코드
전화번호부 만들기
PhoneInfo.java
public class PhoneInfo {
private String name;
private String phoneNo;
private String birth;
public PhoneInfo() {}
public PhoneInfo(String name, String phoneNo, String birth) {
super();
this.name = name;
this.phoneNo = phoneNo;
this.birth = birth;
}
public PhoneInfo(String name) {
this.name = name;
}
//기능 : 1명의 전화내역 출력
public void show() {
System.out.println("이름 : " + name);
System.out.println("전화번호 : " + phoneNo);
System.out.println("생년월일 : " + birth);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
public String getBirth() {
return birth;
}
public void setBirth(String birth) {
this.birth = birth;
}
}
Universe.java
public class Universe extends PhoneInfo {
private String major;
private String year;
public Universe() {}
public Universe(String name, String phoneNo, String birth, String major, String year) {
super(name, phoneNo, birth);
this.major = major;
this.year = year;
}
@Override
public void show() {
super.show();
System.out.println("학과 : " + major);
System.out.println("학년 : " + year);
}
public void show2() {
System.out.println(major + " : " + year);
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
}
Universe클래스는 PhoneInfo를 상속하고 있다.
company.java
public class Company extends PhoneInfo {
private String dept;
private String position;
public Company() {}
public Company(String name, String phoneNo, String birth, String dept, String position) {
super(name, phoneNo, birth);
this.dept = dept;
this.position = position;
}
@Override
public void show() {
super.show();
System.out.println("부서 : " + dept);
System.out.println("직책 : " + position);
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
Company클래스는 PhoneInfo클래스를 상속하고 있다.
Manager.java
public class Manager {
PhoneInfo arr[];
Scanner sc = new Scanner(System.in);
private int count = 0;
public Manager() {
arr = new PhoneInfo[10]; // 객체생성과 동시에 배열 초기화
}
public void addPhoneInfo() {
// 이름, 전화번호, 생년월일 입력
// 1.일반 2.동창(major, year) 3.직장(dept, position)
System.out.println("메뉴를 선택해 주세요.");
System.out.println("1.일반 2.동창 3.직장");
String menu = sc.nextLine();
System.out.println("이름 : ");
String name = sc.nextLine();
System.out.println("전화번호 : ");
String phoneNo = sc.nextLine();
System.out.println("생년월일 : ");
String birth = sc.nextLine();
switch (menu) {
case "1":
arr[count++] = new PhoneInfo(name, phoneNo, birth);
break;
case "2":
System.out.println("학과 : ");
String major = sc.nextLine();
System.out.println("학번 : ");
String year = sc.nextLine();
arr[count++] = new Universe(name, phoneNo, birth, major, year);
break;
case "3":
System.out.println("부서 : ");
String dept = sc.nextLine();
System.out.println("직책 : ");
String position = sc.nextLine();
arr[count++] = new Company(name, phoneNo, birth, dept, position);
break;
}
}
public void listPhoneInfo() {
// 배열에 있는 모든 PhoneInfo 객체를 출력
// show()
System.out.println("메뉴를 선택해 주세요.");
System.out.println("1.전체 2.동창 3.직장");
String menu = sc.nextLine();
switch (menu) {
case "1":
System.out.println("======전체======");
for (int i = 0; i < count; i++) {
arr[i].show();
}
break;
case "2":
System.out.println("======동창======");
for (int i = 0; i < count; i++) {
if (arr[i] instanceof Universe) {
arr[i].show();
Universe uni = (Universe) arr[i];
uni.show2();
}
}
break;
case "3":
System.out.println("======직장======");
for (int i = 0; i < count; i++) {
if (arr[i] instanceof Company) {
arr[i].show();
}
}
break;
}
}
public void searchPhoneInfo() {
// 이름의 전화번호 내역을 검색되도록 한다.
System.out.println("이름 : ");
String name = sc.nextLine();
int idx = -1;
for (int i = 0; i < count; i++) {
PhoneInfo info = arr[i];
if (name.equals(info.getName())) {
info.show();
idx = i;
}
}
if (idx == -1) {
System.out.println("찾을 수 없습니다.");
}
}
}
addPhoneInfo 메서드를 보면 정보를 추가할 때 일반, 동창, 직장 서로 다른 객체를 하나의 배열안에 넣으려고 하고 있다. 하지만 자바의 다형성으로 Universe와 Company가 PhoneInfo를 상속하고 있기 때문에 PhoneInfo 상위클래스로 자동 형변환 되어 서로 공존할 수 있게 된다.
listPhoneInfo 메서드를 보면 조건문에서 instanceof 키워드를 통해 타입을 검사하고 동창이면 동창만 직장이면 직장만 출력될 수 있도록 하였다.
Main.java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 1.추가 2.출력 3.종료
Scanner sc = new Scanner(System.in);
Manager m = new Manager();
while (true) {
System.out.println("1.추가 2.출력 3.검색 4.종료");
System.out.println("선택 : ");
String menu = sc.nextLine();
switch (menu) {
case "1":
m.addPhoneInfo();
break;
case "2":
m.listPhoneInfo();
break;
case "3":
m.searchPhoneInfo();
break;
case "4":
System.out.println("프로그램 종료");
return;
} //end switch
} // end while
} //end main()
}
'Java' 카테고리의 다른 글
[Java] java.lang패키지(1) Object 클래스, wrapper클래스 (0) | 2020.07.17 |
---|---|
[Java] 객체지향(5) 추상클래스와 인터페이스 (0) | 2020.07.16 |
[Java] 객체지향(3) 상속 정리 (0) | 2020.07.15 |
[Java] 객체지향(2) 연습 정리 (0) | 2020.07.11 |
[Java] 객체지향(1) 정리 (0) | 2020.07.11 |