Звучит так, будто вы пытаетесь смоделировать телефонные контакты и контакты электронной почты, но я думаю, что у вас действительно есть контакты с основным методом контакта: телефон или электронная почта. То, как я бы это структурировал, было бы с композицией - при условии, что вы хотите иметь гибкость, чтобы иметь несколько телефонных номеров / адресов электронной почты. Если вы можете жить с одним из них, вы можете сохранить его непосредственно в таблице контактов. Если вам нужно несколько адресов, то обрабатывайте их так же, как телефон / электронная почта с отдельной таблицей.
Contacts Table
ContactID
FirstName
LastName
MI
StreetAddress1
StreetAddress2
City
StateProvince
PostalCode
PreferredContactMethod (0 = Phone, 1 = Email)
... more details ...
PhoneNumbers Table
PhoneID
ContactID
PhoneNumber
IsPrimary
...more details...
EmailAddresses Table
EmailID
ContactID
EmailAddress
IsPrimary
...more details...
Тогда для ваших классов у вас будет класс Contact, который содержит один или несколько номеров телефонов и один или несколько адресов электронной почты. Если у вас есть другие вещи, кроме контактов, которые имеют номера телефонов или адреса электронной почты, то может иметь смысл иметь интерфейсы, указывающие на то, что они являются IPhoneable или IEmailable - это означает, что вы можете добавлять / удалять номера телефонов или адреса электронной почты с них, например :
public interface IPhoneable
{
public PhoneNumber GetPrimaryNumber();
public void AddNumber( PhoneNUmber number );
public IEnumerable<PhoneNumber> GetNumbers();
}
public interface IEmailable
{
public EmailAddress GetPrimaryAddress();
public void AddEmailAddress( EmailAddress address );
public IEnumerable<EmailAddress> GetEmailAddresses();
}
public class Contact : IPhoneable, IEmailable
{
private List<PhoneNumber> phoneNumbers;
private List<EmailAddresses> emailAddresses;
public int ContactID { get; private set; }
public string FirstName { get; set; }
...
public Contact()
{
this.phoneNumbers = new List<PhoneNumber>();
this.emailAddresses = new List<EmailAddress>();
}
public PhoneNumber GetPrimaryNumber()
{
foreach (PhoneNumber number in this.phoneNumbers)
{
if (number.IsPrimary)
{
return number;
}
}
return null;
}
...
}
Если бы вы хотели, вы могли бы иметь PhoneableContact и EmailableContact, который бы разделял на подклассы контакт и был бы дифференцируемым в зависимости от предпочтительного метода контакта, но я действительно не вижу в этом необходимости. Если бы вы сделали это, то Contact не реализовал бы ни один интерфейс - подклассы реализовали бы соответствующие соответственно.