Part1 다형성
1. 다형성이란:
- 자바에서는 한 타입의 참조변수로 여러 타입의 객체 참조 가능
- 부모클래스 타입의 참조변수(부모의 데이터타입으로)로 자식 클래스의 인스턴스(객체) 참조 가능
2. 다형성이 가능한 이유
- 자바의 상속: 자식클래스는 부모클래스로부터 필드, 메서드, 그리고 "데이터타입"을 물려받는다.
[1] 부모타입 자료형으로 부모 객체를 다루는 경우
Parent p1 = new Parent();
p1.printParent();
[2] 자식타입 자료형으로 자식객체를 다루는 경우
Child1 c1 = new Child1 ();
c1.printChild1();
c1.printParent(); // 부모로부터 물려받은 메서드
==> 자식타입 객체로는 자기 자신, 그리고 부모의 메서드 모두 접근가능
[3] 부모타입 자료형으로 자식객체를 다루는 경우 (upcasting): * 다형성 적용 *
-> 자동형변환: 자식 -> 부모타입 형변환
Parent p2 = new Child1(); // 양변의 데이터타입이다름 ==> 자동형변환 (promotion)
Parent p2 = (Parent) new Child1(); // 자손->부모타입 형변환은 JVM자동형변환 가능
-> 메모리에서 일어나는 일
1) stack영역에 p2만큼의 공간(4byte)생성 (0x100으로 가는 주소를 저장하고 있음)
2) heap 영역 0x100에 Child1() 만큼의 공간 생성
2-1) 부모인 Parent()만큼의 공간생성
2-2) 부모 제외, 자식만큼 공간 추가생성
3) Parent 형태를 데이터로 다루는 p2는 Child1() 공간 중에서 Parent 공간만큼만 활용가리킴
* 부모타입 객체로 자식타입의 메소드 호출시 : 오류발생
(Child1)p2.printChild();
---> 오류 : 연산자 우선순위에 의해서 p2.printChild()가 먼저 실행된 후 Child1으로 형변환
Parent p2 = new Child1();
3. ****주의 ***** down casting이 성립하는 조건
[4] 자식타입 자료형으로 부모객체를 다루는 경우 (down casting):
==> promotion불가능, force casting시도시 일반적으로 runtime error발생
Child1 c2 = new Parent(); --> promotion 불가능
Child1 c2 = (Child1)new Parent(); ==> force casting 시 runtime error 발생
ClassCastException
===> 단, 자식클래스 => up casting(부모타입 자료형으로 변환)
==> down casting(다시 자식타입 자료형으로 변환)
인 경우 !
force casting을 통해 강제형변환 후 사용가능
Parent p = new Child1(); // 자손타입 객체를 자동형변환하여 부모타입 참조변수p에 저장
Child1 c = (Child1)p;
// 부모타입으로 다운캐스팅된 자손객체 (p에 저장되어 있는 주소값)를 다시 자식타입으로 force casting
====> 이 경우 jvm은, (Child1)p의 태생인 child1 객체를 알고있다!
4. 다형성의 장점
- 부모타입 자료형으로 다양한 자식객체를 다룰수 있음
==> 하나의 배열 안에 여러개 타입 넣을 수 있음
==> 반복문 사용 가능
( 부모타입 배열에 다양한 자손타입 대입 가능 ==> 자손타입 객체가 부모타입 객체로 upcasting 되어 들어감)
====> 소스코드 감소로 효율성 증대
< 다형성을 접목하기 전 배열 >
Class child1 extends Parent.
Class child2 extends Parent.
Parent를 자손으로 하는 child1형 객체 2개, child2 객체 2개를 담으려면,
child1[], child2[] 배열이 필요하다
Child1[] arr1 = new Child1[2];
arr1[0] = new Child1(1,2,3);
arr1[1] = new Child1(4,5,6);
Child2[] arr2 = new Child2[2];
arr2[0] = new Child2(7,8,9);
arr2[1] = new Child2(10,11,12);
< 다형성을 접목한 후 배열 > : 자손타입은 부모타입으로 자동 upcasting이 가능함
===> 한 종류의 배열로 여러 자손의 객체를 다룰 수 있음
Parent[] arr = new Parent[4];
arr[0] = new Child1(1,2,3); // child1 타입 객체가 parent타입으로 promotion된 후 대입
arr[1] = new Child1(2,3,4);
arr[2] = new Child2(4,5,6); // child2 타입 객체가 parent타입으로 promotion된 후 대입
arr[3] = new Child2(3,4,5);
for (int i=0; i < arr.length; i++) {
arr[i].printParent();
}
---------------------------------------------------------
printChild1, 2를 호출하려면 ==> child형으로 강제형변환 후 사용
하단의 arr[0]~ arr[3]은 태생이 child형이었는데 upcasting되어 arr배열에 저장되어 있었던 것
casting 연산자로 다시 downcasting하여 child1, child2가 가지고 있는 메소드 사용 가능
((Child1)arr[0]).printChild1();
((Child2)arr[1]).printChild2();
((Child2)arr[2]).printChild2();
((Child1)arr[3]).printChild1();
instanceof 연산자 => t/f반환 if (a instanceof b) { }
현재 객체가 실질적으로 어떤 클래스타입을 참조하는지 확인할 때 사용
for (int i=0; i < arr.length ; i++) {
if(arr[i] instanceof Child1) {
((Child1)arr[i]).printChild1();
} else {
((Child2)arr[i]).printChild2();
}
}
for (int i=0; i < arr.length ; i++) {
arr[i].print();
public class ElectronicsController1 {
// 필드부
private Tv tv;
private SmartPhone sp;
private AirPod ap;
// 생성자부 생략 ===> jvm이 기본생성자 자동 생성
// 메서드부
// 재고를 추가해주는 기능 --> 오버로딩 (조건: 매개변수의 자료형 or 개수 or 순서가 다르다)
public void insert(Tv tv) { //setter역할을 하는 메서드
this.tv =tv;
}
public void insert(SmartPhone sp) {
this.sp =sp;
}
public void insert(AirPod ap) {
this.ap =ap;
}
public Tv selectTv() { // getter역할을 하는 메서드
return tv;
}
public SmartPhone selectSmartPhone () {
return sp;
}
//
public AirPod selectAirPod () {
return ap;
}
}
public class Electronics {
// 필드부
private String brand;
private String name;
private int price;
// 생성자부
public Electronics() {
super();
}
public Electronics(String brand, String name, int price) {
super();
this.brand = brand;
this.name = name;
this.price = price;
}
// 메서드부
getter-setter
toString생략
ublic class SmartPhone extends Electronics {
// 필드부 없음
// 생성자부
private String phoneNumber;
public SmartPhone() {
super();
}
public SmartPhone(String brand, String name, int price, String phoneNumber) { // 매개변수 순서는 부모의 생성자 매개변수와 동일하게! 바꾸지 말것
super(name, brand, price);
this.phoneNumber = phoneNumber;
}
// getter - setter
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
// toString
@Override
public String toString() {
return super.toString() + ", phoneNumber : "+phoneNumber;
}
}
class Run {
public static void main(String[] args) {
1. 다형성을 적용 하지 않았을 경우
객체 생성: 재고를 담을 필드들이 메모리영역에 올라감
ElectronicsController1 ec1 = new ElectronicsController1();
***이해가 어려웠던 부분
ec1.insert(new Tv("LG", "스탠드형티비", 3000000, false));
// new Tv()의 주소값을 매개변수로 넘기는 것!
ec1.insert(new SmartPhone("베가", "lg",2000000, "010-1234-5678"));
ec1.insert(new AirPod("베가", "lg",2000000, true));
Tv t = ec1.selectTv();
SmartPhone s = ec1.selectSmartPhone();
AirPod a = ec1.selectAirPod();
System.out.println(t.toString()); // toString은 출력문 안에 있을 때에는 생략이 가능하다
System.out.println(s);
System.out.println(a);
2. 다형성을 적용했을 경우
ElectronicsController2 ec2 = new ElectronicsController2();
ec2.insert(new Tv("LG", "스탠드형티비", 3000000, false), 0);
ec2.insert(new SmartPhone("베가", "lg",2000000, "010-1234-5678"), 1);
ec2.insert(new AirPod("베가", "lg",2000000, true), 2);
Tv tv =(Tv) ec2.select(0);
SmartPhone sp =(SmartPhone) ec2.select(1);
AirPod ap =(AirPod) ec2.select(2);
System.out.println(tv);
System.out.println(sp);
System.out.println(ap);
// 재고 전체 출력
Electronics[] elec = ec2.selectAll(); // 얕은복사 ==> 주소값 받아옴
for (int i =0; i< elec.length; i++) {
System.out.println(elec[i]);
}
}
<기타 배운 것>
A.contains(B)
==> A 문자열에 B문자열이 포함되어 있는지 여부를,
boolean(t/f)타입으로 반환하는 메소드
boolean타입이므로 조건식 사용이 가능하다
A.equals(B)와 비슷하게 활용됨
(A문자열의 내용과 B문자열 내용이 동일한지 여부를 boolean으로 반환하는 메서드)
어려웠던 부분:
- downcasting이 가능한 경우
- 동적바인딩, 정적바인딩 다시보기
- ec1.insert(new Tv("LG", "스탠드형티비", 3000000, false));
// new Tv()의 주소값을 매개변수로 넘기는 것
'코딩공부일지 > 수업 review' 카테고리의 다른 글
컬렉션 개념, ArrayList (0) | 2022.09.22 |
---|---|
자바: abstract & interface & 예외 (0) | 2022.09.21 |
자바 - 상속 & 오버라이딩 (0) | 2022.09.20 |
자바 - 객체지향프로그래밍2( 오버로딩, 객체배열) (0) | 2022.09.14 |
자바 - 객체지향 프로그래밍1(클래스, 캡슐화, 변수, 생성자, 메서드) (0) | 2022.09.13 |