tags:

views:

360

answers:

9

Is it possible in C# to have a class that implement an interface that has 10 methods declared but implementing only 5 methods i.e defining only 5 methods of that interface??? Actually I have an interface that is implemented by 3 class and not all the methods are used by all the class so if I could exclude any method???

I have a need for this. It might sound as a bad design but it's not hopefully. The thing is I have a collection of User Controls that needs to have common property and based on that only I am displaying them at run time. As it's dynamic I need to manage them for that I'm having Properties. Some Properties are needed by few class and not by all. And as the control increases this Properties might be increasing so as needed by one control I need to have in all without any use. just the dummy methods. For the same I thought if there is a way to avoid those methods in rest of the class it would be great. It sounds that there is no way other than having either the abstract class or dummy functions :-(

+2  A: 

You can make it an abstract class and add the methods you don't want to implement as abstract methods.

In other words:

public interface IMyInterface
{
    void SomeMethod();
    void SomeOtherMethod();
}

public abstract class MyClass : IMyInterface
{
    // Really implementing this
    public void SomeMethod()
    {
        // ...
    }

    // Derived class must implement this
    public abstract void SomeOtherMethod();
}

If these classes all need to be concrete, not abstract, then you'll have to throw a NotImplementedException/NotSupportedException from inside the methods. But a much better idea would be to split up the interface so that implementing classes don't have to do this.

Keep in mind that classes can implement multiple interfaces, so if some classes have some of the functionality but not all, then you want to have more granular interfaces:

public interface IFoo
{
    void FooMethod();
}

public interface IBar()
{
    void BarMethod();
}

public class SmallClass : IFoo
{
    public void FooMethod() { ... }
}

public class BigClass : IFoo, IBar
{
    public void FooMethod() { ... }
    public void BarMethod() { ... }
}

This is probably the design you really should have.

Aaronaught
I think this is correct answer to the wrong question. I think that real issue is bad design of interface. If some methods of interface might be not implemented by some classes, it means that you need more than one interface. And classes will implement only those interfaces that are necessary for them
iPhone beginner
FWIW I'd say SomeMethod should be virtual.
Chris Marisic
iPhone: Not necessarily. The ICollection<> interface defines the Add and Remove methods, but it is common to not implement them for read-only collections. But yeah, in general I have to agree with you.
Brian Gideon
@Chris: If it's `virtual` then it has to have a body; that's equivalent to implementing the method, but having it do nothing. I'm not sure if that's the behaviour the OP wants, especially if these methods have to return a value.
Aaronaught
@Brian Actually my opinion is that this is bad design of `ICollection`. Usually you can't change "is collection read only" flag. So (again in my opinion) it doesn't make sense to have such methods in read only collection. Personally I prefer design in which hypothetic `IMutableCollection` interface extends `IReadOnlyCollection` but this is not how it is done in the .Net world. In this aspect objective-c Cocoa world is closer to my ideal.
iPhone beginner
@iPhone beginner: Be that as it may, there are legitimate uses of "not supported" methods. For example, a `NetworkStream` doesn't support the `Seek` method; would it really have made sense to break the `Stream` abstraction (which, most of the time, does support seeking) just to be able to exclude this method from the `NetworkStream`? What you're saying has merit, but it's not black-and-white; in this case it sounds like the OP doesn't have a great design, but the truth is none of us know much about the design or the decisions that went into it.
Aaronaught
@Aaronaught your SomeMethod DOES implement a body, but can't be overridden now by any inheritors of the abstract class.
Chris Marisic
@Chris: Right, my mistake, I thought you were referring to the abstract method. It's kind of a moot point since we're talking about an entirely fictional class hierarchy with undefined functionality - you can make it `virtual` if you like. :P
Aaronaught
@Aaronaught I think both you examples are better for developers who develop code, but are worse for developers who use the code. This is a trade off between simplicity of code and simplicity of other code that uses it. For example, such design means that any method that has such interface (class) as parameter might throw unexpected exception that should be handled somewhere. Or at least caller has to remember if his particular object can be safely passed to method. That's why I think that in **standard libraries** this **is** bad design. It saves efforts of a few in exchange to efforts of many
iPhone beginner
@iPhone beginner: Oh, do tell. How would you have implemented the `Stream` hierarchy instead? If I have a `Stream` and I need to `Seek` on it one way or another, which is better, to just attempt the seek and have it throw a `NotSupportedException`, or to explicitly check for an `ISeekableStream` implementation in 72 different places and then... throw an exception if it's not supported? Framework classes are supposed to *reduce* the amount of code you need to write. `NotSupportedException` is well-documented and easy to stick in a `try-catch` block if you need to handle the possibility.
Aaronaught
@Aaronaught of course we'd make it virtual, I was raising the point for the OP and future SO readers since this question is more of a fundamental OOD question relevant to C#. And having non abstract, non virtual methods in an abstract class imposes serious future design decisions since it can never be overridden.
Chris Marisic
@Chris: Sure, I hear you, it's an important decision - that doesn't mean it's a wrong one. There are plenty of good reasons to have non-virtual methods in an abstract class; it's simply a question of what your invariants are. Look at `MarshalByRefObject.GetLifetimeService` and `WebRequest.ImpersonationLevel` for two examples - both concrete methods of abstract classes that would make no sense to override.
Aaronaught
@Aaronaught, why do you need `ISeekableStream`? Just make abstract `SeekableStream` class that is subclass of `Stream`. And actual implementations would inherit one of base classes depending of supported features. Now if method has argument of `SeekableStream` type, the method knows that it is 100% safe to call `Seek`. No additional code is required to check it. On the other hand, caller is also in safer position. You *can't* pass non-seekable `Stream` to a method that (unexpectedly to you) calls `Seek` method and thus will not have unexpected exception.
iPhone beginner
@iPhone beginner: Great, that works for *one* characteristic of streams. Now what about the read/write characteristics of streams? Shall we have a `ReadableSeekableStream` and a `WritableSeekableStream`? And the same for non-seekable streams? What about streams that support both reading and writing? How would you handle this multiple-inheritance combinatorial explosion dilemma? Everything's easy if you're willing to settle for solving only 1/10th of the problem; Framework designers have to consider all possible use cases.
Aaronaught
@Aaronaught Yes, `ReadableSeekableStream` is **exactly** what I'd like to have in base library. If I have a stream object, I'd like to know what I can do, and what I can't without additional checks and exceptions. I agree that this means more work for a few core developers, but this saves time for us, usual developers. IMHO, for `Stream` case there is no need of multiple-inheritance as there is no default implementations for main methods of different features anyway. So this might be done with multiple interfaces inheritance and some delegation. However, I agree that this is a matter of taste.
iPhone beginner
+1  A: 

You can simply have the methods you don't want to impliment trow a 'NotImplementedException'. That way you can still impliment the interface as normal.

UpTheCreek
I cannot use 'NotImplementedException' as the exception will be thrown to my code which don't know this and it's against my requirement so:-(
Jankhana
In that case I second PoweRoy's answer
UpTheCreek
+2  A: 

That is not possible. But what you can do is throw NotSupportedException or NotImplementedException for the methods you do not want to implement. Or you could use an abstract class instead of an interface. That way you could provide a default implementation for methods you choose not to override.

public interface IMyInterface
{
  void Foo();

  void Bar();
}

public class MyClass : IMyInterface
{
  public void Foo()
  {
    Console.WriteLine("Foo");
  }

  public void Bar()
  {
    throw new NotSupportedException();
  }
}

Or...

public abstract class MyBaseClass
{
  public virtual void Foo()
  {
    Console.WriteLine("MyBaseClass.Foo");
  }

  public virtual void Bar()
  {
    throw new NotImplementedException();
  }
}

public class MyClass : MyBaseClass
{
  public override void Foo()
  {
    Console.WriteLine("MyClass.Foo");
  }
}
Brian Gideon
Also, if you don't want the not implemented methods to be visible on Intellisense you can explicitly implement them. For example:public class MyClass : IMyInterface{... public void IMyInterface.MyNotImplementedMethod() { throw new NotImplementedException(); }}this way if you have a variable of type MyClass, the explicitly implemented methods won't be displayed on Intellisense.
Anero
Hmmm that means MyInterface.MyNotImplementedMethod() will be visible???
Jankhana
Yes, explicitly implemented methods will not be visible if you have object as reference to such class. If you have it as reference to the interface, they, of course, will be visible.
iPhone beginner
Thats great will use that if I go for abstract class concept. Thanks
Jankhana
@Anero: Good call on the explicit interface implementation idea.
Brian Gideon
A: 

Let your Interface be implemented in an abstract class. The abstract class will implement 5 methods and keep remaining methods as virtual. All your 3 classes then should inherit from the abstract class. This was your client-code that uses 3 classes won't have to change.

this. __curious_geek
+12  A: 

Your breaking the use of interfaces. You should have for each common behaviour a seperate interface.

PoweRoy
+1  A: 

No, it isn't. You have to define all methods of the interface, but you are allowed to define them as abstract and leave the implementation to any derived class. You can't compile a class that says that implements an interface when in fact it doesn't.

Otávio Décio
+1  A: 

While I agree with @PoweRoy, you probably need to break your interface up into smaller parts you can probably use explicit interfaces to provider a cleaner public API to your interface implementations.

Eg:

public interface IPet
{
   void Scratch();
   void Bark();
   void Meow();
}

public class Cat : IPet
{
    public void Scratch()
    {
        Console.WriteLine("Wreck furniture!");
    }

    public void Meow()
    {
       Console.WriteLine("Mew mew mew!");
    }

    void IPet.Bark()
    {
        throw NotSupportedException("Cats don't bark!");
    }
}

public class Dog : IPet
{
    public void Scratch()
    {
        Console.WriteLine("Wreck furniture!");
    }

    void IPet.Meow()
    {
       throw new NotSupportedException("Dogs don't meow!");
    }

    public void Bark()
    {
        Console.WriteLine("Woof! Woof!");
    }
}

With the classes defined above:

var cat = new Cat();
cat.Scrach();
cat.Meow();
cat.Bark(); // Does not compile


var dog = new Dog();
dog.Scratch();
dog.Bark();
dog.Meow(); // Does not compile.


IPet pet = new Dog();
pet.Scratch();
pet.Bark();
pet.Meow(); // Compiles but throws a NotSupportedException at runtime.

// Note that the following also compiles but will
// throw NotSupportedException at runtime.
((IPet)cat).Bark();
((IPet)dog).Meow();
orj
Thats very apt example as Cow cannot bark and dog cannot meow but still i cannot segregate the interface hmmm:-(
Jankhana
A: 

I want to add dynamically the control to my form as I have that as my requirement. I found the code from here. I edited it as I needed. So I have the IService class that has the common properties. This is implemented by the User Controls. Which are shown at runtime in different project. Hmmm for that I have different common interface that has properties which are used by the project for displaying the controls. Few controls need some extra methods or peoperties for instance to implement a context menu based on user selection at runtime. i.e the values are there in the project which will be passed as the properties to the control and it will be displayed. Now this menu is there only for one control rest of them don't have this. So I thought if there is a way to not to have those methods in all class rather than one class. But it sounds that I need to either go for dummy methods or abstract class. hmmm dummy methods would be more preferable to me than the abstract class :-(

Jankhana
+1  A: 

Here is a simple stupid example of what I meant by different interfaces for different purposes. There is no interface for common properties as it would complicate example. Also this code lacks of many other good stuff (like suspend layout) to make it more clear. I haven't tried to compile this code so there might be a lot of typos but I hope that idea is clear.

interface IConfigurableVisibilityControl
{
    //check box that controls whether current control is visible
    CheckBox VisibleCheckBox {get;}
}


class MySuperDuperUserControl : UserControl, IConfigurableVisibilityControl
{
    private readonly CheckBox _visibleCheckBox = new CheckBox();

    public CheckBox VisibleCheckBox 
    {
        get { return _visibleCheckBox; }
    }
    //other important stuff
}

//somewhere else
void BuildSomeUi(Form f, ICollection<UserControl> controls)
{
    //Add "configuration" controls to special panel somewhere on the form
    Panel configurationPanel = new Panel();
    Panel mainPanel = new Panel();
    //do some other lay out stuff
    f.Add(configurationPanel);
    f.Add(mainPanel);

    foreach(UserControl c in controls) 
    {
        //check whether control is configurable
        IConfigurableOptionalControl configurableControl = c as IConfigurableVisibilityControl;
        if(null != configurableControl) 
        {
            CheckBox visibleConfigCB = configurableControl.VisibleCheckBox;
            //do some other lay out stuff
            configurationPanel.Add(visibleConfigCB);
        }
        //do some other lay out stuff
        mainPanel.Add(c);
    }
}
iPhone beginner
I will try to use this. thanks. So it's concluded that I need to have either the dummy methods or the abstract class with virtual functions. I would prefer to go with dummy methods than having an abstract class. Thanks for all your reponse. I learned many new things.
Jankhana
No, doing this way you don't have to have dummy methods. You need several different interface. You might add another interface(s) for different feature(s) and check it(them) in the same way. Each your control would implement only those interfaces that are required by the control.
iPhone beginner