OOP Design: Concrete Class having different Operations with Same Base Class - c#

I am wondering if the following code can be written in C#:
AbstractClass a = new ConcreteClass1();
a.Operations.Method1();
AbstractClass b = new ConcreteClass2();
b.Operations.Method2();
where Method1() is exclusive to the ConcreteClass1 instance and Method2() is exclusive to the ConcreteClass2() instance. As a result, a.Operations.Method2() and b.Operations.Method1() would be invalid.

This is not possible by design - a and b have the same type, and the compiler will treat them as such. The only way to make it work is by using runtime exceptions.
The concept behind using abstract classes or interfaces conflicts with what you are attempting to do; it sounds like ConcreteClass1 and ConcreteClass2 do not server the same purpose, should they still use the same abstract base class?
I don't know what exactly you are trying to do - so I'll provide a few options:
Use interfaces to show that specific classes implement specific operations:
interface IOperation1
{
void Operation1();
}
interface IOperation2
{
void Operation2();
}
Then reference the interfaces based on what you are trying to achieve.
If Method1 and Method2 are supposed to be invoked at the same time, consider a design where AbstractClass declares the method to be invoked, and the concrete classes do different operations based on that:
abstract class AbstractClass
{
...
abstract void DoSomeOperation();
}
class ConcreteClass1
{
override void DoSomeOperation()
{
this.Operations.Method1();
}
}
class ConcreteClass2
{
override void DoSomeOperation()
{
this.Operations.Method2();
}
}

It's okay for ConcreteClass1 and ConcreteClass2 to have some different methods, but share some functionality that they both inherit from AbstractClass. (If you cast them as their base type then you can only call common methods that they inherit from the base type.)
It sounds like the difference between whether a concrete class uses Method1 or Method2 is an internal detail that should be handled inside the class. The class should know what method it needs to call. In fact, does a consumer of that class even need to know that it depends on Operations? Probably not. Consumers should just call a method on the class, and then whether that class uses Operations.Method1, Operations.Method2, or even depends on Operations at all is an internal implementation detail.
Maybe what you want is something like this:
public abstract class AbstractClass
{
public abstract void DoSomething();
}
public class Operations
{
public void Method1()
{
//Does something
}
public void Method2()
{
//Apparently does something comopletely different
}
}
public class ConcreteClass1 : AbstractClass
{
private Operations _operations;
public override void DoSomething()
{
_operations.Method1();
}
}
public class ConcreteClass2 : AbstractClass
{
private Operations _operations;
public override void DoSomething()
{
_operations.Method2();
}
}
Operations should only be in the base class if it's required that every derived class will use it. (That doesn't happen too much. If all of the derived classes have the same behavior, why isn't it in the base class?) If that's the case then you can hide it in the base class, like this:
public abstract class AbstractClass
{
private Operations _operations;
protected Operations Operations { get { return _operations; } }
public abstract void DoSomething();
}
That way it's exposed to the derived classes but hidden from everything else.

Related

How to to implementing only one methods from abstract class out of two abstract methods in C#?

In an Abstract class there are two abstract methods Method1() and Method2(),
but I like to inherit only one Method1() in derived Class, how to handle the situation?
public abstract class BaseClass
{
public abstract void Method1();
public abstract void Method2();
}
Really you can't... If you have to (and I would really question the reasons) some options are:
If you do not have any control over the abstract classes involved, and must use this specific abstract class, then, only way is to make the implementation in derived class throw a NotImplementedException.
public MyDerivedClass: BaseClass
{
public override void Method1()
{
// implementation of Method1
}
public override void Method2()
{ throw new NotImplementedException(); }
}
... or create another abstract base class called, say OnlyDOMethod1
public abstract class OnlyDoMethod1
{ public abstract void Method1(); }
then, modify Baseclass so it inherits from OnlyDoMethod1
public abstract class BaseClass: OnlyDoMethod1
{ public abstract void Method2(); }
and use OnlyDoMethod1 anywhere you only want Method1
public MyDerivedClass: OnlyDoMethod1
{
public override void Method1()
{
// implementation of Method1
}
}
It sounds like what you're looking for is interfaces. Something like this:
public interface ICanDoMethod1
{
void Method1();
}
public interface ICanDoMethod2
{
void Method2();
}
Then in your classes you can selectively implement them:
public class JustMethod1 : ICanDoMethod1
{
// implement Method1 here
}
public class Both : ICanDoMethod1, ICanDoMethod2
{
// implement both here
}
// etc.
Essentially, any given class either can or can not be polymorphically interpreted as any given type. If you want to be only part of a type, then what you really have is two types. C# is single-inheritance, so to implement multiple types you would use interfaces.
Conversely, you could also chain your inheritance. Something like this:
public abstract class Base1
{
public abstract void Method1();
}
public abstract class BaseBoth : Base1
{
public abstract void Method2();
}
public class JustOne : Base1
{
// only implement Method1 here
}
public class Both : BaseBoth
{
// implement both here
}
That'll work if the options stack, that is if you don't want to be able to pick and choose and either want "1" or "1 and 2" (but not just "2").
As a last resort, you can "selectively implement" methods by explicitly not implementing the others. It would looks something like:
public class JustOne : BaseClass
{
public override void Method1()
{
// implement
}
public override void Method2()
{
throw new NotImplementedException();
}
}
But this would be something of an anti-pattern, where your objects would advertise functionality that they intentionally do not support. This would mean that the type BaseClass should be considered very unstable/unreliable, because there's no way for anything consuming that type to know how it should actually behave.
Ultimately, it sounds like you've painted yourself into a corner with your types and you need to back up a little and re-think them. Liskov Substitution shouldn't be taken so lightly.
This is basic example of violation of one of SOLID principles Interface segregation principle
A client should never be forced to implement an interface that it
doesn’t use or clients shouldn’t be forced to depend on methods they
do not use
If you have abstraction where you need only some of method you need to split them in separated abstractions.
.NET do not support multi-inheritance from classes, nut have nice workaround for this problem -> interfaces.
If you care about your code, then you have only one option - split abstract class into two separated classes which have only one method.
If you work only with abstraction then interfaces is better approach, because you can implement multiply interfaces in one class.
public interface IMethodOne
{
void Method1();
}
public interface IMethodTwo
{
void Method2();
}
Then you can implement that both interfaces in the class which needs both methods. And use only one interface in the class with one method needs.
public abstract class BaseClass : IMethodOne, IMethodTwo
{
public abstract void Method1();
public abstract void Method2();
}
And class with one method
public abstract class BaseClassOneMethod : IMethodOne
{
public abstract void Method1();
}

Interface inheritance consistency

First look at this code:
class Program
{
static void Main(string[] args)
{
var x =(Base) new Derived();
((IMethod)x).DoWork();
Console.ReadKey();
}
}
interface IMethod
{
void DoWork();
}
abstract class Base : IMethod
{
void IMethod.DoWork()
{
Console.WriteLine("Base.DoWork");
}
}
class Derived : Base, IMethod
{
public void DoWork()
{
//here I where I want to call base.DoWork();
Console.WriteLine("Derived.DoWork");
}
}
Output:
Derived.DoWork
Desired:
Base.DoWork
Derived.DoWork
I'm dealing with an API that exposes an interface that when implemented, the DoWork method will be called at some part of the procession.
Now in the above example, the class Base is a part of the API, that internally (in the API) already explicitly implements that interface and does some important executions in the DoWork method.
I need to override the implementation of the IMethod in my derived class as well, so I get notified when needed, the problem is I can't 'override' the method and call the base method, neither can I cast base to IMethod.
Any solution?
Note: reflection won't work since it's a Silveright project, and private method invoking is prohibited.
Are you able to just compose the classes, rather than using inheritance? Then you can implement DoWork() however you like, and still call DoWork() on the Base object as well. Since Base is abstract, you'll need to derive a dummy type to get everything to work.
class Derived : IMethod
{
private class SneakyBase : Base
{
// abstract implementations here
}
private IMethod baseObject = new SneakyBase();
void DoWork()
{
baseObject.DoWork();
// Custom DoWork code here
}
}
It's obviously a bit of pain to do things this way, but the API designers made an odd choice with the explicit interface implementation, and you're now paying for it.
Are you looking for:
public class Derived : Base
{
public override void DoWork()
{
base.DoWork();
}
}
I've found DanBryant's comment to be the answer, although as he mentions is a bit risky since we can't assure the implementer will call the base method, but is a decent way tho.
I made a protected virtual method that is called from the private interface implementer, then, in the derived class, instead of worrying about the interface, I just care about overriding the base class and calling the base implementation from it, that works perfect, example:
abstract class Base : IMethod
{
void IMethod.DoWork()
{
DoWork();
}
protected virtual void DoWork()
{
Console.WriteLine("Base.DoWork");
}
}
class Derived : Base
{
protected override void DoWork()
{
base.DoWork();
//here I where I want to call base.DoWork();
Console.WriteLine("Derived.DoWork");
}
}

Run same method in base and derived class

What do I need to do to first run the method in the base class then run the same method in the derived class? Is this a good idea?
I want run common actions in base class and extend it in the derived class in the same method. Is this how it is usually done?
public abstract class MyBase
{
void DoStuff()
{
//some common implementation
}
}
public class MyDerived : MyBase
{
void DoStuff()
{
// DoStuff in the base first
// Then DoStuff in here
}
}
are you talking about something like that?
class base
{
protected virtual void method()
{
// do some stuff in base class, something common for all derived classes
}
}
class derived : base
{
public override void method()
{
base.method(); // call method from base
// do here some more work related to this instance of object
}
}
that's not a bad idea, I do use it a lot when I have some common functionality for all derived classes.
If you want to guarantee that the base class logic is run (and not rely on the derived class being polite), you can do this:
public void Method()
{
//Stuff that should always happen in base class
OnMethod();
}
protected virtual void OnMethod()
{
//Default base class implementation that derived class can either override or extend
}
Use base.TheMethod() to run a method in the base class from a derived class.
If you want to run a method of a derived class from a base class, then you have to cast the base class to the derived class. This means that your class needs to be aware of who is deriving it, which breaks encapsulation and should be avoided.

Abstract class does not implement interface

I have an interface so class writers are forced to implement certain methods. I also want to allow some default implemented methods, so I create a abstract class. The problem is that all classes inherit from the base class so I have some helper functions in there.
I tried to write : IClass in with the abstract base, but I got an error that the base didn't implement the interface. Well of course because I want this abstract and to have the users implement those methods. As a return object if I use base I can't call the interface class methods. If I use the interface I can't access base methods.
How do I make it so I can have these helper classes and force users to implement certain methods?
Make sure methods in the base class have the same name as the interface, and they are public. Also, make them virtual so that subclasses can override them without hiding them.
interface IInterface {
void Do();
void Go();
}
abstract class ClassBase : IInterface {
public virtual void Do() {
// Default behaviour
}
public abstract void Go(); // No default behaviour
}
class ConcreteClass : ClassBase {
public override void Do() {
// Specialised behaviour
}
public override void Go() {
// ...
}
}
Move the interface methods into the abstract class and declare them abstract as well. By this, deriving classes are forced to implement them. If you want default behaviour, use abstract classes, if you want to only have the signature fixed, use an interface. Both concepts don't mix.
Having faced with the same problem recently, I've came up with a somewhat more elegant (to my mind) solution. It looks like:
public interface IInterface
{
void CommonMethod();
void SpecificMethod();
}
public abstract class CommonImpl
{
public void CommonMethod() // note: it isn't even virtual here!
{
Console.WriteLine("CommonImpl.CommonMethod()");
}
}
public class Concrete : CommonImpl, IInterface
{
void SpecificMethod()
{
Console.WriteLine("Concrete.SpecificMethod()");
}
}
Now, according to C# spec (13.4.4. Interface mapping), in the process of mapping IInterface on Concrete class, compiler will look up for CommonMethod in CommonImpl too, and it doesn't even have to be virtual in the base class!
The other significant advantage, compared to Mau's solution, is that you don't have to list every interface member in the abstract base class.

Using interfaces on abstract classes in C#

I'm learning C# coming from C++ and have run into a wall.
I have an abstract class AbstractWidget, an interface IDoesCoolThings, and a class which derives from AbstractWidget called RealWidget:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget : IDoesCoolThings
{
void IDoesCoolThings.DoCool()
{
Console.Write("I did something cool.");
}
}
public class RealWidget : AbstractWidget
{
}
When I instantiate a RealWidget object and call DoCool() on it, the compiler gives me an error saying
'RealWidget' does not contain a
definition for 'DoCool'
I can cast RealWidget object to an IDoesCoolThings and then the call will work, but that seems unnecessary and I also lose polymorphism (AbstractWidget.DoCool() will always be called even if i define RealWidget.DoCool()).
I imagine the solution is simple, but I've tried a variety of things and for the life of me can't figure this one out.
You're running into the issue because you used explicit interface implementation (EII). When a member is explicitly implemented, it can't be accessed through a class instance -- only through an instance of the interface. In your example, that's why you can't call DoCool() unless you cast your instance to IDoesCoolThings.
The solution is to make DoCool() public and remove the explicit interface implementation:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool() // DoCool() is part of the abstract class implementation.
{
Console.Write("I did something cool.");
}
}
// ...
var rw = new RealWidget();
rw.DoCool(); // Works!
In general, you use EII in two cases:
You have a class that must implement two interfaces, each of which contains a member that has an identical name/signature to another member in the other interface.
You want to force clients not to depend on the implementation details of your class, but rather on the interface that's being implemented by your class. (This is considered a good practice by some.)
The way you implement the interface is explicit implement void IDoesCoolThings.DoCool(), if you choose implicit implement interface.
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
Then it will work.
Read this :
C# Interfaces. Implicit implementation versus Explicit implementation
Change your declaration to:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
You should do it this way:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget
{
public void DoCool()
{
Console.WriteLine("I did something cool.");
}
}
public class Widget : AbstractWidget, IDoesCoolThings
{
}
Usage:
var widget = new Widget();
widget.DoCool();

Categories

Resources