using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Step37_2
{
internal class Program
{
static void Main(string[] args)
{
Marine marine = new Marine();
marine.name = "마린1";
Firebat firebat = new Firebat();
firebat.name = "파이어뱃1";
marine.Attack();
firebat.Attack();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Step37_2
{
class TerranUnit
{
public string name;
//생성자
public TerranUnit()
{
Console.WriteLine("TerranUnit 클래스의 생성자");
}
public virtual void Attack()
{
Console.WriteLine("{0}이(가) 공격 합니다", this.name);
}
protected void Reload(string weaponName) //자식만 접근 가능
{
Console.WriteLine("{0}이(가) {1}을 장전을 합니다", this.name, weaponName); ;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Step37_2
{
internal class Marine : TerranUnit
{
//생성자
public Marine()
{
Console.WriteLine("Marine클래스의 생성자");
}
public override void Attack()
{
base.Reload("총");
Console.WriteLine("{0}이(가) 총으로 공격합니다.", this.name);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Step37_2
{
internal class Firebat : TerranUnit
{
public Firebat()
{
Console.WriteLine("Firebat클래스의 생성자");
}
public override void Attack()
{
base.Reload("화염방사기");
Console.WriteLine("{0}이(가) 화염방사기로 공격합니다.", this.name);
}
}
}
부모 클래스에서 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("금붕어가 헤엄칩니다.");
}
}