Just inherit Print class and implement virtual size_t write(uint8_t); and you can use all kinds of print/println that Print implements. See Print Class @arduino.cc.
It implements these methods for you:
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
size_t println(const __FlashStringHelper *);
size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
However you have to implement 2D array print if you really need this, I don't see why do you need it but whatever (you can print each line separately). It just saves you time with implementing everything else.
And for std::ostream like approach I like this (works with anything inherited from Print class):
template <class T> inline Print & operator<<(Print & p, const T & val) {
p.print(val);
return p;
}
// ...
void loop() {
float variableA = 221.23;
String variableB = "Some string";
Serial << F("flash string to save some ram: ") << variableA << F(" / ") << variableB << "\n";
}
Then you can implement some commands interface.