[c#] C #에서 섀도 잉과 재정의의 차이점은 무엇입니까?

C #에서 섀도 잉 과 메서드 재정의 의 차이점은 무엇입니까 ?



답변

잘 상속 …

이 클래스가 있다고 가정하십시오.

class A {
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A{
   public new int Foo() { return 1;}     //shadow
   public override int Bar() {return 1;} //override
}

그러면 이것을 부를 때 :

A clA = new A();
B clB = new B();

Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1

//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1

기본 클래스가 있고 상속 된 클래스 대신 모든 코드에서 기본 클래스를 사용하고 그림자를 사용한다고 가정하면 개체의 실제 유형의 상속 트리를 따르는 대신 기본 클래스가 반환하는 값을 반환합니다.

여기에서 코드 실행

이해가 되길 바랍니다 🙂


답변

섀도 잉은 실제로 우리가 C #에 숨어 있다고 부르는 VB 용어입니다.

종종 숨기기 (VB의 그림자) 및 재정의는 Stormenet의 답변과 같이 표시됩니다 .

가상 메서드는 하위 클래스에 의해 재정의되는 것으로 표시되며 슈퍼 클래스 유형 또는 슈퍼 클래스의 내부 코드에서도 해당 메서드를 호출하면 하위 클래스에서 대체 구현을 호출합니다.

그런 다음 new하위 클래스에서 동일한 서명을 가진 메서드를 정의 할 때 키워드 를 사용하여 숨겨진 구체적인 메서드 (가상 또는 추상으로 표시되지 않은 메서드)가 표시됩니다 . 이 경우 메서드가 수퍼 클래스 유형에서 호출 될 때 원래 구현이 사용되며 새 구현은 하위 클래스에서만 사용할 수 있습니다.

그러나 종종 놓치는 것은 가상 방법을 숨길 수도 있다는 것입니다.

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new void DoStuff() {  //new implementation }
}

B b = new B();
A a = b;

b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.

위의 예에서 DoStuff는 구체적이되어 재정의 할 수 없습니다. 그러나 virtualnew키워드를 함께 사용할 수도 있습니다 .

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new virtual void DoStuff() {  //new implementation }
}

class C : B
{
    public override void DoStuff() { //replacement implementation }
}

C c = new C();
B b = c;
A a = b;

c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.

관련된 모든 메서드가 가상 임에도 불구하고 newB 에서를 사용 하면 A 구현이 숨겨 지므로 C에 대한 재정의는 A의 가상 메서드에 영향을주지 않습니다 .

편집 : 위의 내용이 위험하거나 적어도 특별히 유용하지 않을 수 있다는이 답변에 대한 의견에서 언급되었습니다. 그렇다고해도 위험 할 수 있으며 유용하다면 밖에있을 것입니다.

특히 접근성 수정자를 변경하면 모든 종류의 문제가 발생할 수 있습니다. 예 :-

public class Foo
{
    internal Foo() { }
    protected virtual string Thing() { return "foo"; }
}

public class Bar : Foo
{
 internal new string Thing() { return "bar"; }
}

의 외부 상속인에 Bar, Foo것 ()의의 구현은 accesible 및 재정의 남아있다. .NET 유형 규칙에 따라 합법적이고 설명 가능한 모든 것은 결코 직관적이지 않습니다.

나는 자유롭게 사용할 수있는 기술의 제안으로 사물이 작동하지 않는 방식에 대한 이해를 심화시키기 위해이 답변을 게시했습니다.


답변

가장 큰 차이점은 섀도 잉을 사용하면 본질적으로 이름을 재사용하고 수퍼 클래스 사용을 무시한다는 것입니다. 재정의를 통해 구현은 변경되지만 접근성 및 서명 (예 : 매개 변수 유형 및 반환)은 변경되지 않습니다. http://www.geekinterview.com/question_details/19331을 참조 하십시오 .


답변

섀도 잉은 VB.NET 개념입니다. C #에서는 섀도 잉을 숨기기라고합니다. 파생 클래스 메서드를 숨 깁니다. ‘new’키워드를 사용하여 수행됩니다.

Override 키워드는 파생 클래스에서 기본 클래스 메서드 ( ‘Virtual’로 표시됨)의 완전히 새로운 구현을 제공하는 데 사용됩니다.


답변

기본적으로 아래와 같은 것이 있으면

Class A
{
}

Class B:A
{
}

A a = new B();

객체 ‘a’에 대해 호출하는 모든 메서드는 ‘a’유형으로 만들어집니다 (여기서 유형은 ‘A’입니다).하지만 클래스 A에 이미있는 클래스 B에서 동일한 메서드를 구현하면 컴파일러는 “New”키워드를 사용하도록 경고합니다. “New”를 사용하면 경고가 사라집니다. 이것 이외에는 “New”를 사용하는 것과 상속 된 클래스에서 사용하지 않는 것에는 차이가 없습니다.

어떤 상황에서는 객체 유형에 대한 메서드를 호출하는 대신 특정 인스턴스가 해당 순간에 보유하는 참조 클래스의 메서드를 호출해야 할 수 있습니다. 위의 경우 보유하는 참조는 ‘B’이지만 유형은 ‘A’입니다. 따라서 메서드 호출이 ‘B’에서 발생하도록하려면 Virtual을 사용하고이를 재정의합니다.

도움이 되었기를 바랍니다…

Daniel Sandeep.


답변

클래스의 내용을 변경할 수없는 경우 (예 :)가 A있지만 일부 메서드를 사용하려는 경우 이름이 공통된 메서드가있는 경우new 있으면 키워드로 .

요점은 참조와 객체가 동일한 유형이어야한다는 점을 사용하는 것입니다.

class A
{
    public void Test()
    {
        Console.WriteLine("base");
    }
}

class B : A
{
    public new void Test()
    {
        Console.WriteLine("sub");
    }

    public static void Main(string[] args)
    {
        A a = new A();
        B aa = new B();
        a.Test();
        aa.Test();
    }
}


답변