同一对象的多个派生

时间:2010-01-11 16:00:22

标签: c#

我不知道这是什么,但是这里有。

public class Person
{
    long ID;
}

public class Banker : Person
{
    string example1;
}

public class Scientist : Person
{
    string example2;
}

我正在尝试实现我们的ORM来匹配我们的数据库,我遇到了这个问题。希望这个例子很容易理解。

现在,对象关系映射对于作为银行家或科学家的人来说是有意义的。我遇到的问题是作为银行家和科学家的人。所以我想要完成的是能够创建一个银行家或科学家,并能够将它投射到具有完全相同的基类对象的任何一个。

我并不是在寻找多重继承。我正在寻找的是一种使用相同的基类对象实例化多个对象的方法。例如,Person是银行家和科学家,但不是银行家科学家(具有银行家和科学家的属性的类)。

这实际上是数据库中的一个缺陷,模型现在正在改变,但它仍然是一个古怪的问题。

5 个答案:

答案 0 :(得分:9)

C#不支持多重继承,因此当我们需要对与您类似的情况进行建模时,我们经常使用组合或接口。因为您正在处理ORM,所以您可能需要使用接口方法。考虑一下:

interface IPerson { }
interface IBanker : IPerson, IRuinedTheEconomy { }    
interface IScientist : IPerson { }
interface IRobot : IAsimov { }

class Person : IPerson { }
class Banker : Person, IBanker { }
class Scientist : Person, IScientist { }
class BankerAndScientist : Person, IBanker, IScientist { }

至于你正在采用的方法,你不能在兄弟类之间进行转换(即两个具有相同基类的类)。这是一件好事。请记住,继承用于模拟“是一种”关系。

class Animal { }
class Dog : Animal { }
class Cat : Animal { }

所以这里DogAnimalCatAnimal,但是能够在两者之间施放是没有意义的。是的,您可以定义用户定义的转换,但不能;这将是一个巨大的设计气味。

答案 1 :(得分:2)

不幸的是,在大多数.NET语言中(特别是C#) - 你不能使用multiple inheritance来创建一个BankerScientist:

public class BankerScientist : Banker, Scientist { ... }  // illegal

你能做的最好的就是使用构图。将定义科学家和银行家的细节分离为非持久化类,然后将它们组合到您的相关映射类中。

您也可以使用接口来定义IScientist和IBanker,然后由BankerScientist类实现。

答案 2 :(得分:1)

您正在寻找的术语是Multiple Inheritance,而C#并不直接支持。

您可以使用多个界面。

答案 3 :(得分:0)

我建议使用接口。不支持多重继承,但类可以继承多个接口。

你可以拥有一个可以在你的Person类中实现的IPerson接口,然后你就可以为IBanker和IScientist提供单独的接口,这些接口既可以从IPerson派生,也可以单独实现,也可以同时实现。您编写的任何类仍然可以使用Person类作为基础,但可以在每个实例中实现您需要的任何接口。

答案 4 :(得分:0)

我总是将此作为一项规则:

  • 如果存在“是一种”关系,则使用派生
  • 使用接口来表示“表现得像”的关系

现在考虑一下您的示例,我会根据PersonIBanker来实现IScientist,并将一个或其他接口返回到需要它的代码。银行家可能会成为一个 - 后来成为科学家(理论上;-))。在您的数据库中,您可能也没有两个单独的表或者是吗?我想这是一个区分两者的旗帜。成为一个人不是银行家的本质,机器人也可以像银行家一样行事。因此,我不会采用从人物中获取银行家的方式,类似的科学家论证。

我希望它有所帮助。