virtual?
요약하자면,,
부모 클래스에서 virtual 키워드를 사용하여 함수를 만들면, 자식 클래스에서 이 함수를 재정의 할 수 있도록 허용
특징 :
1. virtual 이 붙은 함수는 자식 클래스에서 재정의가 가능하다.
2. 자식 클래스에서는 new 또는 override 키워드가 사용가능하다.
- override는 재정의를 하겠다는 확장의 의미이고, new 는 기본 클래스를 숨기는 의미이다.
3. 자식클래스의 함수 시그니쳐가 동일해야 재정의가 가능하다.
4. 자식클래스의 함수는 base 키워드를 사용해 부모 클래스의 함수를 호출 할 수 있다.
5. abstract 와는 달리 자식클래스에서 구현은 선택이다. (구현 안하면 부모의 함수 사용)
6. static, abstract, private,sealed 키워드와는 사용이 불가능하다.
그럼 왜 사용할까?
public class Monster
{
public virtual void hit()
{
Console.WriteLine("Monster hit");
}
}
public class Orc : Monster
{
public override void hit()
{
Console.WriteLine("Orc hit");
}
}
public class Elf : Monster
{
public new void hit()
{
Console.WriteLine("Elf hit");
}
}
public class Wolf : Monster
{
public void hit()
{
Console.WriteLine("Wolf hit");
}
}
class Program
{
static void Main(string[] args)
{
Monster monster1 = new Monster();
Orc monster2 = new Orc();
Elf monster3 = new Elf();
Wolf monster4 = new Wolf();
monster1.hit();
monster2.hit();
monster3.hit();
monster4.hit();
Monster monster5 = new Orc();
Monster monster6 = new Elf();
Monster monster7 = new Wolf();
Console.WriteLine("////////////////////");
monster5.hit();
monster6.hit();
monster7.hit();
}
}
이런식으로 하나씩 입력을 하면 원하는 값은 얻을 수 있지만
나중에 더 많아지면 코드가 길어지면 자연스럽게 코드가 무거워지고 가독성이 떨어지게 된다.
virtual 키워드로 지정된 메서드는 가상 메서드가 되는데 가상 메서드는 자식 클래스가 오버라이드 할 수 있도록 허용된다.
자식 클래스는 override 키워드를 사용해 부모 클래스의 가상메서드를 재정의 할 수 있다.
override?
기반 클래스에서 선언된 메소드를 자식 클래스에서 재정의
기반 클래스에서 오버라이딩할 메소드를 미리 virtual로 한정
파생 클래스는 virtual 메소드를 override한정자를 이용하여 재선언
즉, 가상메서드는 자식 클래스가 오버라이드 할 수 있도록 허용된 메서드
base?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Person : MonoBehaviour
{
public virtual void Work()
{
Debug.Log("일하다");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Salesman : Person {
public override void Work()
{
base.Work();
Debug.Log("나는 셀러리맨이다");
}
private void Start()
{
Work();
}
}
보기와 같이 메서드의 이름이 Work로 같이 정의되어도 자식클래서에서 같은 이름 접근가능하고
부모클래스를 호출할 수 있다.
혹시나 부모클래스의 메소드가 자식 클래스에 의해 변형이 될가 봐 테스트 해보았고,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Salesman : Person {
public override void Work()
{
base.Work();
Debug.Log("나는 셀러리맨이다");
}
private void Start()
{
Person person = new Person();
person.Work();
}
}
결론은 보기과 같이 "아니" 다.
ChatGpt에게 수업이 끝나기 전 간단한 예제를 내달라 했는데 혼자서 입력해봤던 것과 난이도가 같아서
더 어려운 예제를 풀 것이다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fish : MonoBehaviour
{
//1.물고기를 나타내는 Fish 클래스를 작성합니다.
//이 클래스에는 Swim() 메서드가 있어야 합니다. 이 메서드는 "물고기가 헤엄칩니다."라는 메시지를 출력합니다.
public virtual void Swim()
{
Debug.Log("물고기가 헤엄칩니다.");
}
private void Start()
{
Swim();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Goldfish : Fish
{
//2.Fish 클래스를 상속받는 Goldfish 클래스를 작성합니다.
//이 클래스에는 Swim() 메서드를 오버라이드하여 "금붕어가 헤엄칩니다."라는 메시지를 출력하도록 구현합니다.
public override void Swim()
{
Debug.Log("금붕어가 헤엄칩니다.");
}
}
자식클래스가 먼저 호출되고 부모클래스가 잇따라 호출되었다.
'낙서장 > C#' 카테고리의 다른 글
[C#] 메서드 오버로딩 (0) | 2024.06.02 |
---|---|
상속과 다형성 (1) | 2024.03.08 |
흐름 제어 (1) | 2024.02.26 |
데이터를 가공하는 연산자 (0) | 2024.02.25 |
데이터를 담는 변수와 상수 (0) | 2024.02.22 |