The Coplien Envelope / Letter Pattern (in his compulsory book Advanced C ++ Programming Styles and Idioms) is a classic way to do this.
In short, an envelope and a letter are both subclasses of the abstract base class / interfcae, which defines an open interface for all subclasses.
An envelope holds (and hides the true type) of the letter.
Different letter classes have different implementations of the public interface of an abstract class.
The envelope has no real implementation; it just helps (delegates) in his Letter. It contains a pointer to an abstract base class and points to a specific instance of the Letter class. As the implementation changes, you must change the pointer type of the Letter subclass.
Since users only have a link to the envelope, this change is invisible to them, except that the behavior of the envelope changes.
Coplien examples are especially clean because they are the letters, not the envelope, that cause the change.
One example of the hierarchy of the Number classes. The abstract base announces certain operations on all numbers, for example, adding. The integer and complex are examples of specific subclasses.
Adding Integer and Integer leads to Integer, but adding Interget and Complex leads to the creation of a complex.
Here's what the envelope to add looks like:
public class Number { Number* add( const Number* const n ) ;
Now, in the client index, it never changes, and they never need to know what Envelop holds. Here's the client code:
int main() {
In his book, Coplien goes deeper โ you will notice that the add method requires multiple submissions of some form โ and adds syntactic sugar. But this is the essence of how you can get what is called "run-time polymorphism."