Тот же метод для нескольких классов, реализующих один и тот же интерфейс
Извините, я действительно не знал, как назвать вопрос, вот проблема...
У меня есть интерфейс и несколько классов, которые реализуют интерфейс. Реализация некоторых из методов в интерфейсе в каждом классе реализации одинакова. Я чувствую, что должен быть способ упростить это, поэтому мне не нужно писать один и тот же код каждый раз. Пример:
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 static, поэтому мне не нужно создавать новый экземпляр
Иметь лучшие идеи?
Ответы
Ответ 1
Используйте абстрактный класс и инициализируйте поле в конструкторе:
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")
в подклассы.
Как @Peter Lawrey сказал, что если у вас уже есть интерфейс или вы хотите по какой-то другой причине:
public interface IFoo {
String getName();
}
public abstract class Foo implements IFoo {
protected String name;
String getName() {
return name;
}
}
Ответ 2
Вы можете сделать очень простой подход:
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";}
}
Ответ 3
Это не работает для геттеров, как в вашем примере, но поскольку вопрос более общий, я думаю, стоит упомянуть, что с 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; }
}