Reputation: 323
There is an issue I have been running into and I don't know the technical terms to describe it, so it has been difficult for me to search for an answer myself and I'm hoping someone might be able to shed some light what is going on here.
Let's say a library has 2 or more similar classes with somewhat similar functionality, such as JTextField and JTextArea. I would like to make an additional method available to both of these classes.
I could extend both classes and add the method to each, but the method to be added might be so similar that it could be copied and pasted into each class. This makes me think there is a better way to do this.
In this simplified example, is it possible to: A) eliminate the near duplicate definition of "getStringValue()" between CustomJTextField and CustomJTextArea while B) retaining the original functionality of both JTextArea and JTextField.
CONCEPTUAL EXAMPLE:
public interface AnInterface {
public String getStringValue();
}
public class CustomJTextField implements AnInterface{
//Could Duplication of this method be avoided?
@Override
public String getStringValue(){
return this.getText();
}
}
public class CustomJTextArea implements AnInterface{
//Mirrors CustomJTextField's definition
@Override
public String getStringValue(){
return this.getText();
}
}
public class CustomJCheckbox implements AnInterface{
@Override
public String getStringValue(){
return this.isSelected() ? "Checked" : "Not Checked";
}
}
public class Main{
public static void main(String[] args) {
ArrayList<AnInterface> items = new ArrayList<AnInterface>();
items.add(new CustomJTextField());
items.add(new CustomJTextArea());
items.add(new CustomJCheckbox());
for (AnInterface item : items){
String output = item.getStringValue();
System.out.println(output);
}
}
}
My frustration has been that I can't seem to just extend JTextComponent without losing the functionality of JTextField and JTextArea, but if both are extended, it feels like unnecessary duplication. Is there an elegant way to avoid this kind of duplication?
Upvotes: 0
Views: 152
Reputation: 19915
If you use Java 8
, then default
method implementations in interface
definitions, offer a good solution.
In the above example, you can define AnInterface
as
public interface AnInterface {
public getText(); // Abstract method (re)definition
default String getStringValue() {
return this.getText();
}
}
and only override the getStringValue()
method for the CustomJCheckbox
class.
Of course the above is of little value for methods with trivial (e.g., 1-line) implementations. It is very useful, however, for mpore complex methods.
Upvotes: 1