2017-06-23 75 views
1

請採取掠奪我的代碼:如何在C#中使用自動後期綁定?

public class TweenerBase { 
    public void Update() {} 
} 

public class Vector3Tweener : TweenerBase { 
    public void Update() { ... } 
} 

public class ColorTweener : TweenerBase { 
    public void Update() { ... } 
} 

在一些其他類我稱之爲:

private List <TweenerBase> tweens; 

tweens = new List <TweenerBase>(); 

ColorTweener tween1 = new ColorTweener(); 
Vector3Tweener tween2 = new Vector3Tweener(); 

tweens.Add(tween1); 
tweens.Add(tween2); 

的問題出現時,我呼籲:

tweens[ 0 ].Update(); 

它調用:TweenerBase。更新()不是我所期望的ColorTweener.Update()。我可以用這樣的修正:

if (tweens[ 0 ].type == "ColorTween") ((ColorTween) tweens[ 0 ]).Update(); 

但它是非常不方便的解決方案,如果我使用類似:

((ColorTween) tweens[ 0 ]).Update(); 
float value = ((ColorTween) tweens[ 0 ]).GetCurrentValue(); 
((ColorTween) tweens[ 0 ]).SomeAnotherVoid(); 
((ColorTween) tweens[ 0 ]).SomeAnotherVoid2(); 

它看起來令人難以置信的:)有沒有一種方法,使後期綁定調用只是:

tweens[ 0 ].Update(); 

它會自動調用ColorTweener.Update()?

+0

在Java中,方法是'默認virtual'(而且也沒有關鍵字的話)。如果你想在C#中實現同樣的事情,你需要在'TweenerBase'的聲明中加入'virtual'(正如其他人所說的那樣)。 在這種情況下,它看起來像你的抽象類只有一個空方法。如果你使用'interface',而不是從TweenerBase'繼承的東西,就必須實現它。 –

回答

1

您需要在您的基類方法上使用虛擬並在您的子類上覆蓋它,目前您隱式地在您的子類方法上使用new,因此在傳遞基類時調用update會調用基類方法。

1

爲什麼你沒有使Update()函數爲虛擬?

0

如果你想派生類的方法來隱藏基地的方法,你必須使用new關鍵字在派生類中的方法聲明:

class derived : base 
{ 
    public new void method() { } 
} 

或者,如果基類就是由你的容器爲了一次處理不同的子類,你可以在底部聲明該方法爲abstract,通過覆蓋派生的方法來提供它的實現。

abstract class base 
{ 
    public abstract void method(); 
} 

class derived : base 
{ 
    public override void method() 
    { // your code } 
} 
0

您應該使用在基類virtual關鍵字和關鍵字override在派生類這是你所期望的工作。

using System; 
using System.Collections.Generic; 

namespace ConsoleApplication 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var tweens = new List<TweenerBase>(); 

      var tween0 = new TweenerBase(); 
      var tween1 = new ColorTweener(); 
      var tween2 = new Vector3Tweener(); 

      tweens.Add(tween0); 
      tweens.Add(tween1); 
      tweens.Add(tween2); 

      foreach (var tween in tweens) 
      { 
       tween.Update(); 
      } 
     } 
    } 

    public class TweenerBase 
    { 
     /// <summary> 
     /// Make sure you mark the base implementation as 'virtual'. 
     /// </summary> 
     public virtual void Update() 
     { 
      Console.WriteLine(nameof(TweenerBase)); 
     } 
    } 

    public class Vector3Tweener : TweenerBase 
    { 
     /// <summary> 
     /// Make sure to user 'override' keyword to override the base implementation. 
     /// </summary> 
     public override void Update() 
     { 
      Console.WriteLine(nameof(Vector3Tweener)); 
     } 
    } 

    public class ColorTweener : TweenerBase 
    { 
     /// <summary> 
     /// Make sure to user 'override' keyword to override the base implementation. 
     /// </summary> 
     public override void Update() 
     { 
      Console.WriteLine(nameof(ColorTweener)); 
     } 
    } 
} 

這個程序打印出:

TweenerBase 
ColorTweener 
Vector3Tweener