RICK
RICK

Reputation: 273

Work around the need to override abstract methods in Java?

I've been working on an assignment that involves an abstract class that represents a generic animal, with subclasses for cat, dog, reptile, etc. The superclass has abstract methods that aren't actually used by each subclass. For example, there are accessors and mutators for breed and gender that are used by dog and cat but not the reptile class. I personally think this is an odd setup, but it's what is required by the assignment.

At first I tried leaving out the abstract methods not used in a particular subclass, but I quickly found out that leads to an error, due to abstract methods not being overridden. All I had to do to fix that was put in the appropriate methods...

public class Reptile extends Animal
...
public void setBreed(String newBreed){}  
public String getBreed(){return null;}  


...though it seems to be a bit of a waste seeing as they aren't used. It's not a huge issue, but it made me curious as to whether or not there is an alternative to having to override unused abstract methods in a given subclass. Barring that, is there any convention for what to do when you need to override an abstract method but won't actually be using the method at all?

Upvotes: 1

Views: 3033

Answers (2)

user207421
user207421

Reputation: 311050

Another version of @earchengine's answer, add a couple of interfaces:

public abstract class Animal{
  public abstract void fooMethod();
}

public class Breed {...}
public interface Bred {
  Breed breed();
}

enum Gender { ...}

public interface Gendered
  Gender gender();
}

public class Reptile extends Animal {
  public void fooMethod(){}
}

public class Cat extends Animal implements Gendered, Bred {
  public void fooMethod(){}
  public Breed breed(){}
  public Gender gender(){}
}

public class Dog extends Animal implements Gendered, Bred {
  public void fooMethod(){}
  public Breed breed(){}
  public Gender gender(){}
}

Upvotes: 1

searchengine27
searchengine27

Reputation: 1471

You have two solutions here.

You can have multiple levels of abstract classes. In other words (these are shell classes and functions...i.e. no code):

public abstract class Animal{
  public abstract void fooMethod();
}

public abstract class Pet extends Animal{
  public abstract void breed();
  public abstract void gender();
}

public class Reptile extends Animal{
  public void fooMethod(){}
}
public class Cat extends Pet{ //do the same for Dog
  public void fooMethod(){}
  public void breed(){}
  public void gender(){}
}

This way, Reptile still extends Animal, but you know Reptile doesn't have a breed or gender function, so you don't have to do anything for it. Similarly, Cat and Dog also extend Animal, but now they have breed and gender they must override as well.

Your other solution is to do something like this (the worse of the two solutions):

public class Reptile extends Animal{
  public void breed(){
    throw new UnsupportedOperationException("Don't call Reptile#breed!!");
  }
}

This solution is particularly bad, because if you don't have proper error handling, this exception will propagate all the way up the stack to your main method, and if there is not exception handling for this all the way to your main method, then your program crashes.

I recommend choice A, personally.

Upvotes: 4

Related Questions