일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 스프링 시큐리티 없이
- 스프링 소셜 로그인
- android studio
- sops 암호화
- 쿠버네티스 #fabric8
- sops age
- 안드로이드 스튜디오
- 시크릿 깃에 올리기
- 로또 등수 알고리즘
- 스프링 환경변수 설정
- jpa bulk insert
- 스프링 환경변수
- 로또 앱 만들기
- spring 채팅방
- oauth 로그인
- java
- 스프링 오어스
- 로또 등수 코드
- mysql multi-row insert
- 시크릿 암호화
- 리사이클러뷰 멀티뷰
- 채팅방 구현
- jpa dto 매핑
- sops
- jpa 최적화
- multiview
- 중간 테이블 엔티티 최적화
- springboot
- hibe
- Androoid Studio
- Today
- Total
야미의 개발
[JAVA] 다형성 - 캐스팅과 메소드오버라이딩 본문
출처
김영한의 실전 자바 - 기본편 강의 - 인프런
실무에 필요한 자바 객체 지향의 핵심 개념을 예제 코드를 통해 쉽게 학습합니다., 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바 문법을 안다
www.inflearn.com
본 내용은 김영한님의 실전 자바 강의를 보고 정리한 내용입니다 자세한 내용은 강의를 참고해주세요!
다형성
객체 지향 프로그래밍에서
다형성(Polymorphism)은 객체 지향의 주요 개념 중 하나로,
프로그램 언어의 각 요소들이 다양한 자료형에 속하는 것이 허가되는 성질
-> 하나의 타입에 여러 객체를 대입할 수 있는 성질입니다
Java에서의 다형성을 나타내는 개념에는
오버라이딩, 오버로딩, 상속받는 객체의 참조변수 형변환 등이 있습니다
그리고 다형성을 이해하기 위해서는 아래의 두가지 개념에 대해 알아보겠습니다.
- 다형성 참조
- 메소드 오버라이딩
다형적 참조
package poly.basic;
//부모 객체
public class Parent {
public void parentMethod() {
System.out.println("Parent.parentMethod");
}
}
package poly.basic;
//부모객체를 상속받는 자식 객체
public class Child extends Parent {
public void childMethod() {
System.out.println("Child.childMethod");
}
}
위와같은 클래스들이 있다고 가정할 때 아래의 변수에 객체를 대입하는 상황들을 먼저 보면
1. 부모 변수가 부모 인스턴스 참조
Parent parent = new Parent();
2. 자식 변수가 자식 인스턴스 참조
Child child = new Child();
3. 부모 변수가 자식 인스턴스 참조(다형적 참조)
Parent poly = new Child();
위와 같이 3가지 참조가 가능합니다
위는 3번째 다형적 참조의 메모리 구조입니다.
부모타입의 변수가 자식 인스턴스를 참조합니다
Child 인스턴스를 만들때에는 메모리 상에 Child와 Parent 모두 생성됩니다.
Parent poly = new Child();
--> poly.parentMethod();
따라서 위와 같은 상황에서
poly는 Parent 타입이므로 Parent 클래스부터 시작하여 메소드인 parentMethod를 찾고
호출될 수 있습니다.
한편
poly는 Parent 타입이므로 Parent 클래스부터 기능을 찾고, 상속관계에서는 자식방향으로 내려갈 수 없습니다. 따라서 Child 객체안에 있는 childMethod는 호출할 수 없습니다
-> 이럴때 캐스팅(형변환)이 필요합니다.
캐스팅(형변환)
위의 상황에서 poly를 Parent 타입이 아닌 Child 타입으로 변경한다면 Child에 있는 childMethod를 호출할 수 있습니다.
Child child = (Child) poly //Parent poly;
다음과 같이 괄호 사이에 그 타입을 지정하면 참조 대상을 특정 타입으로 변경할 수 있고
이것을 캐스팅(형변환)이라 합니다.
chlid 객체는 타입이 자식타입이므로 childMethod를 호출 할 수 있습니다.
(poly의 타입이 바뀌는 것은 아님)
캐스팅의 종류
- 업캐스팅(upcasting): 부모 타입으로 변경
- 다운캐스팅(downcasting): 자식 타입으로 변경
다운캐스팅
Child child = (Child) poly //Parent poly;
부모 타입의 poly를 자식 타입으로 변경했으니 위의 코드는 다운 캐스팅입니다.
업캐스팅
Child child = new Child();
Parent parent1 = (Parent) child;
Child 타입을 Parent 타입에 대입해야 한다. 따라서 타입을 변환하는 캐스팅이 필요합니다.
한편 다운캐스팅과 달리 부모는 자식을 담을 수 있기때문에 위와같은 업캐스팅은 생략이 가능합니다.
그렇다면 다운캐스팅만 명시적으로 적어야하는 이유는 무엇일까?
다운캐스팅과 주의점
다운캐스팅을 잘못했을 경우 런타임 오류가 발생할 수 있습니다.
package poly.basic;
//다운캐스팅을 자동으로 하지 않는 이유
public class CastingMain4 {
public static void main(String[] args) {
Parent parent1 = new Child();
Child child1 = (Child) parent1;
child1.childMethod(); //문제 없음
Parent parent2 = new Parent();
Child child2 = (Child) parent2; //런타임 오류 - ClassCastException
child2.childMethod(); //실행 불가
}
}
위의 상황에서 child2는 처음에 Parent타입으로 객체를 생성하기 때문에
메모리 상에 자식 타입은 존재하지 않습니다
따라서 (Child)를 사용하여 형변환을 하고나서 사용할 Child가 메모리에 존재하지 않고
childMethod를 호출하기도전에
다운 캐스팅을 할 때 ClassCastException라는 예외가 발생됩니다.
instanceof
다형성에서는 참조형 변수는 다양한 자식을 대상으로 참조할 수 있습니다.
따라서 참조하는 대상이 다양하므로 어떤 인스턴스를 참조하고 있는지 확인하고 싶을때
바로 instanceof 키워드를 통해 확인 할 수 있습니다.
public static void main(String[] args) {
Parent parent1 = new Parent();
System.out.println("parent1 호출");
call(parent1);
Parent parent2 = new Child();
System.out.println("parent2 호출");
call(parent2);
}
private static void call(Parent parent) {
parent.parentMethod();
if (parent instanceof Child) {
System.out.println("Child 인스턴스 맞음");
Child child = (Child) parent;
child.childMethod();
}
}
위의 코드와 같이 Parent의 타입으로 넘어온 변수를 instanceof 로 확인하여 원하는 타입으로 변경이 가능한지 확인한후 다운캐스팅을 수행할 수 있습니다.
이를 통해 다운캐스팅을 하다 메모리 상에 인스턴스가 없어 런타임에러가 발생하는 것을 막을 수 있습니다.
메서드 오버라이딩
메서드 오버라이딩에서는 오버라이딩 된 메서드가 항상 우선권을 가집니다.
따라서
Parent poly = new Child();
다음과 같이 부모 타입으로 만들어진 poly 변수가 있을때
poly는 기본적으로 부모타입에 있는 메소드를 먼저 사용하지만,
오버라이딩된 메소드가 있을때에는 무조건 자식타입에 있는 메소드를 호출하게 됩니다
위과 같은 그림으로 이해할 수 있습니다.
'JAVA' 카테고리의 다른 글
[JAVA]자바와 객체지향(1) - JAVA가 만들어진 이유와 실행환경 간단히 살펴보기 (0) | 2024.02.13 |
---|---|
[JAVA]객체 지향 프로그래밍의 5가지 원칙 (SOLID 원칙) 예시와 개념 (2) | 2024.02.05 |
[JAVA] JAVA 메모리 영역과 구조, static까지 (0) | 2024.01.18 |
[JAVA]접근 제어자 - 개념과 이해 (0) | 2024.01.18 |
[JAVA] 패키지 - 개념, 사용법 정리 (0) | 2024.01.18 |