2012-05-17 2 views
2

내가이 있다고 가정하자 :상속 된 과부하를 호출하면 어떤 메소드가 호출됩니까?

내가 new SuperiorFoo().Bar(new C()) 이유를 실행하면 호출됩니다 과부하
class A { } 
class B : A { } 
class C : B { } 

class Foo 
{ 
    public void Bar(A target) { /* Some code. */ } 
} 

class AdvancedFoo : Foo 
{ 
    public void Bar(B target) 
    { 
     base.Bar(target); 
     // Some code. 
    } 
} 

sealed class SuperiorFoo : AdvancedFoo 
{ 
    public void Bar(C target) 
    { 
     base.Bar(target); 
     // Some code. 
    } 
} 

? 계단식으로 호출 될 것 같아요.하지만 그 동작이 보장되는지, 이유가 무엇인지 파악할 수 없습니다.

은 그래서, 모두 FooSuperiorFoo에 대한 AdvancedFoo, 그래서 함께 base. 작품은 어느라고 왜됩니다 업데이트?

+1

막대가 고정되어 있지 않으므로 SuperiorFoo.Bar를 호출 할 수 없습니다. –

+0

'막대'가 가상 재 지정이 아니기 때문에 단순히 막대에 방법을 숨기고 있습니다. – dasblinkenlight

+0

@SachinKainth 보시다시피, "새로운 SuperiorFoo.Bar (..)"가 있습니다. @dasblinkenlight 아니요. 다른 형식화 ​​된 인수를 받아들이므로 오버로드됩니다. – AgentFire

답변

6

이제 내 질문에 대한 답변이 수정되었습니다.

빠른 추적

는 다음 보여줍니다)

  1. SuperiorFoo.Bar를 (해당 기본 메서드를 호출

    Entering SuperiorFoo.Bar() 
    Entering AdvancedFoo.Bar() 
    Entering Foo.Bar() 
    Leaving Foo.Bar() 
    Leaving AdvancedFoo.Bar() 
    Leaving SuperiorFoo.Bar() 
    

    는 무슨 일을 통해 이야기 할 수 있습니다. SF.Bar()는 AdvancedFoo에서 을 상속하므로 기본 메서드는 AdvancedFoo.Bar()입니다.

  2. AdvancedFoo.Bar()는 기본 (즉, 부터 Foo()를 상속 받음)을 호출합니다. 당신이 잠재적으로 중간 클래스의 동작을 할 수 있기 때문에

프로세스 흐름은 Foo.Bar에 SF.Bar()()에서 이동하지 않습니다.

이 메서드를 AdvancedFoo에서 제거하면 탐색이 약간 다릅니다. SuperFoo.Bar()는 여전히 기본 메서드를 호출하지만 AdvancedFoo가 Foo.Bar() 메서드를 더 이상 숨기지 않으므로 논리는 Foo.Bar() 메서드로 이동합니다.

+0

젠장 .. 내가 파티에 늦었 어 +1 – V4Vendetta

+1

"Stackoverflow"on –

+0

죄송합니다, "기본"을 추가하는 것을 잊었습니다. 피 호출자에게. 결정된. – AgentFire

0

StackOverflowException으로 충돌 할 때까지 SuperiorFoo 내부의 Bar() 메서드를 계속 호출합니다. 당신이 바() (그래서 AdvancedFoo 내부의 방법)의 기본 메소드를 호출 할 경우, 당신은이를 사용해야합니다 :

base.Bar(target); 

편집 :

원래 게시물에 코드처럼

이 보이는 변경되었습니다. 이제는 SuperiorFoo의 'Bar'가 Foo의 'Bar'를 호출 할 AdvancedFoo의 'Bar'를 호출 한 후 코드가 종료됩니다.

+0

그래, 내가 한거야. – AgentFire

+0

코드를 변경 했습니까? ;) VS10에 붙여 넣었지만 코드에는 '기본'이 없습니다. –

+0

예. 변경했습니다. – AgentFire

0

KingCronus는 기본적으로 무한 루프가 있음을 지적했습니다. 서명이 적절한 방법으로 개체의 정확한 유형에 따라 첫 경기에 노력할 것, 그에서 내려 가야한다 ...

class Foo 
{ 
    public void Bar(A target) { /* Some code. */ } 
} 

class AdvancedFoo : Foo 
{ 
    public void Bar(B target) 
    { 
     base.Bar((A)target); 
     // continue with any other "B" based stuff 
    } 
} 

sealed class SuperiorFoo : AdvancedFoo 
{ 
    public void Bar(C target) 
    { 
     base.Bar((B)target); 
     // continue with any other "C" based stuff 
    } 
} 

을 '기타'타입으로 타입 캐스팅하여 (예 : B 또는 A) ...

+0

무한 루프는 복사/붙여 넣기시 OP 부분에서 오류가 발생했기 때문입니다. 이후 내 대답을 수정했습니다 :-) – KingCronus