Hello JGO & Class/Interface Inheritance Discussion

Hello JGO! I’ve been lurking for a few months and finally decided to get an account; :slight_smile:

First off, to all the awesome people who’s posts I’ve been reading, thank you; JGO is a great community with a lot of great information and advice;
In no particular order, some of the awesome people I remember at the moment include: Riven, princec, theagentd, ClickerMonkey, wessles, Danny02, and all the other awesome people who’s names I’m forgetting;

I’m currently a university student and spend every spare minute I can programming; I like learning protocols such as HTTP, FTP, UDP, etc, and used to love benchmarking stuff;
Although I’ve benchmarked so many different things in Java that I’ve worn myself out of the habit (most results were that Java is a well balanced language and, other than string concatenation/manipulation, everything in Java is relatively fast);


I thought I’d post a topic along with my hello thread; The topic/question is: class inheritance (extends) and inheritance (implements) as it may relate to code readability, developer efficiency, etc;

Class inheritance is cool, we wouldn’t have Swing as we know it without class inheritance; However class inheritance seems problematic for a few reasons; Serialization causes a lot of corner cases for classes; From security risks to enforcing correct serialization patterns in every leaf of an inheritance tree; Class inheritance also reveals implementation details; Protected fields and methods are accessible and the inner state of your class can be modified in ways you might not have expect when wrote the parent class;

Class inheritance is good and necessary for Java as a language; However, I’d like to share some of the experiences I’ve had going ‘class inheritance-less’ in some of my code;

Interfaces hide implementation details; Some time ago I was coding some structures for rendering a scene and using lwjgl’s Renderable interface everything could be treated the same, stored in the same collections, etc; From complex frustrum culled scene views to simple sprites, everything identical on the surface, but different underneath;
Of course none of this is new to anyone who has used interfaces for more than a few weeks; I’m not new to it either; However, I started wondering what challenges a developer would face if they only used interface inheritance; Interested in this, I started coding without using class inheritance;

Some of the resulting patterns that have emerged are immutability and composition; I find that coding large, complex classes is much easier when their design is broken down into modules rather than parent-child inheritance relationships;

For example, if a class represents a UI text field or button, it will probably need to fulfill a lot of roles; You could recreate Swing’s design pattern with thousands of lines of code nested in class inheritance trees many classes deep, or you could just create your object using a bunch of simpler objects that each provide a piece of your functionality; A button that needs a position, background, foreground text/icon, keyboard/mouse listeners, etc, could simply have fields for each of these pieces;

The basic concept in code tends toward composition:


Button implements ... {
	private Renderable backgroundModel;
	private UiElement foregroundModel; // which itself contains renderables for icons, text, etc.
	private Position pos;
	private InputHandler<Keyboard> keyHandler;
	private InputHandler<Mouse> mouseHandler;
...
}

Again, this is not revolutionary, I’m not even telling you anything you probably don’t already know; Just taking a one-sided programing technique and showing just how awesome it can be;

Maybe I just haven’t had enough time with interfaces to become less enthusiastic about their usefulness, but so far interfaces are making my code much cleaner and far more reusable;

Your experiences and thoughts are welcome; Please no arguing about what percentage of code should be extends vs. implements or whether one should be used exclusively; Both patterns/techniques are perfectly valid and can coexist seamlessly in Java; However, do you favor one over the other and do you find that it saves you time/effort by doing so?

I don’t think the discussion should be about one type of inheritance over the other, but instead about when to use one type of inheritance over the other. Favouring a certain type of inheritance gives you restrictions; you should always keep an open mind.

Interfaces allow you to abstract out a set of behaviours, i.e they allow you to share the same type of behaviour among several classes which implement those behaviours in a certain way. Classes on the other hand allow you to inherit a fixed set of states and behaviours. Abstract classes allow you to share a fixed set of states and behaviours but also allow you to abstract out a set of behaviours.

If there’s benefits of a certain type of inheritance then you should consider using that type. That said, you shouldn’t abuse inheritance. If there’s little or no benefit of polymorphism, then you should be considering composition over inheritance.

To answer your original question though, I find myself using abstract classes most often as they allow the greatest flexibility.

Good point Troubleshoots, all types of features offered by Java have specific situations which they solve best;
As the first post mentions in the last paragraph, I wasn’t saying that one feature is exclusive over another, just that I’ve seen a lot of cool patterns emerge from only using interfaces; Patterns which have made my code far easier to maintain and reuse; No more unknown super calls or hard to find fields accessed in child classes but located in parent classes, no more need to remember the internal state of every class’ parent class and no more bugs caused by modifying a parent class’ state at the wrong time;

The discussion was geared toward what types of experiences others have had and whether they have found that certain development patterns or techniques (related to inheritance) improve their coding life;

Thanks for your input, I’ve actually very rarely used abstract classes, maybe I should try it out more; I dislike having to hard coding behavior into any class which will be used as a reference type;
idk when it started, but whenever possible I prefer all my references to be interface types; It’s so easy to switch out an interface’s default implementation without changing any other code;