Reputation: 723
If I have a super class BaseClass and a subclass SubClass, and I want some of the subclass's functions to be slightly different, is it bad practice to just override the original, call super, and tack on a little extra functionality?
For example: (pseudo code)
public class BaseClass{
int fooA();
int fooB();
int fooC();
}
public class SubClass extends BaseClass{
@Override
int fooB(){
int temp = super.fooB();
temp += 1;
return temp;
}
@Override
int fooC(){
System.out.println("I'm doing something extra in fooC!");
return super.fooC();
}
}
I'm trying to prevent code duplication, but I kind of feel like I'm doing something wrong or forgetting some basic OOP stuff, so I thought I'd ask if this was bad practice. It's been a while since I've done inheritance; thanks for any insight.
Upvotes: 2
Views: 2505
Reputation: 103
I think it might be correct approach, but from my experience it's more readable and convenient to make one abstract class with common functions implemented and then have two subclasses to extend it in order to implement different functions, like that:
public abstract class BaseClass {
public void fooA() {
System.out.println("Some common function");
}
public void fooB() {
System.out.println("Another common function");
}
public abstract int fooC();
}
public class SubClass1 extends BaseClass {
@Override
public int fooC() {
return 0;
}
}
public class SubClass1 extends BaseClass {
@Override
public int fooC() {
return 1;
}
}
This way it will be much easier to navigate through larger projects and feels more natural
Upvotes: 0
Reputation: 4504
You can do what you suggest, is an option. But, what happen if you have for example 3 classes which do the same? You're still repeating code and logic, because in each of them you will call super. What you can do in that case is implement a template method pattern. If you haven't read about it, it means to define a method in the super class as abstract, use it there and then define it in the subclasses. Following your example, it could look something like this:
public class BaseClass{
int fooA();
int fooB();
int fooC(){
//here goes the common logic;
this.printWhatItHasToPrint();
}
void printWhatItHasToPrint() {}; //if the class is abstract you may define it as abstract
}
public class SubClass1 extends BaseClass{
@Override
int fooB(){
int temp = super.fooB();
temp += 1;
return temp;
}
@Override
void printWhatItHasToPrint(){
System.out.println("I'm doing something extra in fooC!");
}
}
public class SubClass2 extends BaseClass{
@Override
void printWhatItHasToPrint(){
System.out.println("I'm doing something extra in fooC, and I'm another class!");
}
}
Upvotes: 0
Reputation: 316
The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type.
Hopefully this provides an answer to your question.
https://docs.oracle.com/javase/tutorial/java/IandI/override.html
Upvotes: 1
Reputation: 15842
Instead of inheriting you can do the following:
public class SubClass implements MyInterface {
private MyInterfaceBasicImpl base;
int fooB(){
int temp = base.fooB();
temp += 1;
return temp;
}
int fooC(){
System.out.println("I'm doing something using in fooC in base object!");
return base.fooC();
}
}
It's an easy example of Composition
pattern. As there is no multiple inheritance in Java
it'll keep your code Open for improvements.
Upvotes: 3