Running this piece of code will print null
public class Weird { static class Collaborator { private final String someText; public Collaborator(String text) { this.someText = text; } public String asText() { return this.someText; } } static class SuperClass { Collaborator collaborator; public SuperClass() { initializeCollaborator(); } protected void initializeCollaborator() { this.collaborator = new Collaborator("whatever"); } public String asText() { return this.collaborator.asText(); } } static class SubClass extends SuperClass { String someText = "something"; @Override protected void initializeCollaborator() { this.collaborator = new Collaborator(this.someText); } } public static void main(String[] arguments) { System.out.println(new Weird.SubClass().asText()); } } (Here is also the GitHub Gist)
Now, I know why this happens (it's because the field of the superclass is initialized and then the constructor of the superclass is called, before the field of the subclass is initialized)
The questions are:
- What is the design issue here? What is wrong with this design, from an OOP point of view, so that the result looks weird to a programmer? What OOP principles are being broken through this design?
- How to refactor so it does not work 'weird' and is proper OOP code?