2010-01-11 5 views
1

Я не знаю, как это называется, но здесь.Несколько дериваций того же объекта

public class Person 
{ 
    long ID; 
} 

public class Banker : Person 
{ 
    string example1; 
} 

public class Scientist : Person 
{ 
    string example2; 
} 

Я пытаюсь реализовать наш ORM, чтобы соответствовать нашей базе данных, и я столкнулся с этой проблемой. Надеюсь, этот пример достаточно прост для понимания.

Теперь сопоставление объектных отношений имеет смысл для человека, являющегося Банкиром или Ученым. Проблема, с которой я столкнулась, - это Человек, являющийся Банкиром и Ученым. Так что я пытаюсь сделать, это возможность создать Банкира или Ученого и быть способным бросить его, либо имея тот же объект базового класса.

Я действительно не ищу много наследования. Я ищу способ создания нескольких объектов с одним и тем же объектом базового класса. Например, Лицо - это банкир и ученый, но не ученый-банкир (класс, имеющий атрибуты как банкира, так и ученого).

Это был недостаток в базе данных, и теперь модель меняется, но ее все еще вызывает сомнение.

+2

Без особого знания о вашей модели, если это настоящий пример, но для меня это может быть лучше, чем ассоциация, а не наследование - то есть кто-то человек, но имеет профессию (или несколько занятий). Это позволяет упростить техническое обслуживание на тот момент, когда вам нужен банкир/ученый/премьер-министр. Может быть сделано без изменения кода. – Paddy

+0

Также помните правило # 1 наследования: только наследуйте, если вы добавляете поведение к дочернему классу. Не наследуйте, просто добавляйте элементы данных. –

ответ

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 { } 

Так вот Dog является Animal и Cat является Animal, но это не имеет никакого смысла, чтобы быть в состоянии бросить между ними. Да, вы можете определить пользовательские преобразования, но не делать этого; это будет огромный дизайн запаха.

+0

Да, я знаю, что я мог бы сделать что-то подобное, проблема заключается в том, что человек может быть любой перестановкой в ​​18 карьеров. Поэтому я должен создать 18! классы? – Will

+1

Я не думаю, что вы хотите использовать слово «перестановка». Вы говорите, что у вас есть восемнадцать карьеров в вашей системе, и у человека может быть (возможно, несколько) из восемнадцати карьеры? Может ли человек быть любым возможным подмножеством из восемнадцати карьеры (2 18 возможных подмножеств, включая пустой набор)? Это явно нереально. Если это реалистично, вам нужно «class Career {//}» и «class Person {HashSet Careers; //} '. – jason

+0

Для этого примера, нет, это не реально для человека, чтобы быть любым возможным подмножеством в 2^18 карьеры. Но что мне делать, определяет то, что человек может и не может быть, что не кажется оптимальным решением. (Оглядываясь назад, прошу прощения за мою ужасную математику, не знаю, о чем я думал.) – Will

1

Термин, который вы ищете, это Multiple Inheritance, который C# напрямую не поддерживает.

Вы можете использовать несколько интерфейсов.

2

К сожалению, в большинстве языков .NET (C# и конкретно) - вы не можете использовать multiple inheritance создать BankerScientist:

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

Лучшее, что вы можете сделать, это использовать композицию. Разделите детали, которые определяют ученого и банкира в неустойчивые классы, а затем составляют их в свои классы относительного сопоставления.

Вы также можете использовать интерфейсы для определения IScientist и IBanker, которые затем могут быть реализованы классом BankerScientist.

+0

Я думаю, что MI возможно в CLR. Я попытаюсь выкопать ссылку. – jason

+0

Это сообщение в блоге, похоже, подразумевает мое утверждение выше: http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85562.aspx «Однако я должен указать, что компиляторы могут создайте MI для своих типов внутри CLR. Если вы идете по этому пути, есть несколько грубых ребер: результат не поддается проверке, нет взаимодействия с другими языками через CLS, а в V1 и V1.1 вы можете столкнуться с взаимоблокировками с блокировкой загрузчика ОС ». – jason

0

Я бы предложил использовать интерфейсы. Множественное наследование не поддерживается, но класс может наследовать несколько интерфейсов.

У вас может быть интерфейс IPerson, который будет реализован в вашем классе Person, тогда у вас будут отдельные интерфейсы для IBanker и IScientist, которые оба будут получены из IPerson и могут быть реализованы отдельно или оба одновременно. Все написанные вами классы могут по-прежнему использовать класс Person в качестве базы, но могут реализовывать любые интерфейсы, которые вам нужны в каждом экземпляре.

0

Я всегда использую это, как правило:

  • Используйте вывод, если есть «это» отношения
  • Используйте интерфейсы для представления «ведет себя как» отношения

Теперь с учетом ваш пример, я бы пошел путем реализации Person с точки зрения IBanker и IScientist и вернуть тот или иной интерфейс в нужный ему код. Банкир мог стать каким-то - позже ученым (теоретически ;-)). В вашей базе данных вы, вероятно, также не имеете двух отдельных таблиц или нет? Я думаю, что это что-то вроде флага, который различает оба. Дело не в том, что Банкир - это человек, робот тоже может вести себя как банкир. Поэтому я бы не пошел по пути получения Банкира от Лица, аналогичной аргументации для Ученого.

Надеюсь, это поможет.

Смежные вопросы