C# 有没有办法调用方法的最子类实现?
在我的游戏中,我在unity中制作了一个抽象的超类C# 有没有办法调用方法的最子类实现?,c#,oop,polymorphism,C#,Oop,Polymorphism,在我的游戏中,我在unity中制作了一个抽象的超类SpaceshipController,它包含一个实现方法protected void updatespaceshipmotation()。对于每一艘宇宙飞船,都有一个子类,其中一些子类中的方法被覆盖(protectednewvoidupdateplayermovement())。在超类中调用的方法使用了SpaceshipController的实现,我想知道在超类代码中调用该方法时,是否有方法在子类中调用该实现。您要问的是多态性。在您的场景中,您
SpaceshipController
,它包含一个实现方法protected void updatespaceshipmotation()
。对于每一艘宇宙飞船,都有一个子类,其中一些子类中的方法被覆盖(protectednewvoidupdateplayermovement()
)。在超类中调用的方法使用了SpaceshipController
的实现,我想知道在超类代码中调用该方法时,是否有方法在子类中调用该实现。您要问的是多态性。在您的场景中,您可以通过在抽象类中提供默认实现(作为虚拟方法)来实现这一点,并且允许每个子类通过重写该方法来提供自己的实现
在SpaceshipController
中,将protected void updatespaceshipmotation()
更改为protected virtual void updatespaceshipmotation()
。这告诉编译器对SpaceshipController和任何子类使用此默认实现
在子类中,将受保护的新void updatePlayerMovement()
更改为受保护的覆盖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.
}
您必须使用
virtual
关键字正确继承(override
)方法。为了显示差异,我还添加了一个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
方法。(并实现摘要
部分。)
- 意思是:
该方法在基类中已经有一个实现,但仍可以覆盖或使用base.method()
- 意思是:
基类中没有实现=>必须由子类实现
如果所有子类都应该有自己的实现,并且根本不使用
base.updateSpaceshipMovement
,那么an可能会更好:
public interface ISpaceshipController
{
void updateSpaceshipMovement();
}
一个接口
可以解释为一个抽象类
,它只包含抽象
方法,但是以后的一个类可以实现多个接口,这使得它成为一个非常强大的工具
实施它,例如像
public class ExampleController : MonoBehaviour, ISpaceshipController
{
// I have to implement this to fulfill the interface implementation
public void updateSpaceshipMovement()
{
// do stuff
}
}
为什么您要使用
new
而不是使基方法virtual
并在子类中重写?@babaknafas,因为我没有完全取消虚拟标识符的重写。virtual
与abstract
的不同之处在于:该方法在父类中已经有一个实现,但可以被重写使用base.method
您已经说过“它已被覆盖”和“它是新的”。但“被推翻”和“新”是对立的。如果您不理解这个事实,那么停止编程,理解这个事实,然后以正确的理解重新开始。假设每个虚拟方法都声明了一个“槽”,每个重写都会在该槽中放置一个不同的方法,每个“新”都会生成一个新槽。现在你明白为什么“覆盖”和“新”是对立的了吗?“覆盖”表示“更改此插槽的值”,“新建”表示“保持旧插槽不变并创建新插槽”。如果你想在C#中成功编程,你需要了解它是如何工作的。在我的例子中,spaceshipController
有很多已经实现的方法,所以它不能成为一个接口,但感谢你的详细回答。它解释得很好。我建议你清理一下virtual
和abstract
的定义。如前所述,“该方法在父类中已经有一个实现,但无论如何都可以被覆盖或使用base.method进行扩展”是否描述了基类或父类上的虚拟修饰符,这一点并不明显。
public class ExampleController : MonoBehaviour, ISpaceshipController
{
// I have to implement this to fulfill the interface implementation
public void updateSpaceshipMovement()
{
// do stuff
}
}