如何在C#中使用自动后期绑定?
请查看我的密码:如何在C#中使用自动后期绑定?,c#,class,late-binding,C#,Class,Late Binding,请查看我的密码: public class TweenerBase { public void Update() {} } public class Vector3Tweener : TweenerBase { public void Update() { ... } } public class ColorTweener : TweenerBase { public void Update() { ... } } 在另一类中,我称之为: private List
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 );
它调用:tweernerbase.Update(),而不是我所期望的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()。您需要在基类方法上使用virtual并在子类上重写它,目前您在子类方法上隐式使用new,因此在传递基类时调用Update将调用基类方法。为什么您没有进行Update()函数虚拟?如果希望派生类的方法隐藏base的方法,则必须在派生类的方法声明中使用
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 }
}
您应该在基类中使用
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));
}
}
}
在Java中,默认情况下方法是
virtual
(并且没有关键字)。如果你想在C语言中实现同样的效果,你需要在TweenerBase的声明中添加virtual
(正如其他人所说)。在本例中,抽象类似乎只有一个空方法。如果您使用的是接口
,那么您将使用它,以便从TweenerBase
继承的东西必须实现它。
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