C # Interfaces and Base Classes

I have a C # interface and a specific class that implements this interface. Now I want to create another class that implements this interface. Simple enough.

However, most methods will be the same in classes, and only a few methods will really change.

I do not want to duplicate all the logic in my second class, which is contained in my first.

How to create 2nd grade and use logic in my first grade, with the exception of additional materials?

My interface is called IEventRepository, and my first class is called BaseEvents. Now I want to create a new FooBarEvents class.

My class definition for FooBarEvents:

public class FooBarEvents : BaseEvents, IEventRepository 

My intention was then to use the return.Method () base in every method that duplicates the code.

I assume this is not true?

+7
source share
8 answers

FooBarEvents only need to inherit from BaseEvents , and not implement IEventRepository , since BaseEvents already implements the interface. If you need to change the behavior of some IEventRepository methods in FooBarEvents , simply override these methods.

Edit: a few examples

 interface IEventRepository { void CommonMethodA(); void CommonMethodB(); void ImplentationSpecificMethod(); } abstract class BaseEvents : IEventRepository { public void CommonMethodA() { ... } public virtual void CommonMethodB() { ... } public abstract void ImplementationSpecificMethod(); public void BaseEventsMethod() { ... } public void BaseEventsMethod2() { ... } } class FooBarEvents : BaseEvents { public override void CommonMethodB() { // now FooBarEvents has a different implementation of this method than BaseEvents } public override void ImplementationSpecificMethod() { // this must be implemented } public new void BaseEventsMethod2() { // this hides the implementation that BaseEvents uses } public void FooBarEventsMethod() { // no overriding necessary } } // all valid calls, assuming myFooBarEvents is instantiated correctly myFooBarEvents.CommonMethodA() myFooBarEvents.CommonMethodB() myFooBarEvents.BaseEventsMethod(); myFooBarEvents.BaseEventsMethod2(); myFooBarEvents.FooBarEventsMethod(); myFooBarEvents.ImplementationSpecificMethod(); // use the contract thusly: void DoSomethingWithAnEventRepository(BaseEvents events) { ... } 
+10
source

Since BaseEvents already implements IEventRepository , you no longer need to implement it in FooBarEvents . FooBarEvents automatically inherits an implementation of BaseEvents .

+6
source

Why don't you define your methods in the base class as Virtual and override the ones you want to change in the child class?

+3
source

The following code shows how to provide a common implementation of some interface methods with an abstract base class and provide custom implementations for others.

 public interface IEventRepository { void Method1(); void Method2(); } public abstract class BaseEvents : IEventRepository { public void Method1() { Console.WriteLine("This is shared functionality"); } public abstract void Method2(); } public class Implementation1 : BaseEvents { override public void Method2() { Console.WriteLine("Impl1.Method2"); } } public class Implementation2 : BaseEvents { override public void Method2() { Console.WriteLine("Impl2.Method2"); } } public class Program { static void Main(string[] args) { var implementations = new List<IEventRepository> { new Implementation1(), new Implementation2() }; foreach (var i in implementations) { Console.WriteLine(i.GetType().Name); Console.Write("\t"); i.Method1(); // writes 'This is shared functionality' Console.Write("\t"); i.Method2(); // writes type specific message } } 

}

+3
source

You can make your second grade your first grade. Your first class may be abstract, but only implement common methods from the interface.

+2
source

Use inheritance:

 public interface IFoo { void GeneralBehaviorMethod1(); void GeneralBehaviorMethod2(); void SpecificBehaviorMethod1(); } public class Bar: IFoo { public void GeneralBehaviorMethod1() {...} public void GeneralBehaviorMethod2() {...} public virtual void SpecificBehaviorMethod1() {...} ... } public class BarOnSteroids: Bar { public override void SpecificBehaviorMethod1() {...} } 

BarOnSteroids inherits all the behavior of Bar , and you can change the specific behavior of any methods that you need by overriding them in BarOnSteroids (they must be marked as virtual in the base class of Bar ).

So you will have the following:

 IFoo iFoo = new Bar(); iFoo.SpecificBehaviorMethod1(); //Bar implementation will be called; IFoo iFoo = new BarOnSteroids(); iFoo.SpecificBehaviorMethod1(); //BarOnSteroids implementation will be called. iFoo.CommonBehaviorMethod1(); //Bar implementation will be called. Bar bar = new BarOnSteroids(); bar.SpecificBehaviorMethod1(); //BarOnSteroids implementation will be called. bar.CommonBehaviorMethod1(); //Bar implementation will be called. 

It is assumed that you want to change the specific behavior of methods that are part of the IFoo interface. If you want to add additional functions to BarOnSteroids , simply inherit the form Bar to inherit all its functionality and add all the necessary new methods to implement the new functionality.

+2
source

If a specific selection of methods in a BaseEvents implementation of BaseEvents IEventRepository always support the same implementation, then you can simply implement them in the BaseEvents class and mark those that may change as virtual . Thus, if FooBarEvents wants to change the implementation of one of the methods, it can simply override it.

Just pay attention to adding IEventsRepository to your FooBarEvents class: it really is. See here for John Skeet's answer about this.

0
source

There are several different approaches.

One. Skip the interface completely and make it an abstract class. It is easier when it works, but the fact that you can only use one base class for use in C #

 public abstract class EventRepository { public abstract int MustBeOverridden(string str);//classes have to override this public virtual int CanBeOverridden(int i)//classes can override but may choose not to. { return 4; } public int CannotOverride(string str)//this is always the same { return MustBeOverridden(str) + 3;//can make use of this } } 

You can have one class that implements the interface, and the other from it:

 public interface IEventRepository { int Method1(string str); int Method2(string str); } public class EventClass1 : IEventRepository { public int Method1(string str)//can't be overridden as not marked virtual { return 1; } public virtual int Method2(string str)//can be overridden { return 2; } } public class EventClass2 : EventClass1 { public override int Method2(string str) { return -2; } } 

Ask them to override the abstract class, which gives some general behavior:

 public abstract class EventClass : IEventRepository { public abstract int Method1(string str); public int Method2(string str) { return 2; } } public class EventClass1 : EventClass { public override int Method1(string str) { return 1; } } public class EventClass2 : EventClass { public override int Method1(string str) { return -1; } } 

They can also use a static helper class that has nothing to do with hierarchy, but which provides methods that are useful in implementing functionality.

Be careful though from this template:

 public class EventClass1 : IEventRepository { public int Method1(string str)//not override-able { return 1; } public int Method2(string str)//not override-able { return 2; } } public class EventClass2 : EventClass1, IEventRepository { //We really want our own Method1! public new int Method1(string str) { return 3; } int IEventRepository.Method1(string str) { return -1; } } EventClass2 e2 = new EventClass2(); EventClass1 e1 = e2; IEventRepository ie = e2; Console.WriteLine(e2.Method1(null));//3 Console.WriteLine(e1.Method1(null));//1 Console.WriteLine(ie.Method1(null));//-1 

Even when IEventRepository.Method1 defined more reasonably, the above can lead to confusion.

0
source

All Articles