This question already has answers here:
Interface vs Base class
(38 answers)
Closed 8 years ago.
I'm a bit new to OO programming and I'm trying to understand all facets of this kind of practice : inheritance, polymorphism and such, but there's a thing my brain DOESN'T WANT to fully understand: Interfaces.
I can understand the benefits of using interfacing instead of class-inheritance (mostly because a class can't inherit from multiple parents) but here's where I'm stuck:
Let's say I have something like this:
/** a bunch of interfaces **/
public interface IMoveable
{
void MoveMethod();
}
public interface IKilleable()
{
void KillMethod();
}
public interface IRenderable()
{
void RenderMethod();
}
/** and the classes that implement them **/
public class ClassOne : IMoveable
{
public void MoveMethod() { ... }
}
public class ClassTwo: IMoveable, IKilleable
{
public void MoveMethod() { ... }
public void KillMethod() { ... }
}
public class ClassThree: IMoveable, IRenderable
{
public void MoveMethod() { ... }
public void RenderMethod() { ... }
}
public class ClassFour: IMoveable, IKilleable, IRenderable
{
public void MoveMethod() { ... }
public void KillMethod() { ... }
public void RenderMethod() { ... }
}
By using interfaces here, I would have to declare MoveMethod, KillMethod and RenderMethod each time, in each classes... That means duplicating my code. There must be something wrong, because I don't find this really practical.
So should I implement interfaces only on a few classes? Or should I find a way to mix inheritance and interfaces?
Interfaces are like a contract to a class.. If some class states that it supports such an interface, it must have it's method defined as you properly sampled. Interfaces are great to expose common things that don't easily cross different class implementations.
Now, from your samples, you may be best to do a combination to prevent duplicate code by subclassing from a class and ALSO an interface. So you can get parent-structure code constant and expand as needed.
/** Based on same interfaces originally provided... and the classes that implement them **/
public class ClassOne : IMoveable
{
public void MoveMethod() { ... }
}
public class ClassTwo: ClassOne, IKilleable
{
// Move Method is inherited from ClassOne, THEN you have added IKilleable
public void KillMethod() { ... }
}
public class ClassThree: ClassOne, IRenderable
{
// Similar inherits the MoveMethod, but adds renderable
public void RenderMethod() { ... }
}
public class ClassFour: ClassTwo, IRenderable
{
// Retains inheritance of Move/Kill, but need to add renderable
public void RenderMethod() { ... }
}
Related
I have an abstract class with methods with logic.
Then i have childs but not all childs can have all methods from the abstract class. I have been thinking of a design pattern that allows me to keep the logic instead of using interfaces but can't think of anyhting other then using a static class with methods. But it would make my code very sloppy.
Another way of formulating my question is: How do i use interfaces with logic in them...
public abstract class Company
{
public virtual void Dowork1()
{
//logic
}
public virtual void Dowork2()
{
//logic
}
public virtual void Dowork3()
{
//logic
}
}
public class ItCompany : Company
{
//DoWork2 NOT callable
}
public class ManagementCompany : Company
{
//DoWork1 NOT callable
}
A pillar of object oriented programming is Liskov substitution principle. In practical terms this means that any implementation of Company need to implement all the methods. I.e. one implementation of a company should be possible to substitute for any other.
You seem to be concerned about implementation inheritance, i.e. allow any of the implementations to reuse the same logic without the need to reimplement it. This can be problematic since it couples the base class to the derived classes. However, you should be able to do what you describe by making the implementations protected.
public abstract class Company
{
protected virtual void DoworkImpl1()
{
//logic
}
protected virtual void DoworkImpl2()
{
//logic
}
protected virtual void DoworkImpl3()
{
//logic
}
}
This lets each implementation define what parts they want to expose:
public class ItCompany : Company
{
public void Dowork1() => DoworkImpl1();
public void Dowork3() => DoworkImpl3();
}
You may also add different interfaces for each type of company if you want to, as shown in other answers. However, if Company does not expose any public methods, you cannot really do anything with a object of the base type, except check what specific type it is, and this is often indicative of a problem in the class design. I would recommend reading Eric Lipperts article on Wizards and Warriors for some perspective.
A possible replacement is to move logic to static methods, for example using extension methods or default interface methods:
public static class CompanyHelpers{
public static void Dowork1(this ICompany company){
// Logic
}
}
This can be very useful with well designed interfaces that expose a minimal set of functions, and provides most extra functionality via extension methods. See LINQ for an example. But it may or may not be applicable in your specific situation.
I think you are looking at the problem from the wrong side. Let me rename your methods to make it more clear.
public abstract class Company
{
public virtual void ManagementWork()
{
//logic
}
public virtual void ItWork()
{
//logic
}
public virtual void BuildCompany()
{
//general logic
}
}
public class ItCompany : Company
{
//ManagementWork NOT callable
}
public class ManagementCompany : Company
{
//ItWork NOT callable
}
It would be better this way
public abstract class Company
{
public virtual void BuildCompany()
{
//general logic
}
}
public class ItCompany : Company
{
public virtual void ItWork()
{
//logic
}
}
public class ManagementCompany : Company
{
public virtual void ManagementWork()
{
//logic
}
}
I guess this is the better way :
interface IDoableWorkOne
{
void DoWork1();
}
interface IDoableWorkTwo
{
void DoWork2();
}
interface IDoableWorkThree
{
void DoWork3();
}
interface ICompany
{
//Other Company Shared Logics
}
public class ManagementCompany: IDoableWorkTwo, IDoableWorkThree, ICompany
{
/// Do your Business
}
public class ItCompany : IDoableWorkOne, IDoableWorkThree, ICompany
{
/// Do Your Business
}
Hope this helps.
Trying to stick with inheritance in such situation makes me think that you are trying to use the wrong tool for your job.
You may achieve code reuse by favoring composition over inheritance and refactor your code as follow:
public sealed class Company
{
public void Dowork1()
{
//logic
}
public void Dowork2()
{
//logic
}
public void Dowork3()
{
//logic
}
}
public sealed class ItCompany
{
private readonly Company _company;
public ItCompany(Company company) => _company = company;
//Call DoWork1 and DoWork3 whenever you want from _company
}
public sealed class ManagementCompany
{
private readonly Company _company;
public ManagementCompany (Company company) => _company = company;
//Call DoWork2 and DoWork3 whenever you want from _company
}
This code has the same benefits of code reuse than inheritance but without the burden of trying to hide normally public inherited methods.
Also you can be sure that no one ever can alter Company's behavior (such a central piece of logic for you) since the class is sealed, unlike solutions trying to stick with inheritance that allow overriding DoworkX() methods.
EDIT
Ive rephrased the question so it better reflects what im trying to do
I'm trying to create a suite of classes that all inherit from 1 "superclass" or "baseclass".
However i'm looking for a way around having to implement the code for each method, in every single class since it seems to be theres a lot of duplication.
Here is the Super class:
public abstract class WebObject
{
string Id { get; set; }
string Name { get; set; }
public void Click() { Console.WriteLine("Clicking object"); }
public string GetAttribute() { return "An attribute"; }
public void SetAttribute(string attribute, string value)
{
//code to set attribute
}
}
I've also created a couple of interfaces:
interface IReadable
{
string GetText();
}
interface IWriteable
{
void SetText(string value);
}
Here is an example derived class:
public class TextBox: WebObject, IWriteable, IReadable
{
}
Of course the above class contains an error. It does not implement IWriteable or IReadable.
So I could do something like:
public class TextBox: WebObject, IWriteable, IReadable
{
public void SetText(string value)
{
//Implemented code
}
public string GetText()
{
//Implemented code
return "some value";
}
}
Which would compile fine...
However the problem here is that SetText and GetText contain a lot of code. I don't want to have to copy this every single time I want to implement the method. Id rather just write the code once and have it called any time I need to use that method.
I know we cant do multiple inheritance in C# and Java. So my original thought was simply to create a suite of static classes with the code for SetText and GetText Shown here:
public static class Setter
{
public static void SetText(string value)
{
//Code to set text
}
}
public static class Getter
{
public static string GetText()
{
//Code to get text
return "";
}
}
Then changing my TextBox class to the following:
public class TextBox: WebObject, IWriteable, IReadable
{
public void SetText(string value)
{
Setter.SetText(value);
}
public string GetText()
{
return Getter.GetText();
}
}
I cant help but feel this is a pretty long winded solution. It accomplishes what I want in that TextBox has the vanilla methods plus the 2 it implements itself.
But my question is, can I achieve the same goal using a more concise design?
Footnotes
Each object actually implements several of common methods. Take TextBox, ComboBox and SelectBox they all should be able to SetText, however only CombBox and SelectBox should be able to use Select.
The cleanest way to do what you are asking is to implement protected helper methods within your base class that decompose the problem of "a lot of duplication" into smaller pieces that can be composed in your concrete method implementations, like this:
public abstract class WebObject {
protected void SetTextImpl() { /* Implementation */ }
protected void GetTextImpl() { /* Implementation */ }
}
Then in your derived classes, implement only the applicable interfaces and appropriate methods:
public class TextBox: WebObject, IWriteable, IReadable {
public void SetText() { SetTextImpl(); }
public void GetText() { GetTextImpl(); }
}
public class Span: WebObject, IReadable {
public void GetText() { GetTextImpl(); }
}
If you know that all the subclasses will be IReadable, you can simplify further:
public abstract class WebObject : IReadable {
protected void SetTextImpl() { /* Implementation */ }
protected void GetTextImpl() { /* Implementation */ }
// Implement IReadable -- this could be combined with GetTextImpl() but
// is implemented separately for consistency.
public void GetText() { GetTextImpl(); }
}
public class TextBox: WebObject, IWriteable {
public void SetText() { SetTextImpl(); }
}
public class Span: WebObject, IReadable {
}
If the code for those two methods will always be the same or mostly the same, you could create another abstract class (ex: WebObjectReadWrite) that inherits from WebObject and implements the interface.
public abstract class WebObjectReadWrite : WebObject, IReadable, IWritable
{
// Could be made virtual if some subclasses need to overwrite default implementation.
public void Read()
{
// Implementation
}
// Could be made virtual if some subclasses need to overwrite default implementation.
public void Write()
{
// Implementation
}
}
public class TextBox : WebObjectReadWrite
{
}
This could, however, lead to multiple inheritance problems or inheritance relationships that don't make sense. Another option is to use the strategy pattern (in way) to delegate the read / write operations to other classes that can be reused.
public class TextBox : WebObject, IReadable, IWriteable
{
private IReadable _readable = new TextReader();
private IWriteable _writeable = new TextWriter();
public void Read()
{
_readable.Read();
}
public void Write()
{
_writable.Write();
}
}
public class Span : WebObject, IReadable
{
// Reused class.
private IReadable _readable = new TextReader();
public void Read()
{
_readable.Read();
}
}
public class TextReader : IReadable
{
public void Read()
{
// Reusable implementation
}
}
This isn't quite the strategy pattern because you are not allowing the caller to choose the implementation of IReadable and IWriteable. However, it does allow you to reuse IReadable and IWriteable classes.
I have an Interface:
public interface IMessager
{
void ShowMessage();
}
Is there any way to implement this interface using extension methods?
public static class Extensions
{
public static void ShowMessage(this MyClass e)
{
Console.WriteLine("Extension");
}
}
and a class that implement it:
public class MyClass:IMessager
{
public void ShowMessage()
{
ShowMessage(); // I expect that program write "Extension" in console
}
}
But when I run the program I get the System.StackOverflowException.
The code you posted is just a method calling itself recursively (hence the StackOverflowException).
I'm not entirely sure what you're trying to accomplish but to answer your question
Is there any way to implement this interface using extension methods?
No.
To be a bit more pragmatic about this though, if your aim is to only write your method once you have a few options:
1. Call the extension explicitly
public class MyClass:IMessager
{
public void ShowMessage()
{
Extensions.ShowMessage(this);
}
}
although as pointed out in comments, this basically defeats the point of using the extension method. Additionally there is still "boiler-plate code" such that every time you implement your interface you have to call the static method from within the method (not very DRY)
2. Use an abstract class instead of an interface
public abstract class MessengerBase
{
public void ShowMethod() { /* implement */ }
}
public class MyClass : MessengerBase {}
...
new MyClass().ShowMethod();
This issue with this though is that you can't inherit from multiple classes.
3. Use extension on the interface
public interface IMessenger { /* nothing special here */ }
public class MyClass : IMessenger { /* also nothing special */ }
public static class MessengerExtensions
{
public static void ShowMessage(this IMessenger messenger)
{
// implement
}
}
...
new MyClass().ShowMessage();
I am writing a library and I want to have an interface
public interface ISkeleton
{
IEnumerable<IBone> Bones { get; }
void Attach(IBone bone);
void Detach(IBone bone);
}
The Attach() and Detach() implementation actually should be the same for every ISkeleton. Thus, it could essentially be:
public abstract class Skeleton
{
public IEnumerable<IBone> Bones { get { return _mBones; } }
public List<IBone> _mBones = new List<IBone>();
public void Attach(IBone bone)
{
bone.Transformation.ToLocal(this);
_mBones.add();
}
public void Detach(IBone bone)
{
bone.Transformation.ToWorld(this);
_mBones.Remove(bone);
}
}
But C# doesn't allow multiple inheritance. So among various issues, users have to remember to inherit from Skeleton every time they want to implement Skeleton.
I could use extension methods
public static class Skeleton
{
public static void Attach(this ISkeleton skeleton, IBone bone)
{
bone.Transformation.ToLocal(skeleton);
skeleton.Bones.add(bone);
}
public static void Detach(this ISkeleton skeleton, IBone bone)
{
bone.Transformation.ToWorld(this);
skeleton.Bones.Remove(bone);
}
}
But then I need to have
public interface ISkeleton
{
ICollection<IBone> Bones { get; }
}
Which I do not want, because it is not covariant and users can bypass the Attach() and Detach() methods.
Question: Must I really use an abstract Skeleton class or are there any or tricks and methods?
If you need to expose the Attach and Detach methods in your interface, there is always a way to bypass your intended implementations, as all objects implementing the interface can implement them on their own style.
You can let the abstract class Skeleton implement ISkeleton and all classes which are Skeletons do inherit from Skeleton, thus they implement ISkeleton as well.
public interface ISkeleton { ... }
public abstract class Skeleton : ISkeleton { ... } // implement attach and detach
public class SampleSkeleton : Skeleton { ... }
This way you can use your SampleSkeleton as ISkeleton, you don't have to implement these functions as long as you inherit from Skeleton and marking the methods as sealed does not allow overriding them (as long as they are instance methods).
On a side node: Do name your abstract class with Base at the end or mark the base class somehow else (but this is surely up to you).
I would make bones a special type that implements IEnumerable<T>. That way it doesn't violate the single responsibility principle.
public interface ISkeleton
{
AttachableEnumerable<IBone> Bones { get; }
}
public class AttachableEnumerable<T> : IEnumerable<T>
{
// implementation needed.
void Attach(T item);
void Detach(T item);
}
If you want to wrap ISkeleton behaviour, you could always make it a composite object instead of inheriting the behaviour:
public class Body : ISkeleton
{
private SkeletonImpl _skeleton = new SkeletonImpl;
public IEnumerable<IBone> Bones { get { return _skeleton.Bones; } }
public void Attach(IBone bone)
{
_skeleton.Attach(bone);
}
public void Detach(IBone bone)
{
_skeleton.Detach(bone);
}
}
May be you just have to use sealed methods on abstract Skeleton class?
This way they can't be overriden.
http://msdn.microsoft.com/en-us/library/aa645769(v=vs.71).aspx
You can create a wrapper class which implements the 'Attach' and 'Detach' methods and inject this Functionality to your Interface.
So, I'd like to hear what you all think about this.
I have a project where three different inheritance paths need to all implement another base class. This would be multiple inheritance and isn't allowed in C#. I am curious how I can implement this without code duplication.
EDIT: I don't own the three classes. The three classes are from 3rd party code. So I cannot make them all extend my base class.
Right now I am using three different classes, each one extending a different base class. Then I have the same code in each of the three abstract classes.
I could use a single interface, but I would still need to duplicate the code.
I could make some kind of static class that implements the code and then reference that in each of the 3 abstract classes. It would eliminate the duplication, but, I am not sure how I feel about this. I could implement Extensions methods on the interface, but then the interface itself would be empty and the extension methods (containing the duplicate code) would be in a totally different file, which seems not quite right. Plus I can't implement properties in extension methods...
How can I factor out the code duplication here?
EDIT, inheritance tree:
class Class1 : 3rdPartyBaseClass1 { }
class Class2 : 3rdPartyBaseClass2 { }
class Class3 : 3rdPartyBaseClass3 { }
I have code I want to be in each of the above Classes, but I cannot add it to the 3rdPartyClasses.
Create an interface that Class1, Class2, and Class3 can implement. Then put your code in extension methods so it will apply to all.
interface IMyInterface {
void Foo(); //these are the methods that these
//classes actually have in common
void Bar();
}
public class Class1 : 3rdPartyBaseClass1, IMyInterface {
// whatever
}
public static class IMyInterfaceExtensions {
public static void CommonMethod(this IMyInterface obj) {
obj.Foo();
obj.Bar();
}
}
public static class Program {
public static void Main() {
var instance = new Class1();
instance.CommonMethod();
}
}
OK, you can do something similar to my previous suggestion, and also similar to recursive's suggestion. For the functionality you require in all three of your derived classes, you can create a single Interface along with a single class (call it "Implementer" for kicks) that implements that Interface (and that has the actual code you want executed with each call).
In each of your derived classes, then, you implement the Interface and create a private instance of Implementer. In each of the interface methods, you just pass the call along to the private instance of Implementer. Because Implementer and your derived classes all implement your Interface, any changes you make to the Interface will require you to modify Implementer and the derived classes accordingly.
And all your code is in one place, except for all the lines passings the calls on to the private instance of Implementer (obviously multiple inheritance would be better than this, but you go to war with the army you have, not the army you wish you had).
Update: what about just adding a public instance of your class to each of the derived classes?
public class DerivedClass1 : ThirdPartyClass1
{
public MyClass myClass = new MyClass();
}
Or if you care who Demeter is and you get paid by LOC:
public class DerivedClass1 : ThirdPartyClass1
{
private MyClass _myClass = new MyClass();
public MyClass myClass
{
get
{
return _myClass;
}
}
}
Then you'd just call the MyClass methods like this:
DerivedClass1 dc1 = new DerivedClass1();
dc1.myClass.DoSomething();
This way, we could all go to sleep.
Similar to MusiGenesis's suggestion, if you need the functionality of the 3rd party classes but do not have to descend from them, you could use composition as follows:
class ThirdPartyBaseClass1
{
public void DoOne() {}
}
class ThirdPartyBaseClass2
{
public void DoTwo() { }
}
class ThirdPartyBaseClass3
{
public void DoThree() { }
}
abstract class Base
{
public void DoAll() { }
}
class Class1 : Base
{
public void DoOne() { _doer.DoOne(); }
private readonly ThirdPartyBaseClass1 _doer = new ThirdPartyBaseClass1();
}
class Class2 : Base
{
public void DoTwo() { _doer.DoTwo(); }
private readonly ThirdPartyBaseClass2 _doer = new ThirdPartyBaseClass2();
}
class Class3 : Base
{
public void DoThree() { _doer.DoThree(); }
private readonly ThirdPartyBaseClass3 _doer = new ThirdPartyBaseClass3();
}
This also gives you the freedom to define whatever interfaces you want and implement them on your classes.
Sounds like you need to insert the new abstract class into the inheritance tree at whatever point those three paths come together, but there really isn't enough information to tell. If you could post some of your inheritance tree, that would help a lot.
I think you may want to use composition instead of inheritance. Exactly how to do this depends on what the third party classes look like, and what your own code looks like. Some more specific code relating to your problem would be helpful, but for example, suppose you want to have three different third party GUI widgets that all need to be customized with your own initializer code.
Case 1: Suppose your third party widgets look like:
public interface IThirdPartyWidget {
public void doWidgetStuff();
}
public class ThirdPartyWidget1: ThirdyPartyWidget implements IThirdPartyWidget {
...
}
public class ThirdPartyWidget2: ThirdPartyWidget implements IThirdPartyWidget {
...
}
You can do:
public class MyWidget implements IThirdPartyWidget {
private IThirdPartyWidget delegateWidget;
public MyWidget(IThirdPartyWidget delegateWidget) {
this.delegateWidget = delegateWidget;
}
public void doWidgetStuff() {
delegateWidget.doWidgetStuff();
}
}
Case 2: Suppose you absolutely need to extend those widgets, and you have to refactor your own code:
public class MyWidget1: ThirdPartyWidget1 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
public class MyWidget2: ThirdPartyWidget2 {
public void myMethod() {
runMyCode();
}
private void runMyCode() {
//something complicated happens
}
}
This can become:
public class MyCodeRunner {
public void runMyCode() {
//...
}
}
public class MyWidget1: ThirdPartyWidget1 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
public class MyWidget2: ThirdPartyWidget2 {
private MyCodeRunner myCode = new MyCodeRunner();
public void myMethod() {
myCode .runMyCode();
}
}
Hope this makes sense!