网站怎么做二维码logo在线设计生成器app
先看代码:
TankBaseObj obj = other.GetComponent<TankBaseObj>();if(obj != null){//说明是坦克打到坦克 受伤处理 固定不会受伤 移动的会受伤obj.Wound(fatherObj);}
TankBaseObj 是一个基类 wound是一个虚函数 子类已经重新实现 当你的游戏对象依附的是一个已经继承TankBaseObj的子类 然后 TankBaseObj obj = other.GetComponent<TankBaseObj>(); obj 就是子类的实例化 只不过 这里是用父类装子类的思想 但是他实际的引用还是子类对象 并且 子类已经重写虚函数Wound 所以这里掉用的就会是重写的函数方法
在Unity中,当你使用GetComponent<T>()方法获取组件时,你实际上是在尝试从游戏对象上获取类型为T的组件。在你的例子中,T是TankBaseObj,这是一个父类。如果游戏对象上附加了一个继承自TankBaseObj的子类组件(比如TankChildObj),那么GetComponent<TankBaseObj>()将会成功返回这个子类组件的实例,因为子类实例也是父类类型的一个对象。
现在,关于你提到的Wound方法被重写的情况,这里有一些关键点需要理解:
-
虚方法和重写:如果
TankBaseObj中的Wound方法被标记为virtual,并且子类(比如TankChildObj)中提供了这个方法的一个override实现,那么当通过父类类型的引用调用这个方法时,实际上会调用子类中的重写方法。这是C#中多态性的一个表现。 -
实际对象类型:在运行时,
obj变量虽然被声明为TankBaseObj类型,但它实际上指向的是子类(如TankChildObj)的一个实例。因此,当调用obj.Wound(fatherObj);时,会调用该实例上重写的Wound方法。 -
编译时与运行时类型:在编译时,
obj的类型是TankBaseObj,编译器只知道它可以调用TankBaseObj上定义的方法。但在运行时,obj实际指向的是一个具体的子类实例,所以运行时会根据这个实例的实际类型来确定调用哪个Wound方法。
举个例子,假设有以下类定义:
public class TankBaseObj : MonoBehaviour
{ public virtual void Wound(GameObject attacker) { // 父类的受伤处理逻辑 Debug.Log("TankBaseObj Wound"); }
} public class TankChildObj : TankBaseObj
{ public override void Wound(GameObject attacker) { // 子类的受伤处理逻辑 Debug.Log("TankChildObj Wound"); // 可能还会调用base.Wound(attacker)来执行父类的逻辑 }
}
如果游戏对象上附加了TankChildObj组件,并且你通过GetComponent<TankBaseObj>()获取了这个组件,然后调用了Wound方法,那么将会输出TankChildObj Wound,因为实际调用的是TankChildObj中重写的Wound方法。
总结来说,当你通过父类类型的引用调用一个被子类重写的方法时,实际调用的是运行时对象类型中重写的方法。这是面向对象编程中多态性的一个基本特性。
