November 19

I know that sounds stupid on the face of it. An interface shouldn't change. But consider this:

A frame timer and a clock timer(seconds) that re-use functionality from a parent class/interface.

class timerType
	{
	void start() = 0;
	void stop() = 0;
	void restart() = 0;
	void set(?) = 0; // ????
	}

class frameTimer : timerType
	{
        void set(int numFrames){}
	}
	
class clockTimer : timerType
	{
        void set(float numSeconds){}
	}

If we put both signatures in the top we're kind of polluting the interface. If we don't put them in the interface, then you can create a timer with no set() function.

None of this is super important on a practical level. There's going to probably be a total of two or three timer types. But as a learning exercise, I'm curious if there is a right/proper/best way to solve this conceptual problem.

And to be clear, frames and seconds are NOT directly interchangeable or convertible. If the game runs at 2 FPS for a moment, a 5 second timer is still 5 seconds (e.g. a countdown), but a frame timer of 2 (for an animation) is still going to be 2 frames.

November 19
On Sunday, November 19, 2023 1:13:16 AM MST Chris Katko via Digitalmars-d- learn wrote:
> I know that sounds stupid on the face of it. An interface shouldn't change. But consider this:
>
> A frame timer and a clock timer(seconds) that re-use
> functionality from a parent class/interface.
>
> ```
> class timerType
>   {
>   void start() = 0;
>   void stop() = 0;
>   void restart() = 0;
>   void set(?) = 0; // ????
>   }
>
> class frameTimer : timerType
>   {
>          void set(int numFrames){}
>   }
>
> class clockTimer : timerType
>   {
>          void set(float numSeconds){}
>   }
>
> ```
>
> If we put both signatures in the top we're kind of polluting the interface. If we don't put them in the interface, then you can create a timer with no set() function.
>
> None of this is super important on a practical level. There's going to probably be a total of two or three timer types. But as a learning exercise, I'm curious if there is a right/proper/best way to solve this conceptual problem.
>
> And to be clear, frames and seconds are NOT directly interchangeable or convertible. If the game runs at 2 FPS for a moment, a 5 second timer is still 5 seconds (e.g. a countdown), but a frame timer of 2 (for an animation) is still going to be 2 frames.

Generally, if a function needs to accept different types depending on the actual type, it doesn't belong on an interface or on a base class, because it cannot be called generically. Rather, you'd normally put the function on the actual class and use it when you're still dealing with the actual object and not the interface. If you need to set the value when it's an interface, then you should probably rethink what you're doing.

Obviously, the exact solution which is best is going to depend on your code and the situation, and in some cases, the best solution is to do something like cast the interface to its actual type so that you can call class-specific functions on it, but ideally, once you're dealing with an interface or base class, you just use it as that and don't need to do anything class-specific to it. So, if possible, it's generally better to figure out how to rework your code so that you don't need to set anything that's class-specific in the parts of the code which deal with the object through an interface or base class reference.

- Jonathan M Davis