6

Don't know how to put it, But I'll try to be as clear as possible

I have a project in which I am creating lots of classes and those classes have some common properties and methods but those methods could have different code in them,

So I decided to make an interface so that I could inherit that in all classes and all classes would have same methods in them like insert, update, delete with different code inside those those methods but this trick flopped when I discovered that not all classes have same structure like some have insert method but not update and if I inherit interface I have to provide a public declaration for all members of that interface which I don't want.

Trick two I thought about abstract classes created one too but same problem all the abstract members has to be implemented with public.

So long story short

I want to create a common inheritable structure which would work as a non instance-able blue print for classes and could be inherited into lots of classes but in many classes I don't want to implement all of the members of that structure

NOTE : I can do no-op(empty methods that do nothing, or return a null, for example) as some guys suggested me but that ain't the solution I am looking for because those unnecessary members will be visible during intellisence and that's what i want to avoid.

How can I do that ?

2
  • 3
    I don't think you need some kind of common inheritable structure. It should be obvious what interfaces you need from how you use those classes. And from what you say, you use those classes directly, so there is no need for some common interface.
    – Euphoric
    Commented Aug 15, 2012 at 18:17
  • What's intellisence? Do you mean IntelliSense - Microsoft's autocompletion software? I don't think designing your code around the capabilites of your IDE is a particularly good idea.
    – James
    Commented Aug 15, 2012 at 19:54

6 Answers 6

7

One way to do this is have one interface with the three methods, and implement it in a few abstract classes (these would be the base classes for the full implementations).

These abstract classes would only implement methods that are not needed and would implement them as no-ops (empty methods that do nothing, or return a null, for example).

Your actual implementation classes would inherit from these abstract classes and only implement the needed subset of operations.


Another option is to adhere to ISP (Interface Segregation Principle) and have a number of interfaces - one for each behaviour needed.

Update:

This second option would suit the requirement to not have certain methods show up in IntelliSense. It does, however, mean that you would not be able to use a single inheritance tree, but segregate it (which, from your description of the model, is probably the correct solution).

3
  • I can do that no-op thing with one interface too I guess, Just create one interface and inherit it and no-op unnecessary members, But sorry that ain't the solution I am looking for because those unnecessary members will be visible during intellisence and that's what i want to avoid.
    – yogi
    Commented Aug 15, 2012 at 18:17
  • @yogi - That's the kind of detail you want to mention in your question.
    – Oded
    Commented Aug 15, 2012 at 18:19
  • Sorry for that I'll edit it right away.
    – yogi
    Commented Aug 15, 2012 at 18:20
11

The simple answer is to just create multiple interfaces: Insertable, Updateable, Deleteable, etc. However, keep in mind that just because classes have similar methods doesn't mean they need to share an inheritance structure. You only want to use inheritance when you need to reuse the code that calls it, like if you need a container that holds a bunch of different objects of different types, and you need to call insert() on everything in that container.

0

What you talk about is polymorphism, which literally means having many shapes.

For example, you might have a base class called Animal, which has a method called Eat(Food food);. Then you might have three classes inheriting from Animal like Dog, Cat, and Hen.

All of these subclasses should have Eat method (by overriding the member of the base class), but each can have its own implementation (doing something differently).

This can be achieved using inheritance by either inheriting from a superclass (base class), or by implementing one or many interfaces (as @Oded said, many small interfaces instead of one big interface).

Another option that comes to my mind is to implementing mixin in C#, but I'm not a pro at it. Just a clue ;).

0

In .net, if an interface inherits other interfaces, a class which implements the constituent interfaces can be made to be regarded as in implementation of the combined interface simply by declaring it as one, without requiring any extra coding effort. It could thus be more convenient to have IThis, IThat, and IThisOrThat interfaces than to have one unified "does everything" interface, since classes that can only handle one of the interfaces need not implement stubs for the interface methods they can't handle. Further, code which needs objects to handle both interfaces at compile time can demand such objects by accepting a parameter of type IThisOrThat.

There are a few limitations with this approach, though:

  1. While it can allow for type-safe code without typecasting, there isn't any remotely-nice way to specify that a collection holds objects which implement multiple interfaces (e.g. {IThis,IThat}) unless all of the types one wishes to use implement a composite interface that includes all the interfaces one needs. Generics can help a lot with parameters and local variables, but can be less useful with mixed-type collections.
  2. Code may hold objects not just for itself, but also for the purpose of giving them to other code. Code might accept an object which is required to implement `IThis`, and a delegate which is expected to accept the passed-in object. If the parameter type of the passed-in object is `IThis`, the code won't be able to pass it to a delegate that expects an `IThisOrThat`, even if the passed-in instance in fact implements the latter interface. Using generics can help here, but they don't always make things totally smooth.
  3. Sometimes code may have instances whose exact capabilities might vary; in some cases, instances might include methods to produce more capable instances. For example, an immutable class might have an `AsMutable` function which would return a mutable class instance initialized with data from the immutable one. It may be more helpful to have fields of type `IMaybeMutableFoo`, which is implemented by both the mutable and immutable classes and includes both "getter" and "setter" methods, than to have the fields of type `IReadableFoo` which includes a getter but no setter and require a typecast any time one wishes to write to the field even after one has tested that the field holds a mutable object.

I like the composite-interface approach, but having semi-composite interfaces (which implement other interfaces, but are not guaranteed to do so usefully) can be useful as well.

0

The problem is all your classes have to look alike, because the program using them doesn't know (and doesn't really want to know) which is which. No-op methods can be a good solution to this problem, but they do have to make sense. If the calling program calls one, it should not be inconvenienced when it does nothing.

The next step is to have methods that return capabilities, so you don't call methods that a particular object cannot handle. If CanFly returns false, the caller knows not to call FlyToLA. This, of course, leaves you with a lot of no-op methods that should never be called--a messy situation at best.

The solution, I think, is to have all your classes/interfaces have a GetFlight method that returns a Flight instance ("Flight" can be a class or interface--interface might work best). If that method returns null, the object doesn't fly. If it returns a Flight object, that object contains all the methods concerned with flight, so they are there and available if applicable and nonexistent and unusable if not.

And you'd have other methods, perhaps rather a lot, such as GetDrive, GetAccounting, GetPersonell, etc. You might even nest them, with the Accounting interface having lot's more "Get" methods for subsets of accounting. There's a lot of variations on this theme.

-1

For the mixin option in C#, then I would recommend using the separation of concerns approach by defining multiple interfaces. If you want to handle the objects in a single collection then simple have a base interface (such as IEntity) which only has 100% common attributes (or none if there are none). You can as "myObj as IMyInterface" and check for null to see if something is supported, and to add methods onto the interfaces you can use extensions methods. Interfaces + Extension methods is a the C# way to achieve mix-ins, and allows you to define methods that act over the properties defined in your interface ... if you need these to form part of your interface then simply have an IEntityWithMethods interface that your child implementation inherits and map this to the extension methods explicitly.

1
  • this post is rather hard to read (wall of text). Would you mind editing it into a better shape?
    – gnat
    Commented Sep 20, 2016 at 15:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.