클래스 A가 클래스 B에서 상속 받고 클래스 C에서 상속 받았다고 가정 해 봅시다. 가상 메소드 void f()가 A에서 정의되었으며 B와 C에서 모두 재정의 된 것으로 가정합니다. 모든 메소드에서 Bf()를 호출합니다. in A는 단순히 base.f()를 사용하여 수행 할 수 있습니다. C.f()를 A의 메소드에서 호출하는 것은 어떻습니까?C# 기본 자료에서 메소드를 호출하는 방법은 무엇입니까?
답변
일반적으로 클래스를 재정의하면 인터페이스 및 원하는 일부 동작을 제공한다는 것을 인정하게됩니다. A는 수퍼 클래스에 의해 명시 적으로 노출되지 않는 한 슈퍼 수퍼 클래스임을 알지 못합니다. B를 서브 클래스화할 때 C가 구현되는 방법을 알 필요가 없기 때문에 이것은 실제로 바람직합니다. C가 관련되어 있다는 것을 알지 못합니다.
b의 f()가 base.f()를 호출하면 a의 base.f()가 자신의 base.f()를 호출하면 완료됩니다. 그렇지 않다면 자신을 수행 할 수있는 유일한 방법은 리플렉션을 기반으로하는 침입 방법입니다. 자신이이 작업을 수행해야하는 경우 설계에 오류가있는 것입니다 (Demeter의 법칙을 위반 함).
감사합니다. 내 자신의 디자인이 아닙니다. 이 경우 클래스 B와 C는 Telerik 구성 요소입니다. B 클래스는 필자가 필요로했던 대부분의 기능을 제공하지만 C에서 메소드를 호출 할 때 필요한 기능 중 일부를 구현하기 위해 사용되었다. – sisis
이 시도 :
C c = this;
c.f();
이 인쇄 "C"를 :
public static void Main()
{
A o = new A();
Console.WriteLine(o.f());
}
class C
{
public virtual string f()
{
return "C";
}
}
class B : C
{
public virtual string f()
{
return "B";
}
}
class A : B
{
public virtual string f()
{
C c = this;
return c.f();
}
}
이는 반사를 통해 수행 할 수 있습니다. 현재 클래스의 Type을 가져 와서 상위 유형을 가져온 다음 상위 유형의 상위 유형을 가져옵니다.
언어에서 직접 지원되지 않는 이유는 상속의 추상화 모델을 손상시키기 때문입니다. 그것은 기존의 객체 지향 설계와 실제로 호환되지 않습니다.
리플렉션을 통해 또는 IL 코드를 생성 할 수 있습니다. 그것 이외에, 당신은 할 수없고, 정말로 그렇게해서는 안됩니다. 이것은 좋은 디자인처럼 들리지 않습니다.
OOP에서 메서드를 재정의 할 때 기본적으로 "이 형식의 경우이 메서드는 이전 메서드를 바꿉니다"라는 말을 필요에 따라 (일반적으로는 가능) 대체 된 재정의 된) 메소드를 호출합니다.
그러나 반성이나 일리노이 속임수에 의지하지 않는 한 직접 레벨을 건너 뛸 수는 없으며, 그럴만한 이유가 있습니다. 중간 클래스가이 메서드 호출을 위해 중간 클래스를 건너 뛸 수 있도록 허용해야한다면 사용할 수있는 특별한 메서드를 추가해야합니다. 이것이 "어렵다"하는 이유는 일반적으로 그렇게해서는 안되며 항상 다음 단계로 올라가서 통제 할 수 있어야하기 때문입니다.
C의 메서드에서 A.f()를 호출한다고 가정합니까?
짧은 답변 :
protected void BaseF()
{
base.f();
}
을 그리고 그때부터 그 메소드를 호출하면 B를 제어 할 수 있다면 당신은
그러나, 당신은 명시 적으로 기본 전화 B로 방법을 추가 할 수 없습니다 C
C의 함수에서 base.f(), 을 호출 할 수 있습니다.이 작업은입니다. 만약 당신이 실제로 부르는 B.f()가 base.f()를 호출하기를 원한다면, 그것은 당신이 원하는 것을 얻는다. 그러나 그것이 일어 났는지 아닌지에 대해서는 B의 구현에 달려있다.
당신은 다음과 같이 A와 C 및 호출 F()를 주조 시도 할 수 있습니다 :
public class C : B {
public override f() {
((A) this).f();
}
}
하지만,이 문제는 C는 F()가 선언 아무 생각이없는 것입니다 - 그것은 알고있는 모든이다 재정의 될 수있는 B에서의 구현이 있다는 것을 C가 알지 못한다. 위 예제는 실제로 코드의 나쁜 부분이며, A가 f()를 구현하지 않으면 컴파일 타임 오류가 발생합니다.
override
이 아닌 사용은 일 수 있습니다 (이 기능은 사용할 수는 있지만 new
을 사용하려면 가상 일 필요가 없습니다).
그래도 다른 문제가 발생할 수 있습니다. MyClass
을 MyBaseClass
으로 업 캐스트하면 MyBaseClass
버전의 기능이 사용됩니다.
private void Form1_Load(object sender, EventArgs e)
{
var mc = new MyClass();
mc.Foo();
((MyBaseClass) mc).Foo();
}
public class MyBaseClass
{
public virtual void Foo()
{
Console.WriteLine("Calling from MyBaseClass");
}
}
public class MyClass : MyBaseClass
{
new public void Foo()
{
Console.WriteLine("Calling from MyClass");
}
}
당신이 얻을 출력은 다음과 같습니다
Calling from MyClass
Calling from MyBaseClass
으로는 이전에 주석하고, 가상이 방법에서 재정의 될 수 없다, 당신은 '새로운'대신 '무시'로 사용해야합니다. 그것은 매우 혼란 얻고 예상되는 상속 동작의 대부분을 파괴하고, '새로운'키워드가 새로운 인터페이스를 강제하기위한 것입니다으로, 이것은 좋은 방법이 아닙니다
:
여기에 클래스 이름을 사용하는 예입니다 항목을 재정의하려는 클래스에 추가하십시오.
건배, 제이슨
class Program
{
static void Main(string[] args)
{
C c = new C();
A a = new A();
a.DoThis();
Console.ReadKey();
}
}
public class C
{
public virtual void DoThis() {
Console.WriteLine("In C"); }
}
public class B : C
{
public new void DoThis()
{
Console.WriteLine("In B");
}
}
public class A : B
{
public new void DoThis()
{
Console.WriteLine("In A..");
((C) this).DoThis();
}
}
이것은 설계 문제처럼 보인다.
옵션의 몇 당신은 :
- 는 A.DoThis()의 대부분을 가지고, 그리고 (보호는?) 적절한 무엇인가라는 또 다른 방법으로 이동 (DoThat()?). 이제 직접 호출 할 수 있습니다.
- 개체를 분할하고 상속보다는 구성을 사용하여 동작을 다시 사용하는 것이 좋습니다.
- 1. ApplicationController에서 메소드를 호출하는 방법은 무엇입니까?
- 2. 런타임에 메소드를 호출하는 다양한 방법은 무엇입니까?
- 3. 체인에서 서로를 호출하는 메소드를 피하는 방법은 무엇입니까?
- 4. 동적 유형의 확장 메소드를 호출하는 방법은 무엇입니까?
- 5. classlibrary에서 Project의 모든 메소드를 호출하는 방법은 무엇입니까?
- 6. 메소드 내부에서 메소드를 호출하는 방법은 무엇입니까?
- 7. fbDialogNotLogin 내에서 메소드를 호출하는 방법은 무엇입니까?
- 8. onSubmit 이벤트에서 메소드를 호출하는 방법은 무엇입니까?
- 9. 이전 페이지에서 메소드를 호출하는 방법은 무엇입니까?
- 10. 이 webservice 메소드를 호출하는 방법은 무엇입니까?
- 11. Cocoa/WebKit 앱의 Javascript에서 Objective-C 메소드를 호출하는 방법은 무엇입니까?
- 12. C++에서 Java 메소드를 호출하는 가장 쉬운 방법은 무엇입니까?
- 13. 각 루프마다 (Thread C# 사용) 메소드를 만들고 호출하는 방법은 무엇입니까?
- 14. 오버라이드 된 객체의 기본 클래스 메소드를 호출하는 방법이 있습니까? (C++)
- 15. C# 메소드를 내보내는 방법은 무엇입니까?
- 16. Javascript에서 Java 메소드를 호출하는 옵션
- 17. Eclipse : 프로젝트의 기본 메소드를 설정하는 방법은 무엇입니까?
- 18. Netbeans에서 Ruby 기본 메소드를 디버깅하는 방법은 무엇입니까?
- 19. C#에서이 Delphi 함수를 호출하는 방법은 무엇입니까?
- 20. 메소드를 호출하기 전에 메소드를 수동으로 호출하는 방법
- 21. heightForRowAtIndexPath의 기본 구현을 호출하는 방법은 무엇입니까?
- 22. 루비에서 클래스 메소드를 호출하는 더 나은 방법은?
- 23. 디버거에서 호출하는 메소드를 볼 수없는 이유는 무엇입니까?
- 24. poi 메소드를 사용하여 Excel에서 차트를 호출하는 방법은 무엇입니까?
- 25. iOS 4 앱이 백그라운드에서 반복적으로 메소드를 호출하는 방법은 무엇입니까?
- 26. 부모보기 컨트롤러의 버튼을 누르면보기 컨트롤러의 메소드를 호출하는 방법은 무엇입니까?
- 27. 어머니의 인스턴스 메소드를 호출하는 객체를 초기화하는 올바른 방법은 무엇입니까?
- 28. inspect.getmembers를 통해 발견 된 메소드를 호출하는 방법은 무엇입니까?
- 29. 카테고리가있는 메소드를 덮어 쓸 때 원래 구현을 호출하는 방법은 무엇입니까?
- 30. 조치 후 또는 뷰에서 javascript 메소드를 호출하는 방법은 무엇입니까?
가능한 중복 : http://stackoverflow.com/questions/1006530/c-how-to-call-a-second-level-base-class-method-like-base-base-gethashcode – itowlson
나는 가정 Af()를 C의 메서드에서 호출하는 것을 의미합니까? –
저는 정말로 추측하고 있습니다 만, C에게'this'을 던질 수는 없습니까? ((C) this) .f(); –