Nope; nowhere near what i was originally looking for. The opposite, rather. Static methods, called by an application that statically constructs a child class. It's all very static on purpose -- no dynamic run-time decisions, because the problem domain does not call for dynamic or double dispatching or dependency injection or any other flavor of dynamic run-time ability.
Taking this into the LapDog.Messaging domain:
Consider a process that needs to send a string to another process; it's going to construct the message using LapDog.Messaging.v2.NativeTypes.lvlib:StringMessage.lvclass:Create StringMessage.vi. This problem domain would never require run-time selection of another ctor, whether through dynamic dispatch, double dispatch, etc. -- because the caller needs to send a string.
Now, taking a look at all of the message ctors in LapDog.Messaging.v2.NativeTypes.lvlib, they all call RenameMessage.vi. -- yet I would suggest it's better if they called Message.lvclass:Create Message.vi, their "prototype", the ctor that exists in the parent -- bear with me; this is not a criticism, it's what I see as a great candidate for "Must Implement":
For a moment, consider the calling of this particular function essential to the construction of a Message object for it to be viable within the framework. Further, even though this is just one function, consider it representative of "the collection of all the essential functions" that must be called in the construction of a Message object. (One very real upgrade we might want to perform in this case is timestamping the message, and we would not want to go into each of the concrete implementations to ensure they call Apply Timestamp.vi)
What I'm suggesting is that each of the concrete Message ctors calls Message.lvclass:Create Message.vi instead of calling Message.lvclass:RenameMessage.vi. With this strategy, we allow the parent to templatize the sequence of essential constructor functions. If Message.lvclass were able to specify 'Must Implement' and 'Must Call Parent Implementation', we formalize the definition of Create StringMessage.vi as implementing -- which is discretely different but having traits in common with overriding -- the functionality of the parent class method Create Message.vi. Further, we guarantee the parent method called in order to perform the essential tasks that construct a well-formed message object.
And we get the unique ConPanes we desire in the concrete implementing method.
I've mentioned previously (post #13), and AQ brought up again (post #132: It may not be proper to even specify the function name (i.e. one might have "Write Boolean.vi" and another have "Write Double.vi")), that this "Must Implement" feature is gated by an inheritance relationship defined through a GUID private to the class rather than filenaming conventions of the method; this is evidenced with the desire for StringMessage.lvclass:Create StringMessage.vi to implement Message.lvclass:Create Message.vi yet not have its same filename.
With these features and contracts in place, if a developer decides to subclass LapDog.Messaging.v2.lvlib:Message.lvclass by creating myArbitraryStructureMessage.lvclass, we can be guaranteed that it both implements and calls the parent implementation of the essential ctor Message.lvclass:Create Message.vi, yet is able to give it any name deemed fit with any conpane necessary to construct the specific object.
The prime motivation here is inverting inversion of control; would one call this taking control? It's an exercise acknowledging that statically composed applications, when the problem domain allows, is superior to dynamically composed systems, in terms of ease of development and troubleshooting and maintenance. I think it would be handy to have language features such as 'Must Implement' that acknowledge the merits of subclassing without necessarily leveraging dynamic run-time abilities.
Thoughts?