C#如何在预定义接口方法中使用受保护类方法?强制实现类继承MonoBehaviour
接口与MonoBehaviour兼容问题解决方案
能否在接口中直接使用GetComponentsInChildren<T>()?
不能。接口本身不继承任何类,也不包含MonoBehaviour的方法实现,所以在接口的私有方法ChangeState里直接调用GetComponentsInChildren<T>()会触发编译错误——接口无法识别该方法的定义。
强制实现类继承MonoBehaviour的两种方案
方案1:改用继承MonoBehaviour的抽象类(推荐)
将原接口替换为继承自MonoBehaviour的抽象类,这样所有子类必须继承MonoBehaviour,同时可以把通用逻辑封装在抽象类中,子类仅需实现必要的抽象属性:
public abstract class EquipableBehaviour : MonoBehaviour { protected abstract string EquipedText { get; } protected abstract string EquipText { get; } protected void ChangeState(bool equipe, string name) { if ((!equipe && ShopData.GetInstance().IsPurchased(name)) || equipe) { string message = equipe ? EquipedText : EquipText; foreach (var button in GetComponentsInChildren<Button>()) { if (button.tag == "PriceButton") button.enabled = !equipe; } foreach (var text in GetComponentsInChildren<TextMeshProUGUI>()) { if (text.name == "PriceText") text.text = message; } } } }
子类实现示例:
public class ShopItem : EquipableBehaviour { protected override string EquipedText => "已装备"; protected override string EquipText => "装备"; }
这种方式既保证了子类必须继承MonoBehaviour,又避免了重复代码,是Unity场景下最常用的做法。
方案2:在接口中声明依赖方法(不推荐)
如果坚持使用接口,可以在接口内声明需要用到的GetComponentsInChildren<T>()方法,强制实现类(必须是MonoBehaviour)提供该方法的包装实现:
public interface IEquipe { protected abstract string EquipedText { get; } protected abstract string EquipText { get; } // 声明依赖方法 protected abstract T[] GetComponentsInChildren<T>() where T : Component; private void ChangeState(bool equipe, string name) { if ((!equipe && ShopData.GetInstance().IsPurchased(name)) || equipe) { string message = equipe ? EquipedText : EquipText; foreach (var button in GetComponentsInChildren<Button>()) { if (button.tag == "PriceButton") button.enabled = !equipe; } foreach (var text in GetComponentsInChildren<TextMeshProUGUI>()) { if (text.name == "PriceText") text.text = message; } } } }
实现类示例:
public class ShopItem : MonoBehaviour, IEquipe { protected string EquipedText => "已装备"; protected string EquipText => "装备"; protected T[] GetComponentsInChildren<T>() where T : Component { // 直接调用MonoBehaviour的原生方法 return base.GetComponentsInChildren<T>(); } }
这种方式需要每个实现类重复编写方法包装,代码冗余度高,仅在必须使用接口的场景下考虑。
内容的提问来源于stack exchange,提问作者SEGMK
相关产品推荐
相关产品推荐

