简体   繁体   中英

implements interface using member as implementor

I've got class A that implements IA.
Now I need to create class B that should implement also IA. Class B has instance of class A as a member.

Is there any way to define that A's instance implements the IA in class B?

interfase IA {
    void method1();
    void method2();
    .
    .
    .
    .
    void methodN();
}

class A:IA {
    public void method1(){}
    public void method2(){}
    .
    .
    .
    .
    public void methodN(){}
}

class B:IA {
    private IA m_a;
    public B(IA a) {
      m_a=a;
    }

    //Instead all of this I am looking of a way to define that m_a is the implement to IA of B
    public void method1(){ use of a.method1 }
    public void method2(){ use of a.method2 }
    .
    .
    .
    .
    public void methodN(){ use of a.methodN }
}

Not really, you're probably going to want to define some sort of interface that returns the IA member, like the Enumerable / Enumerator pattern.

public interface IB
{
   public IA Item { get; }
}

Then B could simply return the instance you're storing in it.

public class B : IB
{
    public IA Item { get; private set; }
}

A could even implement IB

public class A : IA, IB
{
    public void Method1();
    //...
    public void MethodN();

    IA IB.Item
    {
        get
        {
            return this;
        }
    }
}

Derive B from A is all what you need.

class B:A {

    public B() {

    }
}

You basically have two options: inherit from A , or encapsulate A . This is basically the difference between two design patterns: encapsulation andinheritance .

If B is really supposed to implement IA , then B must redefine each of the interface methods one by one, even if each implementation is simply a call to the implementation of the encapsulated A member.

Nevertheless, there is a lazy way which can prevent you from all this tedious stuff and which can be considered almost as the same, from a practical point of view:

class Program
{
    static void Main(string[] args)
    {
        CatOwner Bob = new CatOwner();
        Console.WriteLine(((Cat)Bob).Cry);
        Console.ReadKey();
    }
}

interface ICry
{
    string Cry { get; }
}

class Cat : ICry
{
    public string Cry { get { return "Meow !"; } }
}

class CatOwner
{
    private Cat _MyCat;

    public CatOwner()
    {
        _MyCat = new Cat();
    }

    public static implicit operator Cat(CatOwner po)
    {
        return po._MyCat;
    }
}

CatOwner doesn't really implement Cry since the cat owner is not the one who meows: his cat does. But as an approximation we could consider that by demanding to the cat owner to cry, we of course mean that this demand actually targets his cat, not the owner itself. Then we "cast the cat owner to his cat" and then we can make him Cry .

That's pretty funny, no? :-)

Edit:

That said, Magnus' answer is highly worth considering IMHO. It appears more logical and more clean if passing a member is fine considering the semantic context. My solution may be still interesting if B is just a kind of enhanced variety of A which cannot be inherited (sealed), or in such a particular context... Really depends on the context and the semantic constraints...

Not sure, but why are you inheritting class B from IA? you already have an instance of object A in class B, you can use that...

How about exposing the "implementer" in a property instead of B implementering the interface.

class B
{
  public IA Implementer {get; private set;}
  public B(IA a) 
  {
      Implementer = a;
  }
}

Looking at your question from design perspective, it is a perfectly valid question (in a more complicated real life situation) and it would be nice to save a lot of lines of code by just saying that member m_a is the one that implements all the IA interface in B.

I don't quite agree with the suggestions to inherit B from A: 1- in real life, B could inherit from another class unrelated, or say you are implementing IC, and ID, and have members m_c and m_d would be nice to be able to point the implementation of C to m_c and implementation fo ID to m_d..etc 2- replacing aggregation with inheritance is usually a bad design.

Nice idea though..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM