interface implementation question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Zach

    interface implementation question

    Hi everyone,

    I'm a bit of a newbie to C# programming so forgive this innocent
    question, but coming from a C++ background this seems very odd to me,
    and I'm hoping someone can shed some light onto why things work this
    way as opposed to the C++ way, which I see no real disadvantages in.

    The issue arises when trying to implement an interface in C#. In C++
    it is quite common to define an interface using a bunch fo pure virtual
    functions and then implement it 2 or 3 levels up in the hierarchy. For
    example,

    class A
    {
    public:
    virtual void f() = 0;
    };

    class B : public A
    {

    };

    class C : public B
    {
    virtual void f() {cout << "f()" << endl;}
    }

    In C#, it seems this is not allowed by design (unless I'm missing
    something obvious, which it certainly wouldn't be the first time). My
    question is why? It seems to force you to implement all methods at the
    very next level of inheritance. In the above example, C# compiler
    would have forced me to implement the method f() in class B.

    This method seems very inconvenient, however. For example, there are
    plenty of pre-existing interfaces in the .NET base classes that provide
    various services. What if you want a particular set of classes to all
    provide this service? Normally, in C++, I would have made a base class
    called like BaseServiceClas s, which implemented this interface. Then
    in the derived classes I would provide the implementation, and
    elsewhere in my code I would store pointers to BaseServiceClas s
    objects, all of which could be used to call the method in question.
    What is the paradigm for solving this kind of design problem in the C#
    / .NET world?

    Thanks

  • Michael Bray

    #2
    Re: interface implementation question

    I think you might be confusing "interfaces " with "inheritanc e". Interfaces
    will indeed force you to provide an implementation on the class for which
    it is defined - otherwise what would be the point of the interface?

    The example you give works just fine in C# as well if you are talking about
    "inheritanc e". In fact, the example you give isn't "interface" at all in
    the strict sense of the word - it is in fact inheritance. Also, to avoid
    warnings, you would need the 'override' keyword on the f() in the class C.

    public class A
    {
    public virtual void f() { }
    }

    public class B : A
    {
    }

    public class C : B
    {
    public override void f()
    {
    Console.WriteLi ne("f()");
    }
    }

    -mdb

    "Zach" <divisortheory@ gmail.com> wrote in news:1137427435 .828656.194550
    @g43g2000cwa.go oglegroups.com:
    [color=blue]
    > Hi everyone,
    >
    > I'm a bit of a newbie to C# programming so forgive this innocent
    > question, but coming from a C++ background this seems very odd to me,
    > and I'm hoping someone can shed some light onto why things work this
    > way as opposed to the C++ way, which I see no real disadvantages in.[/color]

    Comment

    • Jon Skeet [C# MVP]

      #3
      Re: interface implementation question

      Zach wrote:[color=blue]
      > I'm a bit of a newbie to C# programming so forgive this innocent
      > question, but coming from a C++ background this seems very odd to me,
      > and I'm hoping someone can shed some light onto why things work this
      > way as opposed to the C++ way, which I see no real disadvantages in.
      >
      > The issue arises when trying to implement an interface in C#. In C++
      > it is quite common to define an interface using a bunch fo pure virtual
      > functions and then implement it 2 or 3 levels up in the hierarchy. For
      > example,
      >
      > class A
      > {
      > public:
      > virtual void f() = 0;
      > };
      >
      > class B : public A
      > {
      >
      > };
      >
      > class C : public B
      > {
      > virtual void f() {cout << "f()" << endl;}
      > }
      >
      > In C#, it seems this is not allowed by design (unless I'm missing
      > something obvious, which it certainly wouldn't be the first time).[/color]

      The above in C# would be:

      public abstract class A
      {
      public abstract void F();
      }

      public abstract class B : A
      {
      }

      public class C : B
      {
      public override void F()
      {
      Console.WriteLi ne ("F()");
      }
      }

      B and A cannot be instantiated directly, as they don't provide
      implementations for all the methods which could be called. Use the
      modifier "abstract" to indicate that a method has to be overridden, or
      to indicate that a class must be derived from.

      Does that answer your question?

      Jon

      Comment

      • Zach

        #4
        Re: interface implementation question

        I understand the difference between the two, the thing is that in C++
        there is no difference: Implementation -is- inheritance. So when
        moving to C# it is more strict about what you can and can't do since it
        distinguishes between the two.

        The problem, however, is that there are interfaces that are already in
        existance in the .NET base class libraries. They are defined using the
        keyword "interface" . A good example is ISerializable. At some point,
        I may want 50 related classes to be serializable. It would seem
        logical that, rather than directly implementing ISerializable on each
        of the 50 classes, I would implement it on a base class, but let the
        derived classes override the GetObjectData() method, rather than the
        base class (since it can't possibly know how derived classes need to
        serialize themselves). This would naturally lead to the base class not
        being instantiatable, which is fine.

        Sure if I'm writing all the code myself I can make my class abstract
        instead of making it an interface, but a lot of times I'm using an
        interface that already exists somewhere (be it in the .NET framework,
        or in some 3rd party code), and use of the other code requires that I
        implement the correct interface rather than using an abstract class
        (for example, because a method specifically requests an interface as a
        parameter).

        For example, following doesn't compile in C#, although I would like it
        to.

        class A : ISerializable
        {
        }

        class B : A
        {
        public void GetObjectData(S erializationInf o info, StreamingContex t
        context)
        {
        //Serialize the class here.
        }
        }

        Instead, I have to do something like this to achieve a similar result:

        abstract class A : ISerializable
        {
        protected abstract void GetObjectDataIm pl(Serializatio nInfo info,
        StreamingContex t context);

        public void GetObjectData(S erializationInf o info, StreamingContex t
        context)
        {
        GetObjectDataIm pl(info, context);
        }
        }

        class B : A
        {
        protected override void GetObjectDataIm pl(Serializatio nInfo info,
        StreamingContex t context)
        {
        //Serialize the class here
        }
        }

        So I guess my real question is, is there a more elegant way of doing
        this, or is this really what I have to do? And what is the reasoning
        behind the designers decision to force interface implementations to
        happen at the very next level in the hierarchy, rather than simply
        making the class uninstantiatabl e until such level in the hierarchy
        where all the interface methods, properties, etc have been provided an
        implementation?

        Comment

        • Zach

          #5
          Re: interface implementation question

          Wait! I've seen the light. Apparently the following code works just
          fine:

          abstract class A : ISerializable
          {
          public abstract void GetObjectData(S erializationInf o info,
          StreamingContex t context);
          }

          class B : A
          {
          public override void GetObjectData(S erializationInf o info,
          StreamingContex t context)
          {
          //Serialize the class here
          }
          }

          It just didn't occur to me that I might be able to add the keyword
          'abstract' at the base class level, and then just leave it
          unimplemented.

          Comment

          • James Curran

            #6
            Re: interface implementation question

            "Zach" <divisortheory@ gmail.com> wrote in message
            news:1137431047 .357381.135580@ g47g2000cwa.goo glegroups.com.. .[color=blue]
            > It just didn't occur to me that I might be able to add the keyword
            > 'abstract' at the base class level, and then just leave it
            > unimplemented.
            >[/color]
            "abstract" is just one of many keywords/syntax rules of C#, which take
            concepts which, in C++ are put in comments(*), and actually puts them in the
            C# code where (EGADS!), the compiler might actual verify them.


            (*) It could happen....
            --
            Truth,
            James Curran
            [erstwhile VC++ MVP]

            Home: www.noveltheory.com Work: www.njtheater.com
            Blog: www.honestillusion.com Day Job: www.partsearch.com


            Comment

            • Zach

              #7
              Re: interface implementation question

              Yea, it's nice having the compiler check more things for you. Still
              though, it seems that educational materials focus so much on drilling
              into your head that "abstract classes" and "interfaces " are completely
              different ("you use -either- an abstract class or an interface") that
              it clouds the real issue. For me, it made me assume that doing things
              the way I finally got it to work would generate a compiler error, since
              the solution to the problem involved using an abstract class -and- an
              interface.

              Comment

              Working...