www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to write an interface but with different signatures

reply Chris Katko <ckatko gmail.com> writes:
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.
Nov 19 2023
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Nov 19 2023