Один и тот же метод для нескольких классов, реализующих один и тот же интерфейс

Извините, я действительно не знал, как назвать вопрос, вот в чем проблема...

У меня есть интерфейс и несколько классов, которые реализуют интерфейс. Реализация некоторых методов в интерфейсе точно такая же в каждом классе реализации. Я чувствую, что должен быть способ упростить это, чтобы мне не приходилось писать один и тот же код каждый раз. Пример:

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;
    }
}

Итак, чтобы сломаться..

  1. есть ли способ поставить код для getName в одном месте, и каждый класс имеет свою собственную переменную имени?

  2. есть ли способ сделать 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; }
}