Is it possible to implement the interface in an abstract class and change the implemented interface method into abstract?
interface ITest
{
string GetData();
int ProcessData();
}
public abstract class MyAbstract:ITest
{
public int Process()
{
// some code
}
public abstract string GetData(); // Change the implemented method into abstract Is it Possible?
}
Yes, you can do it. Simply add the abstract keyword and remove the implementation. There's obviously a pitfall with this. Any class which inherits from your abstract class will have to implement GetData themselves now. Depending on how many classes are children of MyAbstract, this may lead to a lot of work and code duplication.
In your case, where the method in question is declared by the interface which MyAbstract implements, you can actually just drop GetData completely and rely on the declaration of this function in ITest.
Related
i don't seem to find an answer for my kind of problem.
So, let's say have an interface
public interface IBase {
void MethodBase();
}
and a class implementing this, BaseClass not abstract). Now i must have another class that should implement the base interface but also to add new methods (extending the default behaviour), so i'm making my second interface like this
public interface IChild : IBase {
void MethodChild();
}
and a class that implements this one, say ChildClass.
All good for now. Now the problem with IoC and Autofac. I want, on application start up, to conditionally register as IBase (because the project allready uses IBase in other parts) the first or the second concrete class.
The question is, in a consuming class, in its constructor, should i have a parameter of type IBase and in one of its methods should i do
(baseTypeParam as IChild)
and use one of the new methods added by IChild interface?
Because if the constructor parameter is of type IChild and as i said, i register IBase with ChildClass then everything fails because, obviously, there is no IChild registered.
Or i am missing something about how to extend (design pattern?) the base interface with new methods, that the BaseClass should not implement.
You can't cast a parent to a child as you don't know that the implementation you are referencing by IBase actually implements IChild methods. If your class requires methods defined in IChild, it should ask for IChild.
A cleaner solution would to have two implementations of IBase, and not have IChild inherit from IBase. Then you can register which ever implementation of IBase you want depending on your start up parameter, have have a separate class implement IChild.
public interface IBase {
void DoSomething();
}
public class Base1 : IBase{
public void DoSomething() { \\do something }
}
public class Base2 : IBase{
public void DoSomething() { \\do something }
}
public interface IChild{
void DoSomethingElse();
}
public class Child1{
public void DoSomethingElse() { \\do something else }
}
public class IDoSomething{
public IDoSomething(IBase base){}
}
public class IDoMoreThings{
public IDoMoreThings(IBase base, IChild child){}
}
I understand that it might have made sense for IChild to inherit from IBase but without more context I can't really say.
Hope I understood you question correctly.
Is this OOP approach doomed to fail or is there some merit in this?
Before I understood abstract classes I was getting more or less the same benefits of code reuse by using an interface class + a regular class that implements certain methods of the interface. For example
public interface IMyService
{
String Helloword1();
String Helloword2();
String Helloword3();
}
public class MyService
{
public String Helloword1(){return "1";}
public String Helloword2(){return "2";}
//Helloworld3 is not here so I would be forced to provide implementation in any subclass
//very similar to calling abstract on a method
}
public class SubClass1: MyService, IMyService
{
public String Helloword3(){return "3";}
}
public class SubClass2: MyService, IMyService
{
public new String Helloword2(){return "override method";}
public String Helloword3(){return "3";}
}
Can anyone see of any advantage of doing this or is this really providing the same advantages as an abstract class?
Can anyone see of any advantage of doing this or is this really providing the same advantages as an abstract class?
There is a big disadvantage to doing this. You allow people to subclass MyService without implementing Helloword3, since that's not part of the contract.
An abstract class would enforce that the type implements that member. Here, you trust that the user will implement the "required" interface.
In your example someone can actually construct an instance of MyService and use it without the use of the abstract method.
Honestly, there isn't even really any need to inherit form MyService in your two sub classes. If MyService can be created concretely, that type can be composed, rather than inherited from.
The real value in an abstract class is where the concrete methods actually use the abstract methods. Being able to write things like this:
public abstract class Foo
{
public abstract Guid CreateUniqueIdentifier();
public void SaveToDatabase()
{
Guid guid = CreateUniqueIdentifier();
//do stuff with guid
}
}
You cannot do something like this using your pattern; the concrete methods can never be dependent on the not-yet-implemented methods.
Look at the following non-compiling C# code:
public abstract class Operation
{
public abstract void Work();
}
public abstract class Operation<T> : Operation
{
public override void Work()
{
Work();
}
public new abstract T Work();
}
While it's possible to introduce a new name overwriting one in a base class, it doesn't seem to be possible to still override the previous method in the base class - in order to do the override, one would have to define a conflicting method.
Is there something I overlooked or is this impossible to do?
The first option, as much as you may not like to hear it, is that you could simply come up with a new method name, rather than shadowing the other method:
However, another more radical change would be for Operation to be an interface, rather than an abstract class with no implementation.
public interface IOperation
{
void Work();
}
At this point you can also make the inheriting type an interface as well, since it doesn't need an implementation:
public interface IOperationWithResult<T> : IOperation
{
T Work();
}
Or you could make it an abstract class that simply implements the interface explicitly:
public abstract class Operation<T> : IOperation
{
public new abstract T Work();
void IOperation.Work()
{
Work();
}
}
Personally I'd go with two interfaces and no abstract classes here, given that these types aren't conceptually providing any real implementation, nor are they conceptually abstract types. Their purpose is to define a contract that many otherwise unrelated types could meet (namely the ability to do some work or compute some result) which is precisely what interfaces are for.
I get compile errors with this overcomplicated class hierarchy. I wonder if it has anything to do with trying to do DeepCopy() with generics mixed in.
public interface IInterface<T>
{
IInterface<T> DeepCopy();
}
public abstract class AbstractClass<T> : IInterface<T>
{
public abstract IInterface<T> DeepCopy(); // Compiler requires me to declare this public
}
// Everything good at this point. There be monsters below
public class ConcreteClass: AbstractClass<SomeOtherClass>
{
ConcreteClass IInterface<SomeOtherClass>.DeepCopy()
{
return new ConcreteClass;
}
}
I get the following compiler errors:
'IInterface<...>.DeepCopy()': containing type does not implement interface 'IInterface<SomeOtherClass>'
Return bool
Change ConcreteClass IInterface<SomeOtherClass>.MyMethod()
to bool IInterface<SomeOtherClass>.MyMethod()
Edit:
And then you can not use an explicit implementation of the interface, since that does not fulfill the contract of the abstract class you need to implement it like this.
public override IInterface<SomeOtherClass> DeepCopy()
{
return new ConcreteClass();
}
The errors are because the return type of DeepCopy() do not match the declaration in the interface.
Besides that you have a different problem. The abstract class already implements the method from the interface, but in the concrete class you do not implement the abstract method. Instead of the implementation you now have, you should have the following implementation:
public override IInterface<SomeOtherClass> DeepCopy()
{
}
This will implement the abstract method in the abstract class which automatically implements the method in the interface. The reason you need to implement the abstract method in the abstract class, is because that class needs to implement the interface. That is a requirement of a class.
In the following example, the class Derived implements the abstract method method from class Main. But I can't think of a reason to fill in the method body in the abstract Derived class' implementation. Surely I should only implement abstract methods within real classes.
So how can I avoid doing it? What else can I do?
abstract class Main
{
public abstract void method();
}
abstract class Derived : Main
{
public override void method()
{
}
}
class RealClass : Derived
{
}
Usually if someone has specified that an abstract class has an abstract method, it's either because that class depends on that method for some of what it does, or it's because it's part of an expected API that it wouldn't make sense for the parent class to implement at this time. In either case, there must be an implementation once you get to a non-abstract implementation of the class.
Note also that if you are implementing an interface, you are required to state how that interface will be implemented, even if you just call the member abstract and pass the responsibility onto the subclass
public interface IPet {string GetNoise(); int CountLegs(); void Walk();}
public abstract class Pet : IPet
{
public string Name {get; set;}
public abstract string GetNoise(); // These must be here
public abstract int CountLegs();
public abstract void Walk();
}
When it comes to implementing the sub-class, you have a few choices depending on the circumstances. If your implementation is itself an abstract class, you shouldn't need to implement the abstract method.
public abstract class Quadruped : Pet
{
public override int CountLegs () { return 4; }
}
If your implementation is non-abstract, but the standard reason for the method in question really doesn't apply in your circumstance, you can do a no-op method (in the case of void methods), or return some dummy value, or even throw a NotImplementedException to indicate that the method should never have been called in the first place.
public class Fish : Pet
{
public override string GetNoise() {return "";} // dummy value: fish don't make noise
public override int CountLegs() {return 0;}
public override void Walk() {} // No-op
// public override void Walk() { throw new NotImplementedException("Fish can't walk"); }
}
Does that answer your question?
If there's no implementation of method in Derived then you can just make Derived abstract as well:
abstract class Derived : Main
{
}
class RealClass : Derived
{
public override void method() { ... }
}
EDIT: To clarify the comments - if there is no meaningful implementation of an abstract method in a subclass, then one does not need to be provided. This will however require that the derived class is itself abstract, and an implementation must be provided somewhere in the chain of descendant classes to some concrete subclass. I am not saying you should leave the implementation of method empty, as it is in the question, but rather you remove the override in Derived and mark the class abstract. This forces RealClass to provide an implementation (or itself be marked abstract).
All non-abstract descendant classes must provide concrete implementations of abstract methods. If you don't provide an implementation, then it's impossible to call that method.
If some concrete classes don't have an obvious proper implementation of a abstract method then your object design is incorrect. Maybe you should have an abstract class with some abstract methods (but not all). That class could have an both an abstract descendant and some concrete descendants.