2017-06-23 28 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