C# 在我的继承树的不同类之间共享代码
假设我有以下继承树:C# 在我的继承树的不同类之间共享代码,c#,C#,假设我有以下继承树: ______ Object______ / \ Food Material / \ / \ Egg Carrot Box Axe 用C表示# 现在我只想在类框和Egg之间共享功能,例如: bool opened = true; public void Open() { open = tr
______ Object______
/ \
Food Material
/ \ / \
Egg Carrot Box Axe
用C表示#
现在我只想在类框和Egg之间共享功能,例如:
bool opened = true;
public void Open() { open = true; }
public void Close() { open = false; }
public bool IsOpen() { return opened; }
这是一个简短的例子,但它可能会更长
正确的方法是什么?如果我使用继承,其他类(如Carrot和Axe)将得到它,这是我不希望看到的
更新
许多人提到了作文。有人能在我介绍的示例中向我展示一下它是如何工作的吗?为什么不使用接口呢<代码>启用IOP
interface IOpenable {
void Open();
void Close();
bool IsOpen();
}
为什么不使用接口呢<代码>启用IOP
interface IOpenable {
void Open();
void Close();
bool IsOpen();
}
您有几个选择:
您有几个选择:
当我想到
Egg
和Box
之间的相似性,它们不是Carrot
和Axe
共享的属性时,我首先想到的是它们包含一些东西
Egg
和Box
有内容
,可以公开、隐藏、添加、删除等Egg
和Box
有内容
。单词have(或has)表示表示表示另一个对象的内容的对象应用作合成元素
鸡蛋是一种食物。一个蛋含有内容物,即蛋黄和蛋清
框是办公材料的一种类型。框
包含内容
,这些内容是办公用品
我可以这样写:
public class Food : Object
{
public void Eat() { }
}
public class OfficeMaterial : Object { }
public class Contents : Object
{
bool _visible = false;
List<Object> _things = new List<Object>();
public int Count { get { return _things.Count; } }
public bool IsOpen { get { return _visible; } }
public void Expose()
{
_visible = true;
}
public void Hide()
{
_visible = false;
}
public void Add(object thing)
{
_things.Add(thing);
}
public bool Remove(object thing)
{
return _things.Remove(thing);
}
}
public class Box : OfficeMaterial
{
public Contents BoxContents = new Contents();
}
public class Egg : Food
{
public Contents EggContents = new Contents();
}
Eat()
方法是Food
类的方法。Expose()
方法是内容类的方法,而不是食品类或办公材料类的方法,也不属于Egg
和Box
类。当我想到Egg
和Box
之间的相似性时,我首先想到的是它们包含一些东西
Egg
和Box
有内容
,可以公开、隐藏、添加、删除等
注意这里的语言-Egg
和Box
有内容
。单词have(或has)表示表示表示另一个对象的内容的对象应用作合成元素
鸡蛋是一种食物。一个蛋含有内容物,即蛋黄和蛋清
框是办公材料的一种类型。框
包含内容
,这些内容是办公用品
我可以这样写:
public class Food : Object
{
public void Eat() { }
}
public class OfficeMaterial : Object { }
public class Contents : Object
{
bool _visible = false;
List<Object> _things = new List<Object>();
public int Count { get { return _things.Count; } }
public bool IsOpen { get { return _visible; } }
public void Expose()
{
_visible = true;
}
public void Hide()
{
_visible = false;
}
public void Add(object thing)
{
_things.Add(thing);
}
public bool Remove(object thing)
{
return _things.Remove(thing);
}
}
public class Box : OfficeMaterial
{
public Contents BoxContents = new Contents();
}
public class Egg : Food
{
public Contents EggContents = new Contents();
}
Eat()
方法是Food
类的方法。Expose()
方法是Contents
类的方法,而不是Food
类或OfficeMaterials
类,也不是Egg
或Box
类的方法。这是一种有效的多重继承,C除了通过接口之外不支持
一个选项是在不使用Open方法的情况下创建一个接口(否则必须实现它,因此这仅用于键入目的),然后在接口旁边的静态类中实现一个静态扩展方法
public Interface IOpenable { }
public static class IOpenableExtensions {
public static Open(this IOpenable obj){
// work on any concrete implementation of IOpenable
}
}
用法:
var box = new Box; // Box implements IOpenable
var egg = new Egg; // Egg implements IOpenable
box.Open();
egg.Open();
当实际继承反映核心结构或组织,而接口提供某些对象共享的公共“行为”时,此模式可能会很好地工作。一个类可以实现一个或多个这样的接口
C#8默认接口实现可能会使这种模式更加常见
实际上,在使用处理基类的函数时,通常需要将对象强制转换到接口
public IEnumerable<Food> GetFoods(){ ... }
public void HandleFood() {
for(var food in GetFoods()) {
if(food is IOpenable openableFood){
openableFood.Open();
}
}
}
这实际上是多重继承,C#除了通过接口之外不支持其他继承
一个选项是在不使用Open方法的情况下创建一个接口(否则必须实现它,因此这仅用于键入目的),然后在接口旁边的静态类中实现一个静态扩展方法
public Interface IOpenable { }
public static class IOpenableExtensions {
public static Open(this IOpenable obj){
// work on any concrete implementation of IOpenable
}
}
用法:
var box = new Box; // Box implements IOpenable
var egg = new Egg; // Egg implements IOpenable
box.Open();
egg.Open();
当实际继承反映核心结构或组织,而接口提供某些对象共享的公共“行为”时,此模式可能会很好地工作。一个类可以实现一个或多个这样的接口
C#8默认接口实现可能会使这种模式更加常见
实际上,在使用处理基类的函数时,通常需要将对象强制转换到接口
public IEnumerable<Food> GetFoods(){ ... }
public void HandleFood() {
for(var food in GetFoods()) {
if(food is IOpenable openableFood){
openableFood.Open();
}
}
}
这可能与你有关:作文是你的朋友。无论如何,继承被高估了(我个人的观点)。@Dbugger您想要在类之间共享代码,可能需要共享一些行为。组合解决方案是将该行为放入一个类中,然后添加该类的一个实例作为私有membe