티스토리 뷰
▶다형성(Polymorphism) - 오버로딩&오버라이딩
오늘은 자바에서의 다형성에 대해 알아보려고 합니다 :)
🔎 다형성(Polymorphism) ?
다형성이란 프로그램 언어 각 요소들(상수, 변수, 식, 객체, 메소드 등)이
다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다.
- 위키피디아
또는 여러 형태를 받아들일 수 있는 성질, 상황에 따라 의미를 다르게 부여할 수 있는 특성 등으로 정의를 하기도 합니다.
자바에서 다형성을 나타내는 것으로는, 오버로딩과 오버라이딩이 있습니다.
📌 오버로딩(Overloading) : 메소드의 이름을 같게 근데 매개변수는 다르게
오버로딩은 같은 이름의 메소드 여러 개를 가지면서 매개 변수의 유형과 개수가 다르도록 하는 기술을 말합니다.
쉽게 말해서 클래스 내부에서 write()라는 메소드를 선언하고 또 write(String msg)
이런 식으로 매개 변수의 유형과 개수가 다르게 선언만 한다면 같은 이름의 메소드를 사용해도 좋다는 말과 같은데요.
자바는 메소드의 이름이 같더라도 매개변수의 개수나 타입으로도 주소값을 구분하기 때문입니다.
오버로딩이 진원되지 않으면 매개변수의 타입이나 개수가 다른 메소드를 여러 개 만들어줘야 하는 단점이 있지만, 자바에서는 메소드의 이름을 같고 매개변수는 다른 메소드들을 만들어 다형성을 지원합니다.
❓ 언제 사용할까
클래스 내부에서 생성자를 선언하는 부분이 있었습니다.
필요에 따라 인스턴스 생성 시 생성자 내부에 다른 값을 부여해야 할 때 사용됩니다.
class A {
int data;
A(String name) {
System.out.println(name);
}
A(int data) {
this.data = data;
System.out.println(data);
}
}
public class ClassTest {
public static void main(String[] args) {
A a = new A(10);
A b = new A("홍길동");
}
}
동일한 이름의 생성자를 사용했지만, 매개변수의 타입으로 잘 구분이 된 것을 확인할 수 있었습니다.
📌 오버라이딩(Overriding) : 부모 클래스의 메소드를 상속받은 자식 클래스에서 재정의
오버라이딩은 부모 클래스가 가지고 있는 메소드를 자식 클래스가 재정의해서 사용하는 것인데요.
즉 상속받은 클래스의 메소드가 자식 클래스에서 충분한 기능을 제공하지 않거나, 부족할 때 부모 클래스로부터 상속받은 메소드를 재정의 하는 것 입니다.
따라서 부모 필드의 메소드와 동일한 이름으로 선언을 하긴 합니다.
부모 필드가 메모리에 먼저 할당되고 a라는 메소드가 올라간다고 하면,
자식 필드가 메모리에 할당되면서 재정의한 a메소드가 새롭게 만들어지는 것이 아니라
기존에 할당된 a메소드 저장공간에 새롭게 재정의한 자식 필드의 소스코드 주소가 들어가는 것입니다.
따라서 자식 객체로 a메소드에 접근하면 자식 필드에서 재정의한 소스코드의 내용이 읽히게 됩니다.
→ 재정의한 소스코드는 인스턴스 내부에서 관리
❓ 오버라이딩 할 때 주의사항
자식 클래스에서 오버라이딩하는 메소드는 부모 클래스의 메소드와
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 리턴 타입이 같아야 한다.
❓ 오버라이딩 예시
상속 받은 자식 클래스에서 부모 클래스에 있는 함수 이름과 매개 변수를 동일하게 작성하고 메소드 안을 채워주면 되는데요.
이때 부모의 내용이 부족하여 원래 있던 내용에 자식 클래스에서의 내용을 추가하고 싶다면
부모 클래스를 가리키고 있는 super 키워드 + 재정의 하고 있는 메소드 이름을 통해 오버라이딩 되기 전의 메소드를 가져오고 바로 아래에서 내용을 추가해 줄 수도 있습니다.
만약 부모의 내용이 모두 필요없고 처음부터 자식 클래스에서 재정의 하고 싶은 거라면
super 키워드 없이 바로 소스코드를 작성하면 됩니다.
class Human {
public Human() {;}
publick Human(String name) {
super();
this.name = name();
}
void eat() {
System.out.println("먹기");
}
void sleep() {
System.out.println("자기");
}
void walk() {
System.out.println("두 발로 걷기");
}
}
class Monkey extends Human {
@Override
void eat() {
// 부모 꺼를 무시하고 자식에서 다시 재정의
System.out.println("바나나를 주식으로 먹기");
}
@Override
void walk() {
// 부모 클래스에 있는 기능을 살리고 시파면
// super. 을 사용
super.walk(); // 어노테이션 되기 전의 walk();
System.out.println("네 발로 걷기");
}
}
메인 메소드에서 이를 실행해 봅시다.
public class Overriding {
public static void main(String[] args) {
Human human = new Human();
Monkey monkey = new Monkey();
human.walk(); // 두 발로 걷기
monkey.walk(); // 두 발로 걷기 \n 네 발로 걷기
monkey.eat(); // 바나나를 주식으로 먹기
}
}
그리고 또 알 수 있는 점은 재정의를 한다고 하더라도 자식 클래스 내부에서 재정의를 한 것이기 떄문에
부모 클래스의 메소드가 변하지는 않습니다.
'백엔드 > Java' 카테고리의 다른 글
[Java] 자바에서의 접근 권한 제어자(Access Modifier) (2) | 2023.02.02 |
---|---|
[Java] 상속(Inheritance) 개념 정리 (2) | 2023.02.01 |
[Java] 자바 static의 의미와 사용법 (0) | 2023.01.31 |
[Java] 클래스(Class) 기본개념 (0) | 2023.01.29 |
[Java] 자바에서의 형변환(Casting) (0) | 2023.01.19 |
- Total
- Today
- Yesterday
- 데이터분석
- next.js
- 자바
- 디프만
- testing
- 딥러닝
- HTML
- JSP
- 인프런
- TypeScript
- 타입스크립트
- 파이썬
- frontend
- react-query
- 프론트엔드 공부
- 프로젝트 회고
- 프론트엔드
- jest
- 스타일 컴포넌트 styled-components
- Python
- 자바스크립트
- 프론트엔드 기초
- styled-components
- CSS
- 리액트 훅
- 자바스크립트 기초
- 리액트
- 머신러닝
- react
- rtl
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |