🔥 메서드 오버로딩과 오버라이딩의 용어가 헷갈려서 작성하는 포스트 🔥
메서드 오버로딩 (overloading)
: 같은 이름의 메서드를 중복하여 정의하는 것
: 매개변수의 개수나 타입이 달라야 함
: 객체 지향 프로그래밍의 특징 중 하나인 "다형성"의 특징
public class Monster
{
protected int hp;
protected string name;
protected float damage;
public void SettingMonster()
{
}
public void SettingMonster(int hp)
{
}
public void SettingMonster(int hp , string name)
{
}
public void SettingMonster(int hp, string name , float damage)
{
}
}
: 함수이름은 "SettingMonster"로 같다
1. 첫 번째 메서드는 매개변수가 없다.
2. 두 번째 메서드는 int를 매개변수로 가진다.
3. 세 번째 메서드는 int, string을 매개변수로 가진다
4. 네 번째 메서드는 int, string, float를 매개변수로 가진다.
=> 메서드 오버로딩
- 생성자 오버로딩
public class Monster
{
protected int hp;
protected string name;
protected float damage;
public Monster()
{
}
public Monster(int hp)
{
}
public Monster(int hp , string name)
{
}
public Monster(int hp, string name , float damage)
{
}
}
: 생성자 또한 오버로딩 할 수 있다.
- 생성자 오버로딩 사용
public Monster()
{
Console.WriteLine("매개변수가 없는 생성자입니다.");
}
public Monster(int hp)
{
this.hp = hp;
Console.WriteLine($"하나의 매개변수를 가지는 생성자 입니다 {this.hp}");
}
public Monster(int hp, string name)
{
this.hp = hp;
this.name = name;
Console.WriteLine($"두개의 매개변수를 가지는 생성자 입니다 {this.hp} / {this.name}");
}
public Monster(int hp, string name, float damage)
{
this.hp = hp;
this.name = name;
this.damage = damage;
Console.WriteLine($"세개의 매개변수를 가지는 생성자 입니다 {this.hp} / {this.name} / {this.damage}");
}
: 출력 시 해당 메서드가 실행되었는지 확인하기 위해서 출력문을 작성하였다.
- 실행
static void Main(string[] args)
{
// 1. 매개변수가 없는 생성자
Monster monster = new Monster();
// 2. 매개변수가 한개인 생성자
Monster monster2 = new Monster(10);
// 3. 매개변수가 두개인 생성자
Monster monster3 = new Monster(10 , "SLIME");
// 4. 매개변수가 세개인 생성자
Monster monster4 = new Monster(10 , "SLIME" , 20f);
}
: 입력된 매개변수와 유형에 따라 적절한 생성자가 매칭된다.
- 출력
- 그래서 오버로딩을 왜 사용할까?
1. 메서드에 사용되는 이름을 절약할 수 있다.
2. 같은 기능을 하는 메서드를 하나의 이름으로 정의할 수 있다.
- 만약 오버로딩을 사용하지 않고 SettingMonster() 메서드를 사용해 보겠다.
public class Monster
{
protected int hp;
protected string name;
protected float damage;
public void SettingMonster_NoneParemeter()
{
}
public void SettingMonster_OneParemeter(int hp)
{
}
public void SettingMonster_TwoParemeter(int hp, string name)
{
}
public void SettingMonster_TreeParemeter(int hp, string name, float damage)
{
}
}
: 파라미터가 없는 메서드, 한 개만 있는 메서드, 두 개 있는 메서드, 세 개 있는 메서드 이름을 다 다르게 해야 한다.
: 해당 메서드는 Monster의 필드를 세팅해 주는 같은 역할을 하는데, 이름이 다 다르다.
-> 사용할 때 불편하다!
메서드 오버라이딩 (overriding)
: 상속받은 부모 클래스의 메서드를 '자식클래스'에서 재정의 하여 사용하는 것
: 자식클래스에서 오버라이딩할 메서드와 이름, 매개변수의 개수와 타입, 반환값이 같아야 함
- 함수이름만 같다면?
public class Monster
{
protected int hp;
protected string name;
protected float damage;
public void Attack()
{
Console.WriteLine("Monster의 Attack");
}
}
public class Orc : Monster
{
public void Attack()
{
Console.WriteLine("Orc의 Attack");
}
}
static void Main(string[] args)
{
Orc orc = new Orc();
orc.Attack();
}
: 부모 메서드와 이름이 같은 메서드를 작성했을 때
-출력
: Orc클래스의 Attack() 메서드에 커서를 가져다 대면
: " 상속된 Attack() 메서드를 숨깁니다 "라는 경고문구가 뜬다.
: new 키워드를 사용하라고 한다.
public class Orc : Monster
{
public new void Attack()
{
Console.WriteLine("Orc의 Attack");
}
}
: new 키워드를 사용함으로써, 상위 메서드와는 다른 새로운 메서드를 정의한다고 할 수 있다.
- virtual , override 키워드 사용하기
public class Monster
{
protected int hp;
protected string name;
protected float damage;
public virtual void Attack()
{
Console.WriteLine("Monster의 Attack");
}
}
public class Orc : Monster
{
public override void Attack()
{
Console.WriteLine("Orc의 Attack");
}
}
static void Main(string[] args)
{
Orc orc = new Orc();
orc.Attack();
}
: 부모클래스에서 virtual, 자식클래스에서 override 키워드를 사용함으로써 "오버라이딩"을 명시적으로 표현한다.
- return 타입이 같아야 한다
: 오버라이딩 하는 메서드의 반환타입이 같아야 한다.
: 상위 Attack()은 void일 때 오버라이딩 한 메서드의 return 타입을 바꾸게 되면 오류가 난다.
- base 키워드
public class Orc : Monster
{
public void Attack()
{
base.Attack();
Console.WriteLine("Orc의 Attack");
}
}
: base 키워드를 사용하게 되면 부모의 Attack() 메서드도 실행한다.
-출력
오버로딩한 메서드를 오버라이딩
: 코드를 작성하다 보면 오버로딩과 오버라이딩을 같이 사용하는 경우가 많은 것 같다.
- Monster 클래스
public class Monster
{
protected int hp;
protected string name;
protected float damage;
public virtual void Attack()
{
}
public virtual void Attack(float stage)
{
}
public virtual void Attack(float stage, float critical)
{
}
}
: 메서드 오버로딩을 사용하여 같은 이름의 메서드를 3개 정의했다.
- Orc 클래스
public class Orc : Monster
{
public Orc(int h , string n, float d)
{
this.hp = h;
this.name = n;
this.damage = d;
}
public override void Attack()
{
Console.WriteLine($"오크의 기본 공격: {damage * 1.5f} 데미지");
}
public override void Attack(float stage)
{
Console.WriteLine($"오크의 스테이지 {stage} 기반 공격: {damage * stage * 1.5f} 데미지");
}
public override void Attack(float stage, float critical)
{
Console.WriteLine($"오크의 크리티컬 공격: {damage * stage * critical * 1.5f} 데미지");
}
}
: 메서드 오버라이딩을 통해서 하위 Orc 클래스에서 재정의했다.
: 오버로딩한 Attack() 메서드를 오버라이딩 했다!
- Main
static void Main(string[] args)
{
Orc orc = new Orc(100, "오크", 10f);
orc.Attack(); // 기본 공격
orc.Attack(2.0f); // 스테이지 기반 공격
orc.Attack(2.0f, 1.5f); // 크리티컬 공격
}
- 출력
<마치며>
가상함수에 대해 찾아보던 중, 정적바인딩과 동적바인딩에 관해서 알게 되었다.
추후 공부 후 정적/동적바인딩에 대해서도 블로그글을 작성하고 싶다.
<도움이 되었던 링크>
https://www.tcpschool.com/java/java_usingMethod_overloading
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
https://www.tcpschool.com/java/java_inheritance_overriding
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
'용어정리' 카테고리의 다른 글
[c#] Action,Func,Delegate 차이점 (0) | 2025.02.28 |
---|---|
[c#] call by value, call by reference (0) | 2025.02.27 |
[c#]static 정적 변수, 정적 메서드 , 정적 클래스 (0) | 2025.02.24 |
[용어정리]스택 프레임 (stack frame) (0) | 2025.02.13 |
[용어정리]힙메모리와 스택 메모리 (1) | 2025.02.12 |