문제

기본 유형에서 방법을 선언하는 것의 차이점은 무엇입니까? "virtual"그런 다음, 어린이 유형에서 그것을 재정의하는 것"override"단순히 사용하는 것과 반대로 키워드"new"아동 유형에서 일치하는 방법을 선언 할 때 키워드?

도움이 되었습니까?

해결책

"새로운"키워드는 무시되지 않으며 기본 클래스 방법과 관련이없는 새로운 방법을 나타냅니다.

public class Foo
{
     public bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public new bool DoSomething() { return true; }
}

public class Test
{
    public static void Main ()
    {
        Foo test = new Bar ();
        Console.WriteLine (test.DoSomething ());
    }
}

이 오버라이드를 사용하면 True가 인쇄되었을 것입니다.

(Joseph Daigle에서 가져온 기본 코드)

그래서 당신이 진정한 다형성을하고 있다면 당신은 당신을하고 있습니다 항상 무시해야합니다. "새"를 사용해야하는 유일한 곳은 메소드가 기본 클래스 버전과 관련이없는 경우입니다.

다른 팁

나는 항상 사진으로 더 쉽게 이해할 수있는 것들을 찾습니다.

다시, Joseph Daigle의 코드를 가져 와서

public class Foo
{
     public /*virtual*/ bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public /*override or new*/ bool DoSomething() { return true; }
}

그런 다음 다음과 같이 코드를 호출합니다.

Foo a = new Bar();
a.DoSomething();

참고 : 중요한 것은 우리의 대상이 실제로 Bar, 그러나 우리는입니다 변수 유형으로 저장합니다 Foo (이것은 캐스팅과 비슷합니다)

그러면 결과는 사용 여부에 따라 다음과 같습니다. virtual/override 또는 new 수업을 선언 할 때.

Virtual/Override explanation image

다음은 가상 및 비 약행 방법의 동작의 차이를 이해하기위한 몇 가지 코드입니다.

class A
{
    public void foo()
    {
        Console.WriteLine("A::foo()");
    }
    public virtual void bar()
    {
        Console.WriteLine("A::bar()");
    }
}

class B : A
{
    public new void foo()
    {
        Console.WriteLine("B::foo()");
    }
    public override void bar()
    {
        Console.WriteLine("B::bar()");
    }
}

class Program
{
    static int Main(string[] args)
    {
        B b = new B();
        A a = b;
        a.foo(); // Prints A::foo
        b.foo(); // Prints B::foo
        a.bar(); // Prints B::bar
        b.bar(); // Prints B::bar
        return 0;
    }
}

그만큼 new 키워드는 실제로 해당 특정 유형에만 존재하는 완전히 새로운 멤버를 만듭니다.

예를 들어

public class Foo
{
     public bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public new bool DoSomething() { return true; }
}

이 방법은 두 유형 모두에 존재합니다. 반사를 사용하고 유형의 멤버를 얻을 때 Bar, 당신은 실제로 2 개의 방법을 찾을 수 있습니다 DoSomething() 정확히 똑같아 보입니다. 사용하여 new 기본 클래스에서 구현을 효과적으로 숨기므로 클래스가 Bar (내 예에서) 메소드 호출 base.DoSomething() 로 이동 Bar 그리고 아닙니다 Foo.

가상 / 재정의 컴파일러는 두 가지 메소드가 관련되어 있고 어떤 상황에서는 첫 번째 (가상) 메소드를 호출한다고 생각할 때 실제로 두 번째 (재정의) 메소드를 호출하는 것이 정확하다고 말합니다. 이것은 다형성의 기초입니다.

(new SubClass() as BaseClass).VirtualFoo()

서브 클래스의 재정의 virtualfoo () 메소드를 호출합니다.

새로운 기본 클래스의 메소드와 동일한 이름을 가진 파생 클래스에 메소드를 추가하고 있지만 서로 관계가 없습니다.

(new SubClass() as BaseClass).NewBar()

Baseclass의 Newbar () 메소드를 호출하는 반면 :

(new SubClass()).NewBar()

서브 클래스의 Newbar () 메소드를 호출합니다.

기술적 인 세부 사항 외에도 Virtual/Override를 사용하면 디자인에 대한 많은 의미 정보를 전달한다고 생각합니다. 메소드 가상을 선언 할 때 클래스 구현이 자체 비 디폴트 구현을 제공 할 수 있다고 기대합니다. 마찬가지로 기본 클래스에서이를 생략하면 기본 메소드가 모든 구현 클래스에 충분해야한다는 기대를 선언합니다. 마찬가지로, 추상 선언을 사용하여 구현 클래스가 자체 구현을 제공하도록 강요 할 수 있습니다. 다시 말하지만, 이것은 프로그래머가 코드를 사용하는 방법에 대해 많은 것을 전달한다고 생각합니다. 내가 기반을 모두 작성하고 클래스를 구현하고 새로운 것을 사용하는 것을 발견했다면, 나는 부모의 가상을 가상으로 만들지 않고 내 의도를 구체적으로 선언하지 않기로 한 결정을 심각하게 다시 생각합니다.

재정의 키워드와 새로운 키워드의 차이점은 전자가 메소드를 재정의하고 나중에 메소드 숨어 있다는 것입니다.

자세한 내용은 Folllowing 링크를 확인하십시오 ...

MSDN 그리고 다른

  • new 키워드는 숨기기위한 것입니다. - 런타임에 메소드를 숨기고 있음을 의미합니다. 출력은 기반 기본 클래스 방법입니다.
  • override 재정의를 위해. - 기본 클래스를 참조하여 파생 클래스 메소드를 호출한다는 것을 의미합니다. 출력은 파생 클래스 방법을 기반으로합니다.

내 설명 버전은 사용에서 비롯됩니다 속성 차이점을 이해하는 데 도움이됩니다.

override 충분히 간단합니까? 기본 유형 재정의 부모의.

new 아마도 오해의 소지가있을 것입니다. 속성을 사용하면 이해하기가 더 쉽습니다.

public class Foo
{
    public bool GetSomething => false;
}

public class Bar : Foo
{
    public new bool GetSomething => true;
}

public static void Main(string[] args)
{
    Foo foo = new Bar();
    Console.WriteLine(foo.GetSomething);

    Bar bar = new Bar();
    Console.WriteLine(bar.GetSomething);
}

디버거를 사용하면 알 수 있습니다 Foo foo 가지다 2 GetSomething 속성은 실제로 2 가지 버전의 속성이 있으므로 Foo'모래 BarC#을 사용하고 어떤 것을 사용할 것인지 알기 위해 현재 유형의 속성을 "선택"합니다.

바의 버전을 사용하려면 재정의 또는 사용을 사용했을 것입니다. Foo foo 대신에.

Bar bar 전적으로 1, 완전히 원하는대로 새로운 행동 GetSomething.

메소드를 표시하지 않음은 다음과 같습니다.

방법을 표시합니다 virtual 수단 : 객체의 런타임 유형을 사용 하여이 방법을 바인딩하지 않고 시간 유형 (동적 바인딩).

기본 클래스 표시 virtual 방법 override 파생 클래스에서 : 이것은 객체의 런타임 유형 (동적 바인딩)을 사용하여 바인딩되는 방법입니다.

기본 클래스 표시 virtual 방법 new 파생 클래스에서 : 이것은 기본 클래스에서 동일한 이름을 가진 사람과 관련이 없으며 객체의 컴파일 타임 유형 (정적 바인딩)을 사용하여 바인딩되어야하는 새로운 방법입니다.

기본 클래스를 표시하지 않습니다 virtual 파생 클래스의 메소드는 다음을 의미합니다.이 방법은 다음과 같이 표시됩니다. new (정적 결합).

메소드 표시 abstract 수단 :이 방법은 가상이지만 신체를 선언하지는 않으며 그 클래스도 추상적입니다 (동적 바인딩).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top