I am in the process of building some classes, and i have a method in the base class that needs to be included in the deriving classes implementation of the method.
How do i get this performed?
For Example:
public class base{
public base(){}
public void Method(base val){
//Logic implementation
}
}
public class derive:base{
public derive():base(){}
public void Method(derive val){
base.Method(val);
//Logic implementation
}
}
Since you want actual functionality in the base class and augment that functionality in the derived class I would suggest having a public method in the base class that can be called which in turn calls an abstract method that is implemented in the derived class:
public abstract class BaseClass
{
public BaseClass(){}
public void Method(int val)
{
//base class logic here
//now call DoSomething implementation
DoSomething(val);
//some other base class logic here
}
protected abstract void DoSomething(int val);
}
public class Derived : BaseClass
{
protected override void DoSomething(int val)
{
//other logic
}
}
This pattern is known as a Template method pattern or Non-Virtual Interface (NVI) pattern.
Make the method abstract.
public class base{
public base(){}
public abstract void Method(base val);
}
In the derived class you need to mark the method with override
public override void Method(derive val){
If you want to create a default implementation in the base class you mark the method virtual instead of abstract, but then you can not demand that derived classes implement that method.
Related
I was curious if it was possible to create like a parent abstract class that I can define a specific set of methods in but have the children classes include different entity types? Code Example:
public abstract class BaseService
{
public abstract void Add();
public abstract void Delete();
public abstract void Update();
public abstract void Get();
}
Maybe be able to do something like public abstract List<'random type'> GetAll();
But here i would want to override each method with specific parameters that are specific to each of its children:
public class CategoryService : BaseService
{
public override void Add(){ }
public override void Delete(){ }
public override void Update(){ }
public override void Get(){ }
}
However, in my child class, I would want my Get() method to return a specific List<"of Type"> (in this case Category). Furthermore, I might want to do public override Add(int CategoryID) instead of the inherited Add from BaseService.
Is this possible? Thoughts? Am I just crazy? Or am I trying to make this more complicated than it needs to be? I have about 10 different service types that I want to make sure get those generic methods from BaseService.
Thanks in advance!
You could do this if I understand you correctly:
public abstract class BaseService<T>
{
public abstract T Get();
}
Then:
public class CategoryService : BaseService<Category>
{
public override Category Get(){ ... }
}
You can't override methods and have a different signature in the override, but you could use a dictionary/hashtable or something more fancy to pass parameters into the Add method. Passing parameters in using a generic container would mean you are starting to use the query pattern where the parameters in the container determine the query (just for info :-)).
Try using generic type
public abstract List<T> GetAll<T>();
And return appropriate type in your child class
Update
#pw94 answer is also a good way to achieve this, but the only problem is you cannot have multiple type for different methods, only one type will work once you inherit the class.
You can create abstract generic class:
public abstract class BaseService<T>
{
public abstract void Add();
public abstract List<T> Get();
}
And implement:
public class CategoryService : BaseService<int>
{
public override void Add(){ ... }
public override List<int> Get(){ ... }
}
I have the following class with some methods and I would like to use this as a base class of another class.
public class BaseClass
{
public string DoWork(string str)
{
// some codes...
}
// other methods...
}
I don't want this class to be instantiated, but the derived class should still use the original implementation of the methods of its base class.
Is it possible? What should be my modifier?
Since you don't want this class to be instantiated, make it an abstract class. You can still have implementation on the class.
abstract
snippet,
public abstract class BaseClass
{
public virtual string DoWork(string str)
{
// can have implementation here
// and classes that inherits can overide this method because of virtual.
}
// other methods...
}
Make BaseClass abstract:
public abstract class BaseClass
{
// Only available to BaseClass
private string _myString;
public string DoWork(string str)
{
// Available to everyone
return _myString;
}
protected void DoWorkInternal() {
// Only available to classes who inherit base class
}
}
This way, you can define your own code within BaseClass - but it cannot be initialized directly, it must be inherited from.
I created two abstract classes and tried to create a class that inherits from both. But I get an error message.
abstract class AbstractClassOne
{
public abstract void ShowMessage();
public abstract void DisplayName();
}
abstract class AbstractClassTwo
{
public abstract void ShowMessage();
public abstract void DisplayPlace();
}
class DerivedClass : AbstractClassOne, AbstractClassTwo // here under AbstractClassTwo it shows the error "cannot have multiple base classes:"
{
}
So a class can only derive from one abstract class?
If can derive from more than one abstract class, then what happens if both classes define the same method, as is the case above (abstract class one and two both have a method showmessage(), so which one will be in the derived class)?
Multiple inheritance is not allowed by C# but it is allowed by C++.
To answer your question regarding the ShowMessage() method that is a known problem in c++ with multiple inheritance called "The Diamond Problem". see: http://en.wikipedia.org/wiki/Multiple_inheritance
So basically you will have to excitability state to which method you are refereeing when calling it e.g. ParentA::ShowMessage()
if you want to have a type that is polymorphic to 2 other types than you should create two separate interfaces and implement them. and if you want to reuse the same methods than you will have to use compositions.
Interfaces example:
public interface ISomeInterface
{
public void ShowMessage();
public void DisplayName();
}
public class ClassOne : ISomeInterface
{
public void ShowMessage()
{
//implementation
}
public void DisplayName()
{
//implementation
}
}
public class ClassTwo : ISomeInterface
{
public void ShowMessage()
{
//implementation
}
public void DisplayPlace()
{
//implementation
}
}
Interface with reusable Show Message Method using composition:
public class ClassTwo : ISomeInterface
{
private ISomeInterface _MyPrivateReusableComponent = new ClassOne();
public void ShowMessage()
{
_MyPrivateReusableComponent.ShowMessage()
}
public void DisplayPlace()
{
_MyPrivateReusableComponent.DisplayName()
//implementation
}
}
In C# it's not allowed to inherit from more than one class. To do what you want here, you need to use interfaces.
abstract class AbstractClassOne
{
public abstract void ShowMessage();
public abstract void DisplayName();
}
Interface IClassTwo
{
void ShowMessage();
void DisplayPlace();
}
class DerivedClass : AbstractClassOne, IClassTwo
{
}
You can't inherit from more than one class (abstract or otherwise), but in your case the abstract classes are pretty much interfaces, so you can turn them into interfaces and inherit from them (you can inherit from any number of interfaces).
No, abstract class whether having all abstract methods or only some, makes no difference as far as inheritance in concerned. you can inherit only one class (in C#) and as many interfaces as you want.
interface ICanvasTool
{
void Motion(Point newLocation);
void Tick();
}
abstract class CanvasTool_BaseDraw : ICanvasTool
{
protected abstract void PaintAt(Point location);
public override void Motion(Point newLocation)
{
// implementation
}
}
class CanvasTool_Spray : CanvasTool_BaseDraw
{
protected abstract void PaintAt(Point location)
{
// implementation
}
public override void Tick()
{
// implementation
}
}
This doesn't compile. I could add an abstract method "Tick_Implementation" to CanvasTool_BaseDraw, then implement ICanvasTool.Tick in CanvasTool_BaseDraw with a one-liner that just calls Tick_Implementation. Is this the recommended workaround?
The way to do this is to add an abstract void Tick() method to CanvasTool_BaseDraw and override it in CanvasTool_Spray.
Not every programming language does it this way. In Java you do not have to add an abstract method for every method in the interface(s) you implement. In that case your code would compile.
You have a few things mixed up..
Motion should be virtual in your base class so that it may be overridden in child classes.
Your child class needs to make PaintAt override instead of abstract.
The base class needs to implement Tick as an abstract method.
interface ICanvasTool
{
void Motion(Point newLocation);
void Tick();
}
abstract class CanvasTool_BaseDraw : ICanvasTool
{
protected abstract void PaintAt(Point location);
public virtual void Motion(Point newLocation)
{
// implementation
}
public abstract void Tick();
}
class CanvasTool_Spray : CanvasTool_BaseDraw
{
protected override void PaintAt(Point location)
{
// implementation
}
public override void Tick()
{
// implementation
}
}
An alternative is don't list the interface in the base classes declaration. Each derived class must list ICanvasTool in its declaration if it wants to be implementing the interface and then it is solely responsible for implementing the rest of the interface. One drawback I can see is you can't explicitly implement the interface methods in the base class (ie no ICanvasTool:Motion), but otherwise this is a fairly low overhead version.
public interface ICanvasTool
{
void Motion(Point newLocation);
void Tick();
}
public abstract class CanvasTool_BaseDraw
{
public void Motion(Point newLocation)
{
//some implementation
}
}
public class CanvasTool_Spray : CanvasTool_BaseDraw, ICanvasTool
{
public void Tick()
{
//some implementation
}
}
Note: I left out PaintAt because it wasn't necessary for the example.
As was stated before, an interface is a contract and therefore all of it needs to be implemented. If a a consumer tried to call something that is defined in the interface but not implemented in the concrete class the application would crash.
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";
}
}