在我的游戏中,我团结一致地拥有一个抽象超类SpaceshipController
,它包含一个已实现的方法protected void updateSpaceshipMovement()
。对于每个太空飞船,都有一个子类,并且在某些子类中,该方法被覆盖(protected new void updatePlayerMovement()
)。在超类中调用该方法时,会使用SpaceshipController
的实现,而我想知道在超类代码中调用该方法时是否有一种方法可以在子类中调用该实现。
答案 0 :(得分:3)
要回答这个问题:
不,不是您实现此目的的方式。
基类应该如何知道某个地方有一个继承的类,该类具有覆盖其方法的方法,应改为调用它?
您必须使用override
关键字正确继承(virtual
)方法。为了显示差异,我还添加了abstract
方法。
public abstract class SpaceshipController
{
// already has an implementation but might be extended or overruled
protected virtual void updateSpaceshipMovement()
{
// do something general
}
// does not have an implementation -> HAS to be implemented by subclass
protected abstract void Something();
}
如果没有abstract
方法,您甚至根本不必建立基类abstract
。
现在在override
方法的子类virtual
中。 (并实施abstract
。)
public class ExampleController : SpaceshipController
{
// I don't have to implement updateSpaceshipMovement
// but I want to extend or overwrite it
protected override void updateSpaceshipMovement()
{
// optional: anyway execute base code
base.updateSpaceshipMovement();
// do other stuff
}
// I have to implement this
protected override void Something()
{
// do something
}
}
在所有子类都应该有自己的实现并且根本不使用base.updateSpaceshipMovement
的情况下,也许interface可能更好:
public interface ISpaceshipController
{
void updateSpaceshipMovement();
}
interface
可以解释为abstract class
,其中仅包含 abstract
个方法,而但一类以后可以实现多个接口,这使其成为非常强大的工具。
实施,例如像
public class ExampleController : MonoBehaviour, ISpaceshipController
{
// I have to implement this to fulfill the interface implementation
public void updateSpaceshipMovement()
{
// do stuff
}
}
答案 1 :(得分:1)
您要问的是多态性。在您的方案中,可以通过在抽象类中提供默认实现(作为虚拟方法)来实现此目的,并且它们允许每个子类通过重写方法来提供自己的实现。
在SpaceshipController
中,将protected void updateSpaceshipMovement()
更改为protected virtual void updateSpaceshipMovement()
。这是告诉编译器将此默认实现用于SpaceshipController及其所有子类。
在您的子类中,将protected new void updatePlayerMovement()
更改为protected override void updatePlayerMovement()
。这是告诉编译器将此修改后的实现用于此特定类。
protected override void updatePlayerMovement(){
base.updatePlayerMovement(); //you can also call the parent implementation first if you so choose.
//now perform the actions specific to this sub class.
}