Search code examples
javainheritancemethodsabstractrun-time-polymorphism

Inheriting specifid methods in java


Is it possible in java to inherit some methods from the base class, but not all of them? Just to be clear, i will show you what I mean: Suppose we have the base class Visitor

public abstract class Visitor {}

From Visitor we create 2 more Objects, Client and Companion:

public class Client extends Visitor {}
public class Companion extends Visitor {}

In Client, we create the method:

boolean has_Companion() {}

In order to achieve runtime polymorphism, we need to declare the method in Visitor as well:

abstract boolean has_Companion();

The problem is that since we declare the method in Visitor, Companion inherits it as well. We don't want that. When I compile I get the following error:

The type Companion must implement the inherited abstract method Visitor.has_Companion()

There is no point in implementing the method has_Companion() for Companion because it will never be used. It's a waste of code. Can I avoid it in some way? Can the method has_Companion() be inherited only by Client, and not by Companion?


Solution

  • The short answer is that Java does not support what you're trying to do, but the good news is there are many ways to work around it.

    Idea 1: Have Companion override hasCompanion and simply always return false.

    Idea 2: Have Visitor provide an implementation of hasCompanion that simply always returns false. Then Client will override hasCompanion with actual logic to determine if the Client has a companion.

    Idea 3: Don't give a hasCompanion method to Visitor at all, but rather only have the method in Client. Then the code has run-time type checking via the instanceof operator and calls the method on Client via casting. Example:

    if (visitor instanceof Client) {
        Client client = (Client) visitor;
        boolean hasCompanion = client.hasCompanion();
        // other logic
    }
    

    This is fake polymorphism at best and a very kludgy solution. I would advise against doing this if possible.

    Idea 4: Reconsider the design and refactor the type tree and how the code uses inheritance. If it makes no sense to call hasCompanion on Companion extends Visitor, why is hasCompanion a method of Visitor at all?

    Java does not support multiple inheritance, so interfaces are necessary:

    public interface MightHaveCompanion {
        public boolean hasCompanion();
    }
    
    public abstract class Visitor {
        // methods that all Visitors must have
    }
    
    public class Client extends Visitor implements MightHaveCompanion {
        // overriding implementations of MightHaveCompanion and Visitor methods 
    }
    
    public class Companion extends Visitor {
        // overriding implementations of Visitor methods
    }
    

    Then calling code will have to change to use the types MightHaveCompanion or Visitor as necessary. It's clear what methods belong to what types. Make no mistake that on a larger project the amount of work to do this will scale, but it might result in cleaner code.