본문 바로가기
공부

[Unity] 기술 면접 대비 1 - virtual, abstract, interface

by 잰쟁 2024. 4. 3.
728x90

1. virtual, abstract, interface에 대해 설명

 

● virtual (가상)

: virtual 키워드는 메서드,속성, 인덱서 또는 이벤트 선언을 한정하는데 사용.

: 자식 클래스에서 선택적으로 재정의 가능. (재정의가 필수 아님)

: 자식 클래스에서는 new 또는 override 키워드가 사용가능.

  (override - 재정의 , new - 기본 클래스 숨김)

: static, abstract, private, override 키워드와는 사용이 불가능.

: 인스턴스화 가능.

 

[예제]

//부모 클래스
public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("I'm Animal");
    }
}

//자식 클래스 1
public class Dog : Animal
{
   //override 함
    public override void Speak()
    {
        Console.WriteLine("I'm Dog");
    }
}

//자식 클래스 2
public class Cat : Animal
{
   //override 하지 않음
    public void Speak()
    {
        Console.WriteLine("I'm Cat");
    }
}

 

 

[출력 예제]

internal class Program
{
    static void Main(string[] args)
    {
    
    	//...각 클래스에 자기자신을 인스턴스로 담기
        Animal animal1 = new Animal();
        Dog animal2 = new Dog();
        Cat animal3 = new Cat();

        animal1.Speak();
        animal2.Speak();
        animal3.Speak();

        Console.WriteLine("---------------------");

        //...Animal이란 변수에 각 자식 클래스의 인스턴스를 생성해 담기
        Animal animal4 = new Animal();
        Animal animal5 = new Dog();
        Animal animal6 = new Cat();

        animal4.Speak();
        animal5.Speak();
        animal6.Speak();
    }
}

 

 

[출력 결과]

 

==> animal1~3 : 자기 자신을 인스턴스로 담으면 virtual의 의미가 사라짐. (재정의 할 필요가 없음)

==> animal4~5 : override를 한 Dog만 제대로 재정의되어 출력. Cat은 부모 클래스의 Speak를 출력.

 


 

abstract (추상)

: abstract 클래스 내에서만 구현 가능.

  (abstract 클래스는 추상 및 일반 메서드 모두 가질 수 있음)

: 클래스, 메서드, 프로퍼티, 인덱서, 이벤트와 함께 사용 가능.

: 여러개의 파생 클래스에서 공유할 기본 클래스의 공통적인 정의를 제공하는 것이 목적.

  --> abstract가 사용되는 곳에는 누락되거나 불완전한 구현 有

       ==> override를 사용하여 파생(자식) 클래스 누락된 부분을 구현해줘야 함.

: 인스턴스화 불가능.

 

[예제]

//..추상 클래스
public abstract class Animal
{
    public int weight;

    public void Setup(int _weight)       //..일반 메서드
    {
        weight = _weight;
    }

    public abstract void Speak();       //..추상 메서드
}

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Dog: {0}kg.",weight);
    }
}

public class Cat : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Cat: {0}kg.",weight);
    }
}

 

[출력 예제]

static void Main(string[] args)
{
    //...각 클래스에 자기자신을 인스턴스로 담기
    Dog animal1 = new Dog();
    Cat animal2 = new Cat();

    animal1.Setup(2);
    animal1.Speak();
    animal2.Setup(3);
    animal2.Speak();

    Console.WriteLine("---------------------");
    
    //...Animal이란 변수에 각 자식 클래스의 인스턴스를 생성해 담기
    Animal animal3 = new Dog();
    Animal animal4 = new Cat();

    animal3.Setup(4);
    animal3.Speak();
    animal4.Setup(5);
    animal4.Speak();
}

 

[출력 결과]

 

 

==> 두 가지 경우 동일하게 abstract 클래스에서 만든 Setup 함수와 상속받은 Speak 함수가 잘 출력 됨.


 

※ abstract(추상) 클래스의 경우 자기자신을 인스턴스로 삼을 수 없음!!

 

 


 

interface (인터페이스)

: 인터페이스를 구현하는 클래스는 모든 메서드를 정의해야 함. (클래스의 기본 동작 제공 X)

: 접근 제한자를 사용할 수 없으며 모든 필드는 public이 적용.

: 다중 상속 가능.

: 정의만 있고 구현 내역이 없음.

: 자신을 상속받는 클래스에게 오버라이딩을 강제함.

※ C#에서는 인터페이스명 첫 글자에 'I'를 붙이는 것이 암묵적인 룰..!

 

[예제]

//..인터페이스
public interface IAnimal
{
    void Speak();
}

public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("멍멍!");
    }
}

public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("야옹~");
    }
}

 

[출력 예제]

static void Main(string[] args)
{
    //...각 클래스에 자기자신을 인스턴스로 담기
    Dog animal1 = new Dog();
    Cat animal2 = new Cat();

    animal1.Speak();
    animal2.Speak();

    Console.WriteLine("---------------------");
    //...IAnimal이란 변수에 각 자식 클래스의 인스턴스를 생성해 담기
    IAnimal animal3 = new Dog();
    IAnimal animal4 = new Cat();

    animal3.Speak();
    animal4.Speak();

}

 

[출력 결과]

 

==> 두 가지 경우 동일하게  Speak 함수가 잘 출력 됨.


 

※ interface 의 경우 자기자신을 인스턴스로 삼을 수 없음!!

 

 

 

▶ 참고 사이트

https://zprooo915.tistory.com

https://dev-sm.tistory.com

https://hongjinhyeon.tistory.com

https://ivorycirrus.github.io/TIL/csharp-method-override/