Require child classes to call super.doSomething() if overrides it? - c#

I have a abstract class named Vehicle:
public abstract class Vehicle {
public void run() {
addToRunningVehicleList();
}
}
I want that every classes that extends Vehicle must call super.run() if they override run method. For example:
public class Car {
#Override
public void run() { // Error here because does not call super.run()
carRunningAnimation();
}
}
Is it possible in OOP concept, or Java/C#?
EDIT: Following Petar Ivanov, I have this code:
public abstract class Vehicle {
public final void run() {
Log.e("Run", "Add To List");
runImp();
}
public void runImp() {}
}
public class Car extends Vehicle {
#Override
public void runImp() {
Log.e("Run", "Run in Car");
}
}
However, it's not very good for public APIs. When extending Vehicle, the end-users must override runImp, but then they have to call run() method, so I have to make public both run and runImp, which make nothing better.

Here is how I would do it (C#):
public abstract class Vehicle {
public void Run() {
//code that will always run
addToRunningVehicleList();
//code that can be overriden
RunImpl();
}
protected virtual void RunImpl() { }
}
public class Car : Vehicle {
protected override void RunImpl() {
carRunningAnimation();
}
}
You can make the RunImpl protected to make sure it can't be called outside the subclasses of Vehicle.

If you need to require certain code to run in addition to the child class' implementation, perhaps you need to split this into multiple methods:
(C# example)
public abstract class Vehicle
{
public void Run()
{
// Code that always runs before...
RunCore();
// Code that always runs after...
}
protected virtual void RunCore()
{
}
}

Remember who you are designing for. If it's an internal piece of code a comment will suffice. If it's a public API and you want people to inherit then you need to write a piece of documentation telling them to do it.
In C# you can do some sneaky stuff with virtual and non-virtual methods but in Java as all inheritence is virtual it's a lot harder to enforce this without using an abstract base class.
Using an ABT may limit your ability to provide further inheritence and force modification of other code.

Related

Exposing methods of a class only to a Manager class?

Let's say I have a Screen class. This class has few abstract methods like EnterScreen, ExitScreen that are protected.
I want to change screen only through a ScreenManager class but I cannot since both methods are protected.
If I make methods public, I can make a call to both methods in ScreenManager but then I expose them to other classes that accept Screen class as a parameter thus they can easily call Enter and Exit Screen.
Any idea of how can make a call only through ScreenManager and without exposing both methods to other classes? (Only ScreenManager can change screens)
Thanks in advance.
EDIT: #derHugo provided an answer that I should use namespaces and internal keyword, however, I've already tried this but it's not working as expected (methods of the internal class are still accessible in the namespace that is not the same as the Screen class). I'll provide code below and behavior I'm getting.
namespace Test
{
public abstract class Screen<T>
{
internal abstract void EnterScreen();
internal abstract void ExitScreen();
}
}
// Seperate class
namespace Test
{
public class SimpleScreen : Screen<UnityEngine.GameObject>
{
internal override void EnterScreen() { }
internal override void ExitScreen() { }
}
}
// This DOESN'T HAVE A NAMESPACE but I can STILL access the internal methods of the Screen class.
public class GameManager : MonoBehaviour, IInitializable<SimpleScreen>
{
public void Initialize(SimpleScreen screen)
{
// I CAN REFERENCE .Enter & ExitScreen methods here
}
}
One way to approach it is to inject your screenManager instance into your Screen and pass it these Actions that it has privileged access to:
public abstract class Screen<T>
{
protected abstract Action GetEnterScreenAction();
protected abstract Action GetExitScreenAction();
public Screen(ScreenManagerInterface screenManager)
{
screenManager.SetScreenActions(GetEnterScreenAction(), GetExitScreenAction());
}
}
public class SimpleScreen : Screen<UnityEngine.GameObject>
{
private void EnterScreen() { }
private void ExitScreen() { }
protected override Action GetEnterScreenAction() { return EnterScreen;}
protected override Action GetExitScreenAction() { return ExitScreen;}
public SimpleScreen(ScreenManagerInterface screenManager, ....) : base(screenManager) { }
}
public interface ScreenManagerInterface
{
void SetScreenActions(Action enterScreenAction, Action exitScreenAction);
}
A need to make some public methods available only to some other classes may indicate a design flaw in classes relationship. Maybe moving part of the responsibilities into ScreenManager itself could solve this problem.
As you declare Screen class abstract you intent on public or protected methods that can be overridden. So the only option for you to hide them from other classes is to make them protected.
And the only way to access protected members is from the class itself, derived or nested type.
You can make the class ScreenManger nested inside your Screen and it will default to private or make it public. If I understood your question correctly I made an example but without Unity.
I hope it can help
public interface IInitializable<T>
{
}
public class SimpleScreen : Screen<object>
{
protected override void EnterScreen() { }
protected override void ExitScreen() { }
public class ScreenManager
{
private SimpleScreen _simpleScreen;
public void Awake()
{
_simpleScreen.EnterScreen();
}
}
}
public abstract class Screen<T>
{
protected abstract void EnterScreen();
protected abstract void ExitScreen();
}
public class GameManager : IInitializable<SimpleScreen>
{
public void Initialize(SimpleScreen screen)
{
var screenManager = new SimpleScreen.ScreenManager();
screenManager.Awake();
screen.
}
}

Insert code from child class method in middle of base class method [duplicate]

I have a base class and a class inheriting base. The base class has several virtual functions that the inherited class may override. However, the virtual functions in the base class has code that MUST to run before the inherited class overrides get called. Is there some way that I can call the base classes virtual functions first then the inherited class overrides. Without making a call to base.function().
I know I can simply make two functions, one that gets called, the other virtual. But is there a way I can keep the same names as well? I know I may need to change some things around.
class myBase
{
public virtual myFunction()
{ /* must-run code, Called first */ }
}
class myInherited : myBase
{
public override myFunction()
{ /* don't use base.myFunction();,
called from base.myFunction(); */ }
}
Similar question here.
C# doesn't have support for automatically enforcing this, but
you can enforce it by using the template method pattern. For example, imagine you had this code:
abstract class Animal
{
public virtual void Speak()
{
Console.WriteLine("I'm an animal.");
}
}
class Dog : Animal
{
public override void Speak()
{
base.Speak();
Console.WriteLine("I'm a dog.");
}
}
The trouble here is that any class inheriting from Animal needs to call base.Speak(); to ensure the base behavior is executed. You can automatically enforce this by taking the following (slightly different) approach:
abstract class Animal
{
public void Speak()
{
Console.WriteLine("I'm an animal.");
DoSpeak();
}
protected abstract void DoSpeak();
}
class Dog : Animal
{
protected override void DoSpeak()
{
Console.WriteLine("I'm a dog.");
}
}
In this case, clients still only see the polymorphic Speak method, but the Animal.Speak behavior is guaranteed to execute. The problem is that if you have further inheritance (e.g. class Dachshund : Dog), you have to create yet another abstract method if you want Dog.Speak to be guaranteed to execute.
A common solution that can be found in the .NET Framework is to split a method in a public method XXX and a protected, virtual method OnXXX that is called by the public method. For your example, it would look like this:
class MyBase
{
public void MyMethod()
{
// do something
OnMyMethod();
// do something
}
protected virtual void OnMyMethod()
{
}
}
and
class MyInherited : MyBase
{
protected override void OnMyMethod()
{
// do something
}
}
public abstract class BaseTemp
{
public void printBase() {
Console.WriteLine("base");
print();
}
public abstract void print();
}
public class TempA: BaseTemp
{
public override void print()
{
Console.WriteLine("TempA");
}
}
public class TempB: BaseTemp
{
public override void print()
{
Console.WriteLine("TempB");
}
}
There is no way to do what you're seeking other than the 2 ways you already named.
Either you make 2 functions in the base class, one that gets called and the other virtual.
Or you call base.functionName in the sub-class.
Not exactly. But I've done something similar using abstract methods.
Abstract methods must be overriden by derived classes. Abstract procs are virtual so you can be sure that when the base class calls them the derived class's version is called. Then have your base class's "Must Run Code" call the abstract proc after running. voila, your base class's code always runs first (make sure the base class proc is no longer virtual) followed by your derived class's code.
class myBase
{
public /* virtual */ myFunction() // remove virtual as we always want base class's function called here
{ /* must-run code, Called first */
// call derived object's code
myDerivedMustcallFunction();
}
public abstract myDerivedMustCallFunction() { /* abstract functions are blank */ }
}
class myInherited : myBase
{
public override myDerivedMustCallFunction()
{ /* code to be run in derived class here */ }
}
What do you think of this?
class myBase
{
public void myFunctionWrapper()
{
// do stuff that must happen first
// then call overridden function
this.myFunction();
}
public virtual void myFunction(){
// default implementation that can be overriden
}
}
class myInherited : myBase
{
public override void myFunction()
{
}
}

Avoiding the call to protected member of base class

Here's a silly example of a tree structure where every node does a different kind of an action, but exactly one node (any node) has to do some common work at the start and end of a project.
public abstract class Employee
{
public void StartProject()
{
AnnounceProjectToNewspapers();
DoActualWork();
PutProductOnMarket();
}
protected abstract void DoActualWork();
private void AnnounceProjectToNewspapers() { }
private void PutProductOnMarket() { }
}
public class Engineer : Employee
{
protected override void DoActualWork()
{
// Build things.
}
}
public class Salesman : Employee
{
protected override void DoActualWork()
{
// Design leaflets.
}
}
public class Manager : Employee
{
protected override void DoActualWork()
{
// Make gantt charts.
// Also delegate.
foreach (var subordinate in subordinates)
// ...but then compiler stops you.
subordinate.DoActualWork();
}
private List<Employee> subordinates;
}
The problem is, you can't call the protected method DoActualWork() on a base class.
Two solutions I see are:
Make DoActualWork() public. But this would allow anyone to call it without AnnounceProjectToNewspapers() or PutProductOnmarket().
Make DoActualWork() internal. But this would prevent other assemblies from using the "management system".
Is there a standard work-around people use to avoid this limitation?
I have a couple of ways to achieve what you need.
The first and obvious way is to inherit Engineer and Salesman from Manager instead of employee. But this makes the inheritance sound ridiculous. Every Engineer is a Manager (I wish that was true.)
As you've mentioned,
Make DoActualWork() public
This does work. To then prevent any other method from calling DoActualWork() you could find out the type of the class using reflection/stacktrace and block invalid types. Refer here
But both these methods feel clanky to me. There should definitely be a way to design the classes to get what you need.
I came up with a solution like this (this has not been tested)
public interface IEmployee {
void StartProject();
void DoWork();
}
public abstract class EmployeeBase : IEmployee {
public void StartProject() {
AnnounceProjectToNewspapers();
DoActualWork();
PutProductOnMarket();
}
void IEmployee.DoWork() {
// Maybe set a flag to see whether the work has been already done by calling StartProject().
this.DoActualWork();
}
protected abstract void DoActualWork();
private void AnnounceProjectToNewspapers() { }
private void PutProductOnMarket() { }
}
public class Employee : EmployeeBase {
protected override void DoActualWork() {
// Log system Action
}
}
public class Engineer : Employee {
protected override void DoActualWork() {
// Build things.
}
}
public class Salesman : Employee {
protected override void DoActualWork() {
// Design leaflets.
}
}
public class Manager : Employee {
protected override void DoActualWork() {
DoWorkInternal();
}
private void DoWorkInternal() {
foreach (var subordinate in subordinates)
subordinate.DoWork();
}
private List<IEmployee> subordinates;
}
Thinking about all the responses, a compromise just crossed my mind: use an indirect call through an internal method. In other words, a poor man's friend declaration by informal comments.
Here are the relevant bits:
public abstract class Employee
{
// Meant to be called by Manager class only.
internal void FollowTheLeader()
{
DoActualWork();
}
}
public class Manager : Employee
{
protected override void DoActualWork()
{
// Make gantt charts.
// Also delegate.
foreach (var subordinate in subordinates)
// ...but then compiler stops you.
subordinate.FollowTheLeader();
}
}
Deriving classes from other assemblies will be able to customize the work Employees and Managers do, but they will not be able to make anyone do work without proper context.
Classes from within the assembly will be able to do anything, but let's assume you can trust the people developing the framework to follow the instructions in comments.

Some trouble with private abstract methods

Let's say I make a major class Car - and I want this class to be abstract. Abstract because this is my major class, nobody should make an object of this class. This class should be only there as "backbone".
I want that classes can be created only from subclasses of Car (lets say Mercedes, Ferrari...). Because every car should have methods like StartEngine I put it into the major class. Let's say I have this:
abstract class Car
{
public string Name { get; set; }
public abstract void StartEngine();
private abstract bool CheckGasoline();
//and so on...
}
class Mercedes : Car
{
private override bool CheckGasoline()
{
//somehow check gasoline and return whatever...
}
public override void StartEngine()
{
if (CheckGasoline())
//start engine...
}
}
Well this is not gonna work. Because of private abstract:
virtual or abstract members cannot be private
So ill make every private method to protected:
abstract class Car
{
public string Name { get; set; }
public abstract void StartEngine();
protected abstract bool CheckGasoline();
//and so on...
}
class Mercedes : Car
{
protected override bool CheckGasoline()
{
//somehow check gasoline and return whatever...
}
public override void StartEngine()
{
if (CheckGasoline())
//start engine...
}
}
Is this alright? I mean it's working, but is that how it should be? Using protected when I just need a method in the same class (like here: CheckGasoline() is only needed for StartEngine() ). Somehow private would look better.
Any suggestions? Thank you.
Yes that is fine. A sub-type cannot see private methods, therefore cannot override them: they must be protected (or public etc). There is no such thing as "private to method X" in c#, so it'll have to suffice as-is.
Private methods are inaccessible to any class other than the classes that they are in - this includes derived classes.
Protected methods, on the other hand, are accessible both to the classes that they are in AND their derived classes.
Your usage of protected is correct.
You may find this article to be of help: http://msdn.microsoft.com/en-us/library/ba0a1yw2(v=vs.80).aspx.
You can build in override hooks. Microsoft does this with FrameworkElement.ArrangeCore(...) (which utilizes ArrangeOverride) and FrameworkElement.MeasureCore(...) (which utilizes MeasureOverride).
For example:
abstract class Car
{
public string Name { get; set; }
public void StartEngine()
{
if (CheckGasoline())
StartEngineOverride();
}
protected abstract void StartEngineOverride();
protected abstract bool CheckGasoline();
// ...
}
class Mercedes : Car
{
protected override bool CheckGasoline()
{
//somehow check gasoline and return whatever...
}
protected override void StartEngineOverride()
{
// CheckGasoline was already checked, so just do the override portion.
}
}
I reccomend the following:
Try using protected for your member variable declarations in the abstract class. Then use public for your abstract methods, as well.
Next, within your derived class, you should use public and override for your methods in that derived class. However, this is another option that you have, and that is that you could use virtual as well. Therefore, instead of using a single abstract class, nest all of your potential Car type class within one public CarClass class, or whatever you want to call it.
Use the virtual method for a shared method in the first declared class which is an Abstract Car class. Then use public override for the remainder of the declared derived classes that are nested also within the CarClass class which can override the virtual method that you declared in your asbstract Car class. This is another option that you have, although it may limit you to only whatever you declare in the CarClass than a distinct and separate abstract class.

abstract method in a virtual class

I have a c# Class that has lots of virtual methods, some of these methods are essentially abstract ( they are fully implemented in subclasses and the base class is empty).
To get it to compile i am throwing an InvalidOperationException in the base class with a comment on what should be done. This just feels dirty.
Is there a better way to design my classes?
edit:
It is for the middle tier of an application that will be ran in canada, half of the methods are generic hence the virtual. and half of the methods are province specific.
Public class PersonComponent()
{
public GetPersonById(Guid id) {
//Code to get person - same for all provinces
}
Public virtual DeletePerson(Guid id) {
//Common code
}
Public virtual UpdatePerson(Person p) {
throw new InvalidOperation("I wanna be abstract");
}
Public Class ABPersonComponent : PersonComponent
{
public override DeletePerson(Guid id)
{
//alberta specific delete code
}
public override UpdatePerson(Person p)
{
//alberta specific update codecode
}
}
hope this makes sense
Mark the base class as abstract, as well as the methods that have no implementation.
Like so
public abstract class BaseClass
{
public abstract void AbstractMethod();
}
public class SubClass: BaseClass
{
public override void AbstractMethod()
{
//Do Something
}
}
You can't have abstract methods outside of an abstract class. Marking a class as abstract means you won't be able to instantiate it. But then it doesn't make any sense to. What are you going to do with a class that doesn't implement the methods anyway?
Edit: From looking at your class, yeah I'd make PersonComponent abstract along with the UpdatePerson method. Either that, or if UpdatePerson just doesn't do anything for a PersonComponent keep it as is, but make the UpdatePerson method empty for PersonComponent.
Think about your object hierarchy. Do you want to share common code for all your derived classes, then implement base functionality in the base class.
When having shared base code, please notice the Template pattern. Use a public method and chain it to a protected virtual method with the core/shared implementation. End the shared implementation methodname with "Core".
For example:
public abstract class BaseClass
{
protected virtual void DeletePersonCore(Guid id)
{
//shared code
}
public void DeletePerson(Guid id)
{
//chain it to the core
DeletePersonCore(id);
}
}
public class DerivedClass : BaseClass
{
protected override void DeletePersonCore(Guid id)
{
//do some polymorphistic stuff
base.DeletePersonCore(id);
}
}
public class UsageClass
{
public void Delete()
{
DerivedClass dc = new DerivedClass();
dc.DeletePerson(Guid.NewGuid());
}
}

Categories