I'm trying to combine the functions of two different base classes into a new class, to no avail. Say I have class A and B, whereas B is a descendant of A with different functionality (i.e. can't be used as a substitute for A during runtime) and need a class C, which combines A and B, uses both and provides a unique interface to users of C. How can I achieve this? Multiple inheritance isn't possible with C#, interfaces don't seem to fit. So what can I do?
Your design is broken.
B is a descendant of A with different functionality (i.e. can't be used as a substitute for A during runtime)
That situation is a mis-use of inheritance. If you want to do that, you should either use composition or a common interface that both A & B implement separately instead.
Consider explicit interface implementation:
http://msdn.microsoft.com/en-us/library/ms173157.aspx
public interface IFriendly
{
void Greet();
}
public interface IEnemy
{
void Greet();
}
public class SomeGuy : IFriendly, IEnemy
{
//default Greeting
public void Greet()
{
//...
}
//greeting when using an IFriendly reference
void IFriendly.Greet()
{
//,,
}
//greeting when using an IEnemy reference
void IEnemy.Greet()
{
//,,
}
}
You say that B descends from A but is different and cannot be used as an A; this defies the purpose of inheritance altogether. What are you trying to achieve? Regardless, it sounds as though you should be using composition, not inheritance. If C does not expose the interface defined by A or B, then it should not inherit from either.
The fact that you need to consider such an action makes me think that you might need to consider refactoring your class structure.
But, to solve your immediate problem why not instantiate the two classes (ignore the fact that they are in an inheritance relationship) and call the methods in the sequence you need? Think of C as a facade pattern for A and B.
Problem solved. Using System.Reflection now.
Related
Assume this hypothetical situation:
I have a hierarchy of classes:
public class MyBase : System.Windows.Forms.TreeNode
{
public virtual void Init() {...}
}
Now I want to allow third parties to use MyBase to develop their derived classes like these:
public class Drv1 : MyBase { public override void Init() {...} }
public class Drv2 : MyBase { public override void Init() {...} }
I want my application be able to use Drv1 and Drv2 as plug-ins.
Now, my questions are:
Is it incorrect (or bad practice) to use classes (instead of interfaces) to set up plug-in mechanism?
Did I make a mistake I didn't use interfaces to provide THIRD-PARTIES with an interface? (because I want to persuade others to develop plug-ins for my app)
If answer of question 2 is YES, how could I use interfaces (because MyBase is derived from TreeNode) ? (this answer is critical for me)
Many thanks in advance.
Im using following rules:
If there is any code required in base then go for class.
If you need only structure or you need to "inherit" more than one class, use interfaces.
If you need both, features and multiple inheritance use both.
Its really depends what you do with that classes later on.
In your case you should be using base class as virtual method has some code in it, and you inherit from class that is 3rd party for you.
But once your business classes should use different implementation of that class then its worth of adding interfaces and use it in IoC or something.
I think going for Interfaces for only sake of it is not correct approach.
Is it incorrect (or bad practice) to use classes (instead of interfaces) to set up plug-in mechanism?
Neither C# or .NET has anything that labels this as incorrect. They describe under what circumstances your code will continue to work, and when it won't. Bad practice is a matter of opinion, but there are advantages and disadvantages to both approaches.
If answer of question 2 is YES, how could I use interfaces (because MyBase is derived from TreeNode) ? (this answer is critical for me)
If your callers need to provide a type that is derived from TreeNode, and you wish to use an interface, then you can.
public interface IMyInterface {
void Init() {...}
}
You cannot require classes implementing IMyInterface to derive from TreeNode, but you do not need to: you can ensure that the only way this gets exposed to your own application is via a generic registration method, where the generic type constraints do force the type to both derive from TreeNode and implement this interface:
public void RegisterTreeNode<T>() where T : TreeNode, IMyInterface {...}
If plugins are able to call RegisterTreeNode<Drv1>(), you're assured at compile time that it's going to match your requirements. You may of course use a different method signature, possibly one that deals with individual instances of the TreeNode class, it's the type constraints that are key here. If a caller attempts
class X : IMyInterface { public void Init() {...} }
and then
RegisterTreeNode<X>();
the compiler will simply reject this. The plugin may create instances of this X itself, but if your application never sees them, they cannot cause any harm.
Then third parties can do:
public class Drv1 : TreeNode, IMyInterface { ... }
public class Drv2 : TreeNode, IMyInterface { ... }
or even
public class Drv3 : SuperTreeNode, IMyInterface { ... }
where SuperTreeNode is derived from the standard TreeNode.
This is probably the main benefit of using an interface here: it's compatible with existing classes which provide additional functionality on top of the standard TreeNode.
This cuts both ways: the main benefit of using a common base class here, rather than an interface, would be that your own code can provide additional functionality.
P.S.: Depending on what you're after, it may also be possible to decouple this, to make your base class / interface responsible for creating TreeNode objects, rather than deriving from TreeNode. The general rule that favours this approach is called "composition over inheritance", and worth reading up on. It may or may not be a good fit for your particular use case.
I asked this question yesterday, but I think it was unclear what my primary concern was. In C++, we have private and multiple inheritance, which enables us to add private methods to classes by just inheriting from the class declaring these methods. That is, if there's a class
class B {
public:
virtual void doMethodB();
};
and a class
class A : private B {
virtual int doMethodA();
};
doMethodB() can be called from within doMethodA(), but is not accessible from outside.
Now, I'd like to mimic this behavior in C#. There is no multiple nor private inheritance. Up to know, I can think of four way to achieve somthing similar, but still with serious drawbacks:
First: Use an interface, i.e.
interface IB {
public void doMethodB();
};
class A : IB {
public void doMethodB();
int doMethodA();
};
However, when we do this, doMethodB() is public, and must be implemented in each class inheriting from IB.
Second: Use a static method
public static class B {
public static void doMethodB();
};
That way, there need only be one implementation, but the method is still public and can't be restricted to certain classes.
Third: Use a extension method, like that. That way however, the method is called on the object (i.e. a.doMethodB()) and not from "inside".
Fourth: Composition.
class A {
private B b;
public int doMethodA();
};
Now, B's methods can be called like b.doMethodB() from A only, but are other issues now regarding serialization, b == null etc.
Is there another alternative? And if not, which one among the presented ones would you consider "the best"?
Regarding your "First" proposal with interfaces: you can also implement the interface explicitly:
"A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface. "
See / Source: http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx
However, i would choose the Composition approach. "Favor Composition over Inheritance", also see Prefer composition over inheritance?
Ideally, i would constructor-inject B into A by dependency injection, that should help mitigate your b == null concern.
Note:
Using a static method / extension method (is a static method, too...) makes unit-testing A (respectively faking B) very hard, which is why i would forgo these solutions completely.
Edit:
If you don't need B.doMethodB accessible from anyone else than A, you can also make B an abstract class and B.doMethodB a protected method.
But i was thinking that you already know that ;-)
(And because of the testing issues i would still favor composition over inheritance).
I think the concept you are looking for is the protected access modifier. It means that only B itself and its derived classes can access the method, but others cannot.
class B {
protected virtual void DoMethodB() {}
}
class A : B {
virtual void DoMethodA() {
DoMethodB();
}
}
If you wanted, you can further restrict the access to protected internal which means that the method can only be accessed from derived classes inside your assembly.
Also, be aware of the consequences of virtual methods. If there is no explicit need to make a method virtual, it should not be marked virtual.
C#, VS 2008
I have 4 cases say a,b,c,d, I plan to seperate them and create seperate classes
the 4 cases have something in common, I put them in an interface and create a base class that implement the interface. now there are something in common between a&b, a&c, c&d, not sure how to make a good/clean implement
thanks
There are several options.
You could have c and d inherit from a, and d inherit from c.
You could create a base class for each pair a/b, a/c, and c/d.
You could duplicate functionality.
You could provide the functionality via a helper class (static methods might be an option).
It really depends on what functionality is being shared, and the intended usage of the classes.
It depends on how the common things works and how they relate to and use private/protected data, but often composition can be a complement or alternative to inheritance.
Break out the common parts to helper classes that you use from the different implementations of a,b,c and d.
This is only possible if the implementation is not tightly coupled to the private data of each class.
As a general rule, you should only use inheritance if your objects are different kinds of the same object. If this is the case, then you can use inheritance to share implementation that's inherent in the definition of the base object.
If classes a,b,c and d aren't really different kinds of the same object then you can try encapsulating their common functionality in an internally referenced object.
public class a
{
private CommonFunctionalityClass commonFunc;
public a()
{
this.commonFunc = new CommonFunctionalityClass();
}
}
When you want to do the common stuff, you just call your instance of commonFunc. You can do this same encapsulation for a/b, b/c, and c/d where you share functionality via a has a relationship using an internally referenced object. That way you don't duplicate code, but you can share functionality flexibly.
public interface IABInterface
{
//Whatever is common to A and B. It will have to be implemented in the classes
}
public interface IACInterface
{
//Whatever is common to A and C. It will have to be implemented in the classes
}
public interface ICDInterface
{
//Whatever is common to C and D. It will have to be implemented in the classes
}
public class ABCDBase
{
//Whatever is common to all classes
}
public class A : ABCDBase, IABInterface, IACInterface
{
}
public class B : ABCDBase, IABInterface
{
}
public class C : ABCDBase, IACInterface, ICDInterface
{
}
public class D : ABCDBase, ICDInterface
{
}
You can create later in a static class extension methods for your interfaces to not duplicate the code for your methods in the Interfaces implementations (In other words, don't define methods in your interfaces, only properties). With refactoring can be really easy to implement the properties in your interfaces.
It would be nice to have extension properties. Hopefuly in the future.
EDIT
Like this:
public static class Helper
{
public static void IABMethod1(this IABInterface aOrBObject, arguments args)
{
//This will be available for any A or B object without duplicating any code
}
}
I have two classes that implement ISomeBehavior. Now I want them to share functionality. Normally I would replace ISomeBehavior with an abstract class, like SomeBehaviorBase. The problem is that one of the subclasses already derives from another class, and that other class isn’t software we own. (This is C#, so multiple inheritance isn't an option.) The subclass, that derives from the 3rd party class, has no implementation. It simply derives from the 3rd party class, and implements ISomeBehavior, so the 3rd party class can be treated the same way as the other subclasses that implement ISomeBehavior.
What I've done, for the moment, is implement an extension method on ISomeBehavior. Now the consuming code can call the method. The problem with that approach is that I want to force the calling code to use this extension method. I can't remove SomeMethod() from the interface, because the extension method has to eventually call it.
Any ideas on how to let two classes elegantly share the same behavior, when one of them already derives from another, third party, class? Note: The strategy design pattern sounds like it makes sense here, but that pattern is used when behavior varies among subclasses. The behavior here doesn't vary; it just needs to be shared.
Is there any reason you can't use composition instead of delegation to implement the class which currently derives from the 3rd party class? Just delegate all the interface methods to an instance of the third party class. That way, if you want to add functionality you can use a common base class.
This won't work in some cases where the object identity is relevant, but in many cases it's a perfectly reasonable design.
public interface ISomeBehavior
{
int Sample();
}
public class A : ISomeBehavior
{
int ISomeBehavior.Sample()
{
return 1;
}
}
static class SomeExtension
{
public static int Sample(this ISomeBehavior obj)
{
return 2;
}
}
and then use this
A a = new A();
var a1 = ((ISomeBehavior)a).Sample(); // a1 = 1
var a2 = a.Sample(); // a2 = 2
How about something like this:
class MyClass: ThirdPartyClass
{
}
class MyFunctionality
{
public MyFunctionality(ThirdPartyClass target)
...
}
interface IMyFunctionality
{
public MyFunctionality MyFunctionality;
}
So the interface would enforce that the derived class has to instantiate the add-on member, and the design of MyFunctionality would just operate against a reference to the base class. This might not work if there are protected members that you need internal access to, though.
I am new to C#. Recently I have read an article.It suggests
"One of the practical uses of interface is, when an interface reference is created that can
work on different kinds of objects which implements that interface."
Base on that I tested (I am not sure my understanding is correct)
namespace InterfaceExample
{
public interface IRide
{
void Ride();
}
abstract class Animal
{
private string _classification;
public string Classification
{
set { _classification = value;}
get { return _classification;}
}
public Animal(){}
public Animal(string _classification)
{
this._classification = _classification;
}
}
class Elephant:Animal,IRide
{
public Elephant(){}
public Elephant(string _majorClass):base(_majorClass)
{
}
public void Ride()
{
Console.WriteLine("Elephant can ride 34KPM");
}
}
class Horse:Animal,IRide
{
public Horse(){}
public Horse(string _majorClass):base(_majorClass)
{
}
public void Ride()
{
Console.WriteLine("Horse can ride 110 KPH");
}
}
class Test
{
static void Main()
{
Elephant bully = new Elephant("Vertebrata");
Horse lina = new Horse("Vertebrata");
IRide[] riders = {bully,lina};
foreach(IRide rider in riders)
{
rider.Ride();
}
Console.ReadKey(true);
}
}
}
Questions :
Beyond such extend, what are the different way can we leverage the elegance of Interfaces ?
What is the Key point that I can say this can be only done by interface (apart from
multiple inheritances) ?
(I wish to gather the information from experienced hands).
Edit :
Edited to be concept centric,i guess.
The point is, you could also have a class Bike which implements IRide, without inheriting from Animal. You can think of an interface as being an abstract contract, specifying that objects of this class can do the things specified in the interface.
Because C# doesn't support multiple inheritance (which is a good thing IMHO) interfaces are the way you specify shared behavior or state across otherwise unrelated types.
interface IRideable
{
void Ride();
}
class Elephant : Animal, IRideable{}
class Unicycle: Machine, IRideable{}
In this manner, say you had a program that modeled a circus (where machines and animals had distinct behavior, but some machines and some animals could be ridden) you can create abstract functionality specific to what is means to ride something.
public static void RideThemAll(IEnumerable<IRideable> thingsToRide)
{
foreach(IRideable rideable in thingsToRide)
ridable.Ride();
}
As Lucero points out, you could implement other classes that implement IRide without inherting from Animal and be able to include all of those in your IRide[] array.
The problem is that your IRide interface is still too broad for your example. Obviously, it needs to include the Ride() method, but what does the Eat() method have to do with being able to ride a "thing"?
Interfaces should thought of as a loose contract that guarantees the existance of a member, but not an implementation. They should also not be general enough to span "concepts" (eating and riding are two different concepts).
You are asking the difference between abstract classes and interfaces. There is a really good article on that here.
Another great advantage is lower coupling between software components. Suppose you want to be able to feed any rideable animal. In this case you could write the following method:
public void Feed(IRide rideable)
{
//DO SOMETHING IMPORTANT HERE
//THEN DO SOMETHING SPECIFIC TO AN IRide object
rideable.Eat();
}
The major advantage here is that you can develop and test the Feed method without having any idea of the implementation of IRide passed in to this method. It could be an elephant, horse, or donkey. It doesn't matter. This also opens up your design for using Inversion of Control frameworks like Structure Map or mocking tools like Rhino Mock.
Interfaces can be used for "tagging" concepts or marking classes with specifically functionality such as serializable. This metadata (Introspection or Reflection) can be used with powerful inversion-of-control frameworks such as dependency injection.
This idea is used throughout the .NET framework (such as ISerializable) and third-party DI frameworks.
You already seem to grasp the general meaning of Interfaces.
Interfaces are just a contract saying "I support this!" without saying how the underlying system works.
Contrast this to a base or abstract class, which says "I share these common properties & methods, but have some new ones of my own!"
Of course, a class can implement as many interfaces as it wants, but can only inherit from one base class.