Как получить переменную экземпляра класса

Всем привет. У меня есть такой list List<Family> family = Arrays.asList(new Dad(), new Son(), new GrandPa());

дальше в нем я рандомно выбираю экземпляр класса

  family.get( ThreadLocalRandom.current().nextInt(family.size())
).eat(chees);

и ем сыр.Это класс Человек с методом для еды.

 void eat(Chees chees) {
        int a = ThreadLocalRandom.current().nextInt(1, 101);
        chees.eat(a);
        System.out.println( " съел " + a + " грамм");
    }

У отца сына и деда есть приватная переменная name

вопрос в том, как мне в методе eat вывести эту переменную, чтобы в итоге получилось

Отец съел .. грамм Сын съел .. грамм Дед съел .. грамм


Ответы (1 шт):

Автор решения: Alex Rudenko

Если у всех классов-потомков Family имеется общее свойство/поле name, вероятно, имеет смысл перенести его на уровень этого родительского класса Family, и тогда метод Family::eat будет иметь доступ к данному полю.

public class Family {
    private String name; // или protected String name

    void eat(Chees chees) {
        int a = ThreadLocalRandom.current().nextInt(1, 101);
        chees.eat(a);
        System.out.println(this.name + " съел " + a + " грамм");
    }
}

Относительное преимущество такого способа в том, что он позволяет избежать дублирования кода в классах-потомках, однако обратная сторона этого - высокая связанность (high coupling) потомков с родителем, так как достаточно проблематично будет изменить способ печати для каждого из потомков.


Другой способ: сделать класс Family абстрактным, задав в нём некий абстрактный метод -- либо getter getName, либо целый метод для печати сообщения о поедании сыра, реализовать эти методы в классах-потомках, и вызвать их из метода Family::eat:

  • abstract String getName()
public abstract class Family {
    public abstract String getName();

    void eat(Chees chees) {
        int a = ThreadLocalRandom.current().nextInt(1, 101);
        chees.eat(a);
        System.out.println(getName() + " съел " + a + " грамм");
    }
}
class Dad extends Family {
    private String name;

    @Override
    public String getName() {
        return name;
    }
}
  • abstract void cheeseEaten(int cheese); - выводит всё сообщение
public abstract class Family {
    public abstract void cheeseEaten(int cheese);

    void eat(Chees chees) {
        int a = ThreadLocalRandom.current().nextInt(1, 101);
        chees.eat(a);
        cheeseEaten(a);
    }
}
class Dad extends Family {
    @Override
    public void cheeseEaten(int cheese) {
        System.out.println("Папаша съел " + cheese + " г сыра");
    }
}

В данном случае связанность между классами уменьшается, и каждый класс-потомок может реализовать обработку информации о съеденном сыре по-своему.

→ Ссылка