https://Darsman.com/blog/abstraction-in-java/