1

I have a set of interfaces that I'm working with. They are IPatient, IDoctor and IPerson. IPerson contains shared properties of every person(name, gender, address, etc). I would like for IDoctor and IPatient to implement IPerson but this can't be done in C# according to this question..

Is there any way to eliminate these duplicate properties between IPatient and IDoctor?

Community
  • 1
  • 1
Bill Martin
  • 4,825
  • 9
  • 52
  • 86
  • 1
    Why would you need to make `IPerson` an interface? Wouldn't it be better to code `Person` as an abstract class? I find that you should generally prefer abstract classes over interfaces anyway, as it's quite handy to provide default implementation in a single place and only override it in derived classes where necessary. – Cody Gray - on strike Feb 10 '12 at 17:12
  • My methods accept interfaces as their params. If I implement it as an abstract, then I have to cast the param to it's concrete instance to use the properties in the abstract class. – Bill Martin Feb 10 '12 at 17:52
  • @BillMartin no you don't. When you call an interface method, the CLR calls a particular method on the object based on the interface map of the object's run-time type. The author of the object's runtime type has complete control over this through the use of explicit interface member implementation. You don't need to cast the object. Or do I misunderstand the problem? – phoog Feb 10 '12 at 17:54
  • @phoog Does that include inherited types? Using the example, where Person is an abstract class and Doctor inherits Person and implements IDoctor, if my method accepts IDoctor, the Doctor instance has no intellisense for 'Name' from the abstract class inside the method. When I change the method to accept Doctor, I get intellisense. Why would that be? – Bill Martin Feb 10 '12 at 19:11
  • @BillMartin The literal answer to why the Name property from the abstract class isn't visible is because the type of the parameter is the interface, not the class. You need a Name property on the interface. Specifically, it sounds like IDoctor doesn't inherit from IPerson. – phoog Feb 10 '12 at 20:57
  • @BillMartin I think you want `abstract class Person : IPerson`, `interface IDoctor : IPerson` and `class Doctor : Person, IDoctor`. Look for example at the interfaces in `Systems.Collections.Generic`. `IList` doesn't implement `GetEnumerator()`, but if you have a variable of `IList`, you get intellisense for that method because it's inherited (indirectly) from `IEnumerable`. – phoog Feb 10 '12 at 20:58
  • @phoog hmm, did that but since IPerson properties are not explicitly defined in IDoctor, they don't appear. Am I doing something wrong? – Bill Martin Feb 10 '12 at 22:26
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7547/discussion-between-phoog-and-bill-martin) – phoog Feb 10 '12 at 22:26

3 Answers3

6

Where is the duplication you speak of? If you look at an example:

interface IPerson
{
    string Name { get; set; }
}

interface IDoctor : IPerson
{
    string Specialty {get; set; }
}

class Doctor : IDoctor
{
   public string Name { get; set; }
   public string Specialty {get; set;}
}

There is no duplication here - Doctor only has to implement the Name property once and also of course has to implement the Specialty property.

Interfaces give you just that an interface, not an implementation of properties (and that's exactly what you would want in most cases to take advantage of polymorphism) - if you need a default implementation of those properties you should probably use an abstract base class that implements those properties.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
2

This is definitely possible. The linked question also has the constraint that no other class may implement the interface. Scraping that nonsense constraint we can simply do:

interface IPerson
{   
    string Name { get; }
}

interface IDoctor: IPerson
{
    int DoctorSpecificProperty { get; }
}

interface IPatient
{
    int PatientSpecificProperty { get; }
}
vidstige
  • 12,492
  • 9
  • 66
  • 110
1

As is shown in the link you provided, IPatient and IDoctor can both extend IPerson, you just can't stop someone from implementing IPerson without implementing IPatient or IDoctor.

Servy
  • 202,030
  • 26
  • 332
  • 449