Reputation: 153
Sorry I really didn't know how to title the question, here's the problem...
I have an interface and multiple classes that implement the interface. The implementation of some of the methods in the interface are exactly the same in every implementing class. I feel like there should be a way to simplify this so I don't have to write the same code every time. Example:
public interface Foo {
String getName();
}
public class FooImpl1 implements Foo {
private String name = "foo name1";
public String getName() {
return name;
}
}
public class FooImpl2 implements Foo {
private String name = "foo name2";
public String getName() {
return name;
}
}
So to break down..
is there a way to put the code for getName in one place and each class has it's own name variable?
is there a way to make getName static so I don't have to create a new instance
Have better ideas?
Upvotes: 15
Views: 11088
Reputation: 21204
It doesn't really work for getters like in your example, but since the question is more generic I think it's worth mentioning that with Java 8 you can define default methods in interfaces. So if you had something a bit more complex like:
public interface ComplexFoo {
String getFirstName();
String getLastName();
String getFullName();
}
You do not have to repeat the getFullName
implementation in every subclass, but can specify it in the interface:
public interface ComplexFoo {
String getFirstName();
String getLastName();
default String getFullName() {
return getFirstName() + " " + getLastName();
}
}
The getters though still need repeating, since they access members that are not yet available in the interface:
public class FooImpl1 implements ComplexFoo {
private String firstName = "foo";
private String lastName = "name1;
private String getFirstName() { return firstName; }
private String getLastName() { return lastName; }
}
public class FooImpl2 implements ComplexFoo {
private String firstName = "foo";
private String lastName = "name2;
private String getFirstName() { return firstName; }
private String getLastName() { return lastName; }
}
Upvotes: 0
Reputation: 65889
You could take a very simple approach:
public interface Foo {
String getName();
}
public class Named implements Foo {
String name;
public String getName() {
return name;
}
}
public class FooImpl1 extends Named {
{name = "foo name1";}
}
public class FooImpl2 extends Named {
{name = "foo name2";}
}
Upvotes: 1
Reputation: 13596
Use an abstract class and initialize the field in the constructor:
public abstract class Foo {
protected String name;
String getName() {
return name;
}
}
public class FooImpl1 extends Foo {
public FooImpl1 () {
name = "foo name1";
}
}
public class FooImpl2 extends Foo {
public FooImpl1 () {
name = "foo name2";
}
}
JB Nizlet pointed out that it would be cleaner to do something like this:
public abstract class Foo {
protected String name;
public Foo(String newName) {
name = newName;
}
String getName() {
return name;
}
}
And then call super("foo name 1")
in the subclasses.
As @Peter Lawrey said, if you already have an interface or want one for some other reason:
public interface IFoo {
String getName();
}
public abstract class Foo implements IFoo {
protected String name;
String getName() {
return name;
}
}
Upvotes: 12