I'm a bit confused at some code I recently came across. Here is a snippet. First of the Abstract Class Definition and then of the Class that inherits from it:
public abstract class BaseClass
{
protected static void MapEntityToModel(string paramOne, List<TypeDef> types)
{
// Some Logic Here
}
protected static void MapModelToEntity(ModelType model, ResultType result)
{
// Some Logic Here
}
}
public class BaseExtension : BaseClass
{
public static ViewModel MapModelToViewModel(Model m)
{
var result = new ViewModel();
// Some Logic Here
return result;
}
public static List<ViewModel> MapModelsToViewModels(List<TModel> models)
{
return models.Select(m => MapModelToViewModel(m)).ToList();
}
public static Model MapViewModelToModel(ViewModel v)
{
var result = new Model();
// Some Logic Here
return result;
}
}
So my understanding and usage of an Abstract Class has always been that any abstract methods within an Abstract Class must be overridden in the inherited Classes. If a method within an Abstract Class is not declared abstract, the derived Class can create an instance of itself within a method and directly call the non-abstract method of the Abstract Class.
But in either case the methods of the Abstract Class are used in the Derived Class. However, given the previous code snippets the Derived Class has no directly mapped signature or usage.
What then is the purpose of the Abstract Class in this particular scenario and why does it compile without error? I obviously am missing some concept of the Abstract Class and its appropriate implementation.
So my understanding and usage of an Abstract Class has always been that any abstract methods within an Abstract Class must be overridden in the inherited Classes
That is true, but the methods are not abstract, they are concrete (and static). Only virtual or abstract instance methods can be overridden.
What then is the purpose of the Abstract Class in this particular scenario and why does it compile without error?
Since the class has no abstract methods or properties I do not see why it is abstract, other than the author doesn't instances created for some reason.
static methods are not part of instances of the class
when you are saying a class is abstract you are saying that you cannot create instances of it.
Abstract on those classes serves no purpose apart from highlighting that creating instances of them is pointless as all methods are static anyway.
Also inheriting from them seems a little pointless as nothing is inherited - all the members are static.
You may as well have only the inherited class and make the base class an empty interface and move the static methods in it into the inherited class (an interface is in effect an abstract class with no method implementations - but you would normally have what are in effect abstract method definitions though)
abstract class a
{
public abstract string look();
public static string lookStatic()
{
return "look";
}
}
class b : a
{
public override string look()
{
return "look member";
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(b.lookStatic());
var test = new b();
Console.WriteLine(test.look());
var c = (a) test;
Console.WriteLine(c.look());
Console.ReadLine();
}
}
Related
In case I want any class inherits/implements some methods which is better an interface or an abstract class contains these abstract methods only and acts as an interface. I know the difference between the interface and the abstract class well but in this case do the two have the same function or there are different something?
I think we can feel free to use one of them but still I take the side of interface because my aim is to enforce any class to implement these methods and it is the job of interface.
I agree an abstract class with no concrete behavior seems a little pointless so I would favour an interface.
Abstract classes are far more useful when bringing together some common behavior that cannot be overridden along with some elements that can eg) template methods
public abstract class Base
{
public void TemplateMethod()
{
AbstractMethod1();
AbstractMethod2();
}
public abstract void AbstractMethod1();
public abstract void AbstractMethod2();
}
public class Concrete : Base
{
public override void AbstractMethod1()
{
Console.Write("Override Abstract Method 1");
}
public override void AbstractMethod2()
{
Console.Write("Override Abstract Method 2");
}
}
public class Main
{
public Main()
{
var concrete = new Concrete();
concrete.TemplateMethod();
}
}
I have an abstract base class:
public abstract class BaseClass
{
public double CommonMethodForAllSubClasses(double parameter)
{
//common implementation
return 0;
}
public abstract double MethodThatMustBeDefinedInSubClasses(double parameter);
}
And a class hierarchy under it.
I want to make, in another assembly, an Extension class for Base class and its subclasses. I thought to do it with a static class with a methods which receive as parameter:
public static Method(this BaseClass, ...)
But I want this static Method to be defined for all subclasses from BaseClass. I know I can't do a static abstract method but I want to avoid to implement these methods in the class itself... And it would be very good that the compiler "tells me" that these methods must be redefined for sub-classes.
But I want this static Method to be defined for all subclasses from BaseClass.
Your extension method would be callable from instance of derived class. But I guess that's not what you meant.
And it would be very good that the compiler "tells me" that these methods must be redefined for sub-classes.
Implementing it as a regular abstract method on the base class is the only way to achieve that.
Is this what you want?
public abstract class BaseClass
{
protected abstract void MethodThatMustBeDefinedInSubClasses();
}
public class ChildClass : BaseClass
{
protected override void MethodThatMustBeDefinedInSubClasses()
{
Console.WriteLine("Do");
}
}
public static class BaseClassExtensions
{
public static void DoExtension(this BaseClass foo) { }
public static void DoExtension(this ChildClass bar) {}
}
You can specify the extension method for every derived class in the hierarchy and provide a specific implementation for it.
About the "compiler telling you" about a extension method, I think that's not possible, because the extension method is just "syntactic sugar". The extension method can be used like this:
var foo = new BaseClass();
foo.DoExtension();
But actually is just like a normal static class:
var foo = new BaseClass();
BaseClassExtensions.DoSomething(foo);
And the compiler cannot warning you that you should make a static class with a method that should accept a specific type.
I have written the following code in C#.NET
public interface IWork
{
void func();
}
public abstract class WorkClass
{
public void func()
{
Console.WriteLine("Calling Abstract Class Function");
}
}
public class MyClass:WorkClass,IWork
{
}
On compiling, I didn't get any error. Compiler is not forcing me to implement the method "func();" in "MyClass", which has been derived from the interface "IWork".Latter, I can gracefully create a instance of the class "MyClass" and call the function "func()". Why the compiler is not forcing me to implement the "func()" method in the "MyClass"(which has been derived from "IWork" interface? Is it a flaw in C#?
While reading about this subject, I found I couldn't easily put it all together in my head, so I wrote the following piece of code, which acts as a cheat-sheet for how C# works. Hope it helps someone.
public interface IMyInterface
{
void FunctionA();
void FunctionB();
void FunctionC();
}
public abstract class MyAbstractClass : IMyInterface
{
public void FunctionA()
{
Console.WriteLine( "FunctionA() implemented in abstract class. Cannot be overridden in concrete class." );
}
public virtual void FunctionB()
{
Console.WriteLine( "FunctionB() implemented in abstract class. Can be overridden in concrete class." );
}
public abstract void FunctionC();
}
public class MyConcreteClass : MyAbstractClass, IMyInterface
{
public override void FunctionB()
{
base.FunctionB();
Console.WriteLine( "FunctionB() implemented in abstract class but optionally overridden in concrete class." );
}
public override void FunctionC()
{
Console.WriteLine( "FunctionC() must be implemented in concrete class because abstract class provides no implementation." );
}
}
class Program
{
static void Main( string[] args )
{
IMyInterface foo = new MyConcreteClass();
foo.FunctionA();
foo.FunctionB();
foo.FunctionC();
Console.ReadKey();
}
}
Gives the following output:
FunctionA() implemented in abstract class. Cannot be overridden in concrete class.
FunctionB() implemented in abstract class. Can be overridden in concrete class.
FunctionB() implemented in abstract class but optionally overridden in concrete class.
FunctionC() must be implemented in concrete class because abstract class provides no implementation.
To better understand the concept behind interfaces, I just give you the correct code of your implementation:
public interface IWork{
void func();
}
public abstract class WorkClass,IWork{
public void func(){
Console.WriteLine("Calling Abstract Class Function");
}
}
public class MyClass:WorkClass{
...
}
The basic rule: You need to include the interface always where the implementation is. So if you create a method within an abstract classes and define an interface of this method, you'll need to implement the interface into your abstract class and then all subclasses will automatically implement this interface.
As a matter of fact, interfaces have 2 kind of functions you can use them for:
1) As a "real" interface providing a generic handling of any class implementing the interface, so you can handle several kind of classes just by one interface (without knowing their real class names). While "handling" means: Calling a method.
2) As a help for other (framework) programmers not to mess up with your code. If you want to be sure that an method won't be replaced with another name, you define an interface for your class containing all "must have" method names. Even if the method is called nowhere, your programmer will get an compile error message when he changed the method name.
Now you can easily handle your Myclass just by the interface IWork.
Because the abstract class implements the interface.
If your class MyClass would not inherit from WorkClass you would get an error saying 'MyClass' does not implement interface member 'IWork.func()'.
But you also inherit from WorkClass, which actually implements the methods that the interface requires.
You can mark func() as abstract if you want to force the classes that inherits from it to implement it like this:
public abstract class WorkClass
{
public abstract void func();
}
I tried with the classes above in my solution.
It inherits the abstract class so the derived class have the func() method definition. This is the reason it was not able to show compiled errors.
func() is not marked as abstract in the WorkClass so you don't need to implement it in any classes that derive from WorkClass.
WorkClass implements the IWork interface so you don't need to implement it in MyClass because it inherits func() from WorkClass.
Since the func method in the abstract class is a non-virtual method, so the compiler thinks this method is a implementation of the interface.
When you extend MyClass to WorkClass, the method func() (which has been defined), is inherited.
So, when the interface IWork is implemented, the method 'func()' has already been defined. So, there are no more undefined methods in MyClass.
So, the class MyClass is a concrete class, due to which you are able to create a MyClass object without any compilation errors.
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.
I am creating an object structure and I want all sub classes of the base to be forced to implement a method.
The only ways I could think of doing it were:
An abstract class - Would work but the base class has some useful helper functions that get used by some of the sub classes.
An interface - If applied to just the base class then the sub classes don't have to implement the function only the base class does.
Is this even possible?
N.B. This is a .NET 2 app.
You can have abstract methods in a class with other methods that are implemented. The advantage over an interface is that you can include some code with your class and have the new object be forced to fill in the details for the abstract methods.
public abstract class YourClass
{
// Your class implementation
public abstract void DoSomething(int x, int y);
public void DoSomethingElse(int a, string b)
{
// You can implement this here
}
}
An abstract class - Would work but the
base class has some useful helper
functions that get used by some of the
sub classe
An abstract class doesn't require all functions it provides to be abstract.
abstract class Base {
public void Foo() {} // Ordinary method
public virtual void Bar() {} // Can be overridden
public abstract void Xyz(); // This one *must* be overridden
}
Note that if you replace public with protected, the marked method will be only visible to base classes and subclasses.
An interface - If applied to just the
base class then the sub classes don't
have to implement the function only
the base class does.
This is not entirely correct. If the base class is abstract, you can mark methods that belong to the interface as abstract, and force the implementation in the subclasses.
That brings an option you didn't mention: to use both. You have an IFoo interface, and a FooBase abstract base class the implements it, or part of it. This provides subclasses with a "default" implementation of the interface (or part of it), and also lets you inherit from something else and still implement the interface, or if you want to implement the interface but not inherit the base class implementation. An example might help:
// Your interface
interface IFoo { void A(); void B; }
// A "default" implementation of that interface
abstract class FooBase : IFoo
{
public abstract void A();
public void B()
{
Console.WriteLine("B");
}
}
// A class that implements IFoo by reusing FooBase partial implementation
class Foo : FooBase
{
public override void A()
{
Console.WriteLine("A");
}
}
// This is a different class you may want to inherit from
class Bar
{
public void C()
{
Console.WriteLine("C");
}
}
// A class that inherits from Bar and implements IFoo
class FooBar : Bar, IFoo
{
public void A()
{
Console.WriteLine("Foobar.A");
}
public void B()
{
Console.WriteLine("Foobar.B");
}
}
Yes, and if all the classes you need to do this for are logically subclasses of an existing abstract base class, then add an abstract method to the base class... This is better than an interface because it allows you to add implementation later (by changing abstract base class method to virtual method with a default implementation), if/when it turns out that, say, eight of ten derived classes will have the same implementation, and say, only two of them differ...
EDIT: (based on thread in comments below) The base class must be declared as abstract to do this... You can't have an abstract method in a non-abstract class because a non-abstract class can be instantiated, and if an instance of it was created, there wouldbe NO implementation for that method. So this is illegal. By declaring the base as abstract, you inhibit instantiation of the class. Then, only non-abstract derived classes can be instantiated, where, (because the base method is abstract) you MUST add an implementation for that method.
And full worker sample with params (.netcore 2.2):
class User{
public string Name = "Fen";
}
class Message{
public string Text = "Ho";
}
// Interface
interface IWorkerLoop
{
// Working with client message
string MessageWorker(string msg);
}
// AbstractWorkerLoop partial implementation
public abstract class AbstractWorkerLoop : IWorkerLoop
{
public User user;
public Message msg;
// Append session object to loop
public abstract AbstractWorkerLoop(ref User user, ref Message msg){
this.user = user;
this.msg = msg;
}
public abstract string MessageWorker(string msg);
}
// Worker class
public class TestWorkerLoop : AbstractWorkerLoop
{
public TestWorkerLoop(ref User user, ref Message msg) : base(user, msg){
this.user = user;
this.msg = msg;
}
public override string MessageWorker(string msg){
// Do something with client message
return "Works";
}
}