2013-10-04 5 views
2

Рассмотрим следующее -Использование абстрактных переопределение и вызова базового класса

void Main() 
{ 
    var c = new C(); 
    c.Print(); 
} 

public abstract class A 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("I'm in A!"); 
    } 
} 

public abstract class B : A 
{ 
    public abstract override void Print(); 
} 

public class C : B 
{ 
    public override void Print() 
    { 
     Console.WriteLine("I'm in C!"); 

     base.Print(); 
    } 
} 

Это, конечно, не будет компилироваться, так как он думает, что я пытаюсь вызвать метод печати B, который является абстрактным. То, что я хочу сделать, это метод печати C, а затем вызвать метод печати базы, который будет «привязываться» к методу печати A. Я хотел бы, чтобы это было -

I'm in C! 
I'm in A! 

Делает это даже возможно? Что я делаю не так?

EDIT: Я хотел бы добавить, что основная мысль о коде выше заключается в том, что я пытаюсь заставить любого, кто расширяет B, реализовать свой собственный метод печати.

+0

Используйте ее общественности с { общественности C(): базовый() {} Печать(); } – user1956570

+0

Кажется, что иерархия хрупкая и ее нужно перепроектировать. Вам нужно подумать, подходит ли наследование. – ChaosPandion

+0

Почему вы пытаетесь заставить разработчика C копировать и вставлять код из A в C? – jmoreno

ответ

2

Ну, вы могли бы сделать

public abstract class A 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("I'm in A!"); 
    } 
} 

public abstract class B : A 
{ 
    public override void Print() 
    { 
     base.Print(); 
    } 
} 

public class C : B 
{ 
    public override void Print() 
    { 
     Console.WriteLine("I'm in C!"); 

     base.Print(); 
    } 
} 

Который эффективно

public abstract class A 
{ 
    public virtual void Print() 
    { 
     Console.WriteLine("I'm in A!"); 
    } 
} 

public abstract class B : A 
{ 
} 

public class C : B 
{ 
    public override void Print() 
    { 
     Console.WriteLine("I'm in C!"); 

     base.Print(); 
    } 
} 
+0

Это лучший ответ, о котором я мог думать, но он теряет один элемент, который я хотел бы иметь, что заставляет классы, которые расширяют B, реализовать свои собственные Print(). –

+0

Если B не имеет логики diffefrent, другие реализации, которые вы нам не показываете, почему вы обертываете A? –

+0

Чтобы добавить дополнительную информацию о фонах, большинство моих реализаций (скажем, классов D, E и F) напрямую распространяют A. В таких случаях реализация Print() является необязательной. Однако, если B используется для расширения A, я не хочу, чтобы реализация Print была необязательной, я хочу, чтобы она была обязательной (и я также хочу, чтобы это было сделано на еще одном уровне расширения) –

1

Если удалить попытку перекрыть из B:

public abstract override void Print(); 

Это именно то, что он будет делать.

Полный код:

static void Main(string[] args) 
    { 
     var c = new C(); 
     c.Print(); 

     Console.ReadLine(); 
    } 

    public abstract class A 
    { 
     public virtual void Print() 
     { 
      Console.WriteLine("I'm in A!"); 
     } 
    } 

    public abstract class B : A 
    { 
    } 

    public class C : B 
    { 
     public override void Print() 
     { 
      Console.WriteLine("I'm in C!"); 
      base.Print(); 
     } 
    } 

Результат:

I'm in C! 
I'm in A! 
Смежные вопросы