✍️ virtual
- virtual의 가장 큰 특징은 선택적인 재정의(override)가 가능하는 것이다.
- virtual이 붙은 메서드와 속성, 인덱서는 재정의할 수 있지만 필수는 아니며 virtual 키워드가 포함된 클래스는 그 자체로도 완벽한 기능을 제공한다.
class Animal
{
public virtual void Speak()
{
Console.WriteLine("I'm Creature");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("I'm Dog!");
}
}
class Cat : Animal
{
}
class Program
{
static void Main(string[] args)
{
Animal animal = new Animal();
Dog dog = new Dog();
Cat cat = new Cat();
animal.Speak(); // I'm Creature
dog.Speak(); // I'm Dog!
cat.Speak(); // I'm Creature
}
}
🍊 abstract
- 클래스 내부에서 abstract를 사용하려면 클래스 정의부에 abstract 키워드를 붙여줘야 한다.
- abstract 키워드가 붙으면 그 자체로는 불완전해서 파생 클래스에서 반드시 재정의 해야 한다.
- 단, abstract 클래스 내부에 일반 메서드와 일반 멤버 변수를 정의할 수 있다
- abstract 키워드는 인스턴스화할 수 없다.
abstract class Animal
{
public string name;
public abstract void Speak();
public void Sleep()
{
Console.WriteLine("Zzzzz...");
}
}
class Dog : Animal
{
public Dog(string name)
{
this.name = name;
}
public override void Speak()
{
Console.WriteLine($"I'm {name}");
}
}
class Cat : Animal
{
// Error !
}
class Program
{
static void Main(string[] args)
{
Animal creature = new Animal(); // Error !
}
}
- 추상 클래스의 사용 목적은 파생 클래스에게 공통적인 정의를 제공함과 동시에 각각의 파생 클래스에 사용될 기능을 강제적으로 재정의함에 있다.
abstract class Animal
{
public string name;
public abstract void Speak();
public void Sleep()
{
Console.WriteLine("Zzzzz...");
}
}
class Dog : Animal
{
public Dog(string name)
{
this.name = name;
}
public override void Speak()
{
Console.WriteLine($"I'm {name}");
}
}
class Cat : Animal
{
// Error !
}
abstract class Animal
{
public string name;
public abstract void Speak();
public void Sleep()
{
Console.WriteLine("Zzzzz...");
}
}
class Dog : Animal
{
public Dog(string name)
{
this.name = name;
}
public override void Speak()
{
Console.WriteLine($"hello I'm {name} !!");
}
}
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog("Doggy");
dog.Speak(); // hello I'm Doggy !!
dog.Sleep(); // Zzzzz...
}
}
✨ interface
- interface는 가장 높은 추상성을 제공한다.
- 필드로 메서드, 프로퍼티 인덱서만 가질 수 있으며 abstract가 아닌 필드는 정의할 수 없다.
- 접근 제한자를 사용할 수 없으며 모든 필드는 public이 적용된다.
- abstract와 interface의 가장 큰 차이는 interface는 다중 상속이 가능하다.
- interface는 상속의 개념보단 기능을 확장하는 개념이다.
- 서로 관계가 없는 클래스도 동일한 interface를 구현할 수 있다.
- 서로 관계가 없는 클래스도 interface를 구현함으로써 관계가 형성되는데 이는 다형성으로 연결된다.
abstract class Animal
{
public abstract void Speak();
}
interface IWalk
{
void Walk();
}
class Dog : Animal, IWalk
{
public override void Speak()
{
Console.WriteLine("I'm Dog !!");
}
public void Walk()
{
Console.WriteLine("Dog : 네 발로 엉금 엉금");
}
}
class Human : IWalk
{
public void Walk()
{
Console.WriteLine("Human : 두 발로 뚜벅 뚜벅");
}
}
class Program
{
static void Main(string[] args)
{
Dog dog = new Dog();
dog.Speak(); // I'm Dog !!
dog.Walk(); // Dog : 네 발로 엉금 엉금
Human human = new Human();
human.Walk(); // Human : 두 발로 뚜벅 뚜벅
}
}
다형성 개념
class Program
{
static void Main(string[] args)
{
IWalk walkHuman = new Human();
IWalk walkDog = new Dog();
Test(walkHuman);
Test(walkDog);
}
static void Test(IWalk walk)
{
// ~~
}
}
'C#' 카테고리의 다른 글
[C#] Task.FromResult 이해하기 (0) | 2021.12.24 |
---|---|
[C#] C#은 모든 자료형이 객체일까? (0) | 2021.12.15 |
[C#] 객체 생성 방법과 C++와 차이점 (+ reference) (0) | 2021.09.27 |
[C#] 미로 만들기와 길 찾기 알고리즘 Part 3 : BFS 길 찾기 (1) | 2021.08.31 |
[C#] 미로 만들기와 길찾기 알고리즘 Part 2 : Player 만들기 (2) | 2021.08.30 |