C#:如何在使用子类C时隐藏模型类D的ID属性?
嘿,这个场景我之前也碰到过,根据不同的语言和架构偏好,有几个靠谱的解决方案,给你梳理一下:
方案1:拆分模型类D,通过继承分离专属属性
这是最干净的方案——把共享的模型部分抽成父类,再专门给B做一个带专属ID的子类。这样C直接用基础模型,从根源上就没有那个ID属性。
举个Python的例子:
# 基础共享模型,只包含B和C都需要的属性 class BaseSharedD: shared_name = "" shared_value = 0 # 给B专属的模型,继承基础类并添加ID class DForB(BaseSharedD): b_exclusive_id = 0 # 子类B使用带ID的模型 class B(A): def __init__(self): self.model = DForB() # 子类C直接用基础共享模型 class C(A): def __init__(self): self.model = BaseSharedD()
这种方式结构清晰,后续扩展也方便,完全避免了C接触到不属于它的属性。
方案2:在C类中封装模型D,控制属性访问权限
如果不想拆分原有的D类,那可以在C里把D实例私有化,只对外暴露共享的属性,完全屏蔽那个专属ID。
还是用Python举例:
class D: # 共享属性 shared_name = "" shared_value = 0 # B专属ID b_exclusive_id = 0 class A: pass class B(A): def __init__(self): self.model = D() # B可以自由访问ID def get_b_id(self): return self.model.b_exclusive_id class C(A): def __init__(self): # 把D实例设为私有,外部无法直接访问 self._internal_model = D() # 只暴露共享属性的getter/setter @property def shared_name(self): return self._internal_model.shared_name @shared_name.setter def shared_name(self, val): self._internal_model.shared_name = val @property def shared_value(self): return self._internal_model.shared_value @shared_value.setter def shared_value(self, val): self._internal_model.shared_value = val
这样外部访问C的实例时,根本看不到b_exclusive_id这个属性,完美实现隐藏效果。如果是Java/C#这类语言,用私有字段+公共get/set方法就能达到同样的目的。
方案3:用接口/抽象类定义访问契约(强类型语言适用)
如果是Java、C#这类强类型语言,可以定义一个只包含共享属性的接口,让D实现这个接口,然后C类里持有接口类型的引用——这样编译阶段就会限制C只能访问接口定义的内容,看不到专属ID。
比如Java的示例:
// 定义共享属性的接口 interface SharedModel { String getSharedName(); void setSharedName(String name); int getSharedValue(); void setSharedValue(int value); } // 原模型类D实现接口,同时包含B专属ID class D implements SharedModel { private String sharedName; private int sharedValue; private int bExclusiveId; // B专属ID // 实现接口的共享属性方法 @Override public String getSharedName() { return sharedName; } @Override public void setSharedName(String name) { this.sharedName = name; } @Override public int getSharedValue() { return sharedValue; } @Override public void setSharedValue(int value) { this.sharedValue = value; } // B专属的ID访问方法 public int getBExclusiveId() { return bExclusiveId; } public void setBExclusiveId(int id) { this.bExclusiveId = id; } } class A {} class B extends A { private D model; public B() { model = new D(); } // B可以直接调用D的专属ID方法 public int getBId() { return model.getBExclusiveId(); } } class C extends A { private SharedModel model; // 持有接口引用 public C() { model = new D(); } // 只能访问接口定义的共享属性,编译期看不到ID相关方法 public String getSharedName() { return model.getSharedName(); } }
这种方式在编译阶段就杜绝了C访问ID的可能,非常安全,适合强类型语言的严谨场景。
总结一下:优先考虑拆分模型(方案1),结构最清晰;如果不能拆分,就根据语言特性选封装(方案2)或者接口契约(方案3),都能完美解决你的问题。
内容的提问来源于stack exchange,提问作者superninja
相关产品推荐
相关产品推荐

