다형성 (Polymorphism)
자바 객체 지향 프로그래밍의 가장 핵심적인 부분이라고 할 수 있는 다형성이다
하나의 객체가 여러가지 형태를 가질 수 있다
한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것을 의미하는데
구체적으로 말해보면 상위 클래스 타입의 참조변수를 통해 하위 클래스 객체를 참조할 수 있도록 허용한 것이다
참고로 참조변수가 사용할 수 있는 멤버의 개수는 실제 객체의 멤버 개수보다 같거나 적어야 한다
상속에서 배웠듯이 상위 클래스를 상속받은 하위 클래스 멤버 개수가 상위의 것보다 많아지는 것을 보면 이해가 가는 부분
상속을 통해 확장이 될 수 있을지언정 축소되는 건 있을 수 없는 일이기 때문에
하위 클래스에서 사용할 수 있는 멤버의 개수가 항상 상위 클래스와 같거나 많게 되는 구조다
당연히 이러한 다형성이 있기 때문에 얻을 수 있는 장점으로는
코드의 중복을 줄여서 효율적으로 프로그래밍 할 수 있다는 점을 들 수 있다
메소드 오버로딩, 오버라이딩 또한 다형성의 예시이다
매번 다른 이름의 메소드명을 만들지 않더라도 덮어쓰는 식의 사용방법으로 시간을 절약할 수 있다
참조변수 타입 변환
참조변수도 타입변환이 가능한데, 사용할 수 있는 멤버의 개수 조절을 의미한다
1. 상호 상속관계에 있는 상위-하위 클래스 사이에서만 타입변환이 가능
2. 하위에서 상위로 업캐스팅(타입변환)은 괄호를 생략 가능
3. 상위에서 하위로 다운캐스팅(타입변환)은 괄호 명시
public class ElectronicTest {
public static void main(String[] args) {
MainComputer mainComputer = new MainComputer();
SamsungPhone samsungPhone = new SamsungPhone();
ElectronicObject electronicObject = mainComputer;
// ElectronicObject electronicObject = (ElectronicObject) mainComputer;
//상위 클래스인 ElectronicObject로 변환. 괄호 생략 가능
MainComputer mainComputer1 = (MainComputer) electronicObject;
//하위 클래스인 MainComputer로 변환. 괄호 생략 불가능, 괄호 명시해줘야 함
// SamsungPhone samsungPhone = (SamsungPhone) MainComputer;
// 서로 상속 관계가 아니기 때문에 타입 변환 불가능
}
}
상속관계에 있는 클래스 간에는 상호 타입변환이 자유롭다.
하위에서 상위로 변환할 땐 괄호를 생략할 수 있고 그 반대의 경우엔 괄호를 생략할 수가 없다
그리고 서로 상속관계가 아니면 타입 변환 자체가 불가능하다
instanceof 연산자
참조변수의 타입변환, 업 or 다운 캐스팅이 가능한지 여부를 boolean 타입으로 확인할 수 있는 문법요소
캐스팅 여부를 판단하기 위해선 2가지
객체를 어떤 생성자로 만들었지 ?
클래스 사이 상속관계가 있나 ?
이걸 판단해야 한다
프로젝트 규모가 커지고 클래스가 많아지면 이런 정보를 직접 확인하는건 힘든 일이기 때문에
instanceof 를 사용한다
참조변수 instanceof 타입
여기서 리턴 값이 true가 나오면
참조변수가 검사한 타입으로 타입 변환이 가능하다는 말이고
false가 나오면 타입변환이 안된다는 뜻이다
더불어 참조변수가 null이어도 false를 반환한다
다형성 활용 예제
전공책 정보 조회하는 간단한 입출력 콘솔을 만들거다
package Majorbook;
public class MajorBook {
String bookName;
String publisher;
String subject;
int yearOfPublication;
public void show() {
System.out.println("책 이름 : " + bookName);
System.out.println("출판사 : " + publisher);
System.out.println("과목 : " + subject);
System.out.println("출판년도 : " + yearOfPublication);
}
}
가장 상위 클래스인 MajorBook 이라는 클래스를 만들고
각 요소를 타입과 함께 변수 선언해주고
show() 메소드를 이용해서 콘솔 출력 부분을 만들어준다
package Majorbook;
public class DataBase extends MajorBook {
public DataBase(){
bookName = "데이터베이스론";
publisher = "정익사";
subject = "데이터베이스";
yearOfPublication = 20100115;
}
}
package Majorbook;
public class DataStructure extends MajorBook {
public DataStructure(){
bookName = "C로 배우는 쉬운 자료구조";
publisher = "한빛 아카데미";
subject = "자료구조";
yearOfPublication = 20210630;
}
}
package Majorbook;
public class Linux extends MajorBook {
public Linux(){
bookName = "페도라 리눅스";
publisher = "한빛 아카데미";
subject = "리눅스";
yearOfPublication = 20171110;
}
}
package Majorbook;
public class Network extends MajorBook {
public Network(){
bookName = "데이터 통신과 컴퓨터 네트워크";
publisher = "한빛 아카데미";
subject = "네트워크";
yearOfPublication = 20161226;
}
}
package Majorbook;
public class Os extends MajorBook{
public Os(){
bookName = "IT CookBook 202 운영체제";
publisher = "한빛 아카데미";
subject = "운영체제";
yearOfPublication = 20160630;
}
}
이렇게 각 과목 별로 메소드를 만들어준다
그리고 메인 메소드를 만든다
콘솔 입력을 반복해주기 위해 do-while을 사용했다
do 부분을 우선 먼저 반복해준뒤, while 조건에 따라 반복여부를 정해주는데
그냥 나는 true로 만들어두고 탈출 조건으로 break 문을 사용,
else문에서 올바른 입력 값이 아닌 경우 반복을 종료하게끔 만들었다
package Majorbook;
import java.util.Objects;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
MajorBook majorBook;
do {Scanner scanner = new Scanner(System.in);
System.out.printf("전공책 조회 : ");
String input = scanner.nextLine();
if (Objects.equals(input, "데이터베이스")) {
majorBook = new DataBase();
majorBook.show();
} else if (Objects.equals(input, "자료구조")) {
majorBook = new DataStructure();
majorBook.show();
} else if (Objects.equals(input, "네트워크")) {
majorBook = new Network();
majorBook.show();
} else if (Objects.equals(input, "리눅스")) {
majorBook = new Linux();
majorBook.show();
} else if (Objects.equals(input, "운영체제")) {
majorBook = new Os();
majorBook.show();
}
else {
System.out.println("올바른 입력 값이 아닙니다, 종료합니다");
break;
}
}while(true);
}
}
전공책 조회 :
라는 콘솔 입력창을 통해 과목을 작성해주면
저렇게 정보가 뜨게되고
계속 입력하는 창이 뜨다가
올바른 입력 값이 뜨지 않으면 반복 입력 콘솔을 종료한다
위 예시는
다형성의 좋은 예시라고 할 수 있는데,
각 클래스 별로 따로 만들어서 패키지 안에 하나 하나 저장해두고 상속관계를 이용해서
메인 메소드를 작동할 수 있게끔 하였다
이 부분이 자바 객체 지향 프로그래밍, 다형성의 좋은 장점들을 이용한 예시이기 때문이다
코드의 중복을 줄여서 효율적인 코딩을 할 수 있다는 것
'Java' 카테고리의 다른 글
[Java 컬렉션] 컬렉션 프레임워크(Collection Framework) (0) | 2022.06.01 |
---|---|
[Java 컬렉션] 제네릭 (Generic) (0) | 2022.05.29 |
[Java OOP 심화] 추상화 (Abstract) (0) | 2022.05.29 |
[Java OOP 심화] 캡슐화 (Encapsulation) (0) | 2022.05.25 |
[Java OOP 심화] 상속( Inheritance) (0) | 2022.05.25 |
댓글