Один и тот же метод для нескольких классов, реализующих один и тот же интерфейс
Извините, я действительно не знал, как назвать вопрос, вот в чем проблема...
У меня есть интерфейс и несколько классов, которые реализуют интерфейс. Реализация некоторых методов в интерфейсе точно такая же в каждом классе реализации. Я чувствую, что должен быть способ упростить это, чтобы мне не приходилось писать один и тот же код каждый раз. Пример:
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;
}
}
Итак, чтобы сломаться..
есть ли способ поставить код для getName в одном месте, и каждый класс имеет свою собственную переменную имени?
есть ли способ сделать getName статическим, поэтому мне не нужно создавать новый экземпляр
есть идеи получше?
3 ответов
используйте абстрактный класс и инициализируйте поле в конструкторе:
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 указал, что было бы чище сделать что-то вроде этого:
public abstract class Foo {
protected String name;
public Foo(String newName) {
name = newName;
}
String getName() {
return name;
}
}
и затем вызов super("foo name 1")
в подклассах.
As @Peter Lawrey сказал, Если у вас уже есть интерфейс или вы хотите его по какой-то другой причине:
public interface IFoo {
String getName();
}
public abstract class Foo implements IFoo {
protected String name;
String getName() {
return name;
}
}
вы можете принять очень простой подход:
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";}
}
это действительно не работает для геттеров, как в вашем примере, но поскольку вопрос более общий, Я думаю, стоит упомянуть, что с Java 8 вы можете определить методы по умолчанию, в интерфейсах. Поэтому, если у вас было что-то более сложное, как:
public interface ComplexFoo {
String getFirstName();
String getLastName();
String getFullName();
}
вам не нужно повторять getFullName
реализация в каждом подклассе, но можно указать его в интерфейсе:
public interface ComplexFoo {
String getFirstName();
String getLastName();
default String getFullName() {
return getFirstName() + " " + getLastName();
}
}
геттеры, хотя все еще нуждаются в повторении, так как они получают доступ к членам которые еще не доступны в интерфейсе:
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; }
}