Polymorphism best practice

Polymorphism best practice



I've been investigating java design patterns to make my projects more organised, one of the things I need to know is that if the following method is good practice.



When using a parent abstract class or interface, the methods for the sub classes are defined in the parent.



My issue is that when I have a bunch of sub classes, if each overrides method A in the parent, but one of the sub classes needs to have a different method B, is it good practice to define method B in the parent, even though it is only being used for that single sub class.



This poses the issue that methodB will need to be used in every sub class even if it is never called from that class.



Am I meant to do this? It doesn't seem right.



Code Example:


public interface Parent

public void methodA();

//Should this method be in the parent as it is only used once?
public void methodB();




Sub-Classes:


public class First implements Parent

@Override
public void methodA()
System.out.println("This is method A");


// Does Nothing but java must have it used in the sub class
@Override
public void methodB()
throw new UnsupportedOperationException("Do not call methodB from class First!!");





public class Second implements Parent

@Override
public void methodA()
System.out.println("This is method A");


// methodB is being used for this sub-class
@Override
public void methodB()
System.out.println("This is method B");





As you can see from the code above, I only use methodB for the second sub-class, but I am still required to use it in the first sub-class or an exception is thrown. Since this method should never be called inside the first class I simply throw an exception with a message. This seems unoriganised. It is definitely wrong use of inheritance.



If I only use methodB in the Second class, without adding it to the parent:


public static void main(String args)
Parent p = new Second();
p.methodA() // Prints "This is method A"
p.methodB() // throws an error



Does anyone know how I can call a specific method that is in a class without throwing an error. Adding the method to the parent is definitely bad practice.



EDIT:



Thanks for all the quick responses, I discovered that the way to do this is to instead define different interfaces:


interface X
public void A()


interface Y extends X
public void B()


class First implements X
@Override
public void A();


class Second implements Y
@Override
public void A();

@Override
public void B();



If this is still incorrect, please tell me.





I guess that's a violation of the Liskov substitution principle. You shouldn't use inheritance if something isn't actually a more refined or specialized subtype and you definitely shouldn't put methods (i.e. behavior) into a parent if that's not actually behavior of all childs. Rethink those classes. (see also en.wikipedia.org/wiki/Circle-ellipse_problem)
– zapl
Aug 29 at 21:05






What do you mean a "different method B" if it's only used in a single sub-class? If it's only in a single child class, and you're overriding method A anyway, who cares what what's in the methods? If a subclass doesn't need method B why would it be in the parent?
– Dave Newton
Aug 29 at 21:05





If one of the subclasses needs a method B, then it seems to me that either method B is private to that subclass or else that subclass isn't really an instance of the interface.
– Ted Hopp
Aug 29 at 21:06






Should First and Second be implementing Parent? If so, please write that.
– Andy Turner
Aug 29 at 21:18


First


Second


Parent





I'd managed to read your question to me in comments before you deleted it, and tried to answer it (updated)
– Andrew Tobilko
Aug 29 at 21:52




3 Answers
3



[...] is it good practice to define method B in the parent, even though it is only being used for that single subclass.



Of course, no.



Imagine how rapidly your superclass would be growing if each of its subclasses added own piece. Each child would have a bunch of unrelated stuff that other subclasses require. It indicates incorrect relationships between classes and the wrong usage of inheritance.



In your snippet, the relationships among the classes are obscure. Inheritance always requires real examples. Here, I can't state that First is a Parent.


First


Parent



For a method that is going to be implemented by almost all subclasses, I've seen a practice of defining that method within the parent with the default exception-based implementation. So you won't be needed to duplicate the standard behaviour in subclasses.



It would be a little improvement to your current situation:


default void methodB()
throw new UnsupportedOperationException("[...]");



Passing a Parent instance to a method, make sure that you will utilise only the interface provided by this class. That would keep you away from casting and clattering up its interface.


Parent


A -> [methodA] (only)
B -> [methodB] (only)
C -> [methodA, methodB]



If the given methods are not enough, make a compound interface which will add the missed methods:


interface A void methodA();
interface B void methodB();
interface C extends A, B

class First implements A ...
class Second implements C ...





Thanks for the detailed answer with code example, makes more sense now.
– Ben Henderson
Aug 29 at 21:54



An interface is a contract that the class which implements it agrees to fulfill.


interface



Consider a hypothetical interface called Furniture. Not all Furniture would reasonably implement the recline() method - such as a table - but some might. This is a good example why the recline() method shouldn't be in this interface, but perhaps in an extended interface RecliningFurniture.


Furniture


Furniture


recline()


recline()


RecliningFurniture



In this way, an object of class Table would implement Furniture but an object of class Chair might instead implement RecliningFurniture. Both would be bound by the contract of the Furniture interface, but the Chair would also have to fulfill the additional terms of the contract RecliningFurniture.


Table


Furniture


Chair


RecliningFurniture


Furniture


Chair


RecliningFurniture





So pretty much define different interfaces for different categories of sub-classes? This makes more sense, thanks for the answer.
– Ben Henderson
Aug 29 at 21:31





Yes, that is one way. You could also create a class which implements your interface, then extend that class into subclasses. Maybe you want an abstract Chair implements Furniture, then you create a RecliningChair and a SwivelChair, and a Stool, which all extend Chair. Just depends on your project and what you're trying to accomplish.
– Bryan
Aug 29 at 21:35



if some objects behave like X and other like X + something else you need 2 interfaces, cause you have 2 things where one is like the other one plus a bit more


interface X
public void A()


interface Y extends X
public void B()


class First implements X
@Override
public void A();


class Second implements Y
@Override
public void A();
@Override
public void B();



all will behave like X in circumstances where you need X, that's for sure. In other ones you will have to mention that here we have something more





Thanks for the answer, this makes much more sense.
– Ben Henderson
Aug 29 at 21:32



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)