Routing Arduino Mega output to either one of two serial ports
I can think of three distinct ways (and one that is similar to another) of doing what you want.
But first a note on polymorphism.  The HardwareSerial class is itself a child of the Stream class. It's this Stream class that provides all the read/write functionality (it, itself, is a child of the Print class which provides all the print(...) functions).
If all you want to do is print then you should be working with the Print class. if you want to do both reading and writing then the Stream class is what you want. You should only use HardwareSerial if you need to use the Serial-specific functions like .begin(baud).
So with that in mind you could:
1. Assign a pointer
Print *printer;

void setup() {
    Serial.begin(115200);
    Serial1.begin(115200);
    printer = &amp;Serial;
}

void loop() {
    printer = &amp;Serial;
    printer-&gt;println(millis());
    delay(100);
    printer = &amp;Serial1;
    printer-&gt;println(millis());
    delay(100);
}

This is by far the most efficient method from a purely machine perspective.
Note the use of -&gt; instead of . when calling a function on a pointer.
2a. Use a wrapper function
uint8_t stream = 0;

void printit(const char *text) {
    switch (stream) {
        case 0: 
            Serial.print(text);
            break;
        case 1:
            Serial1.print(text);
            break;
    }
}

void setup() {
    Serial.begin(115200);
    Serial1.begin(115200);
}

void loop() {
    stream = 0;
    printit(&quot;Hello on stream 0\r\n&quot;);
    stream = 1;
    printit(&quot;Hello on stream 1\r\n&quot;);
}

This is less efficient and limits what you can print unless you write lots of overloaded functions.
2b. Use a macro
This is like 2a but uses a macro instead of a function:
#define printit(T) if (stream == 0) Serial.print(T) else Serial1.print(T)

This keeps the standard overloading of the print function but has lots of IF statements littered through your code. A fraction more efficient than 2a since it's all inline. Harder for a human to understand though.
3. Create a wrapper class
This is the rolls-royce method. Everything becomes encapsulated in your own object. Pointers are used to keep it efficient.
class Printer : public Print {
    private:
        Print *stream;
        Print *stream0;
        Print *stream1;
    public:
        Printer(Print &amp;s0, Print &amp;s1) : stream0(&amp;s0), stream1(&amp;s1) {
            stream = &amp;s0;
        }
        size_t write(uint8_t c) {
            return stream-&gt;write(c);
        }
        void setStream(uint8_t sno) {
            switch (sno) {
                case 0: stream = stream0; break;
                case 1: stream = stream1; break;
            }
        }
};

Printer printer(Serial, Serial1);

void setup() {
    Serial.begin(115200);
    Serial1.begin(115200);
}

void loop() {
    printer.setStream(0);
    printer.println(millis());
    delay(100);
    printer.setStream(1);
    printer.prinln(millis());
    delay(100);
}

With this method the new class could be put into a library and used across your projects.
You also get all the functions you'd normally get with the Serial object when printing (for reading change Print to Stream and implement all the pure virtual functions you need for that class).
And a footnote for all those that say &quot;Why use pointers? Why not references?&quot; I say: I hate references. Pointers are far more obvious what they are. References you can't tell apart from distinct variables. With a pointer you know it's a pointer. References are the spawn of the devil.