When you delegate, you are simply calling up some class which knows what must be done. You do not really care how it does it, all you care about is that the class you are calling knows what needs doing.
If I were you though I would make an interface and name it IPrinter (or something along those lines) which has one method named print. I would then make RealPrinter implement this interface. Finally, I would change this line: RealPrinter p = new RealPrinter(); to this: IPrinter p = new RealPrinter().
Since RealPrinter implements IPrinter, then I know for sure that it has a print method. I can then use this method to change the printing behaviour of my application by delegating it to the appropriate class.
This usually allows for more flexibility since you do not embed the behaviour in your specific class, but rather leave it to another class.
In this case, to change the behaviour of your application with regards to printing, you just need to create another class which implements IPrinter and then change this line: IPrinter p = new RealPrinter(); to IPrinter p = new MyOtherPrinter();.
public interface IPrinter { void print(); } public class RealPrinter implements IPrinter { @Override public void print() { System.out.println("This is RealPrinter"); } } public class RealPrinter2 implements IPrinter { @Override public void print() { System.out.println("This is RealPrinter2"); } } public class Main { public static void main(String...arg){ IPrinter printer = new RealPrinter(); printer.print(); printer = new RealPrinter2(); printer.print(); } }