Как построить производный класс с существующим объектом базового класса - PullRequest
0 голосов
/ 01 марта 2020

Мне нужно построить класс, например, Apple или Strawberry из существующего объекта Fruit.

Это мой класс Fruit:

public class Fruit {
    int somevariable;
    Thread somethread;

    public Fruit(int somevariable) {
        this.somevariable = somevariable;

        this.somethread = new Thread() {
            public void run() { /* Something here */ }
        }

        this.somethread.start();
    }

    public Fruit(Fruit fruit) {
        this.somevariable = fruit.somevariable;
        this.somethread = fruit.somethread;
    }
}

А это мой класс Apple и Strawberry:

public class Apple extends Fruit {
    public Apple(Fruit fruit) {
        super(fruit);
    }
}

public class Strawberry extends Fruit {
    public Strawberry(Fruit fruit) {
        super(fruit);
    }
}

И у меня есть HashMap вот так:

HashMap<Integer, Fruit> fruits = new HashMap<>();

Сначала я добавляю фрукты вот так: (Все, что я знаю, это то, что это фрукт на данный момент. Я могу ' я не могу сразу добавить яблоко или клубнику.)

fruits.put(17, new Fruit(4));
fruits.put(24, new Fruit(8));
fruits.put(95, new Fruit(12));

И когда я узнаю, что это за фрукт, мне нужно заменить фруктовый объект яблоком или клубникой (тем же фруктовым объектом, что и супер объект). Конечно, не останавливая что-то.

И вот как я это решаю:

fruits.replace(17, new Strawberry(fruits.get(17)));
fruits.replace(24, new Apple(fruits.get(24)));
fruits.replace(95, new Strawberry(fruits.get(95)));

Мои вопросы:

Можно ли это сделать проще? Правильно ли мое решение?

И еще один вопрос, если у меня есть функции в клубнике, которые часто вызываются из других потоков, как убедиться, что нет проблем при замене значения хэш-карты?

Большое спасибо за вашу помощь:)

Ответы [ 3 ]

0 голосов
/ 02 марта 2020

Чтобы ответить на вопрос " Можно ли это сделать проще? Правильно ли мое решение? "

Да. Вам вообще не нужно делать replace, поскольку объекты, которые вы помещаете на карту, имеют тип Fruit, просто разыгрывайте его, когда вам нужно с ним работать.

Вы также можете проверить, как obj instanceof Fruit, если вы хотите быть более точным c.

Кроме того, ваш код выглядит не совсем безопасным, поскольку @ miszcz2137 также упомянул, одновременная модификация неизбежна.

0 голосов
/ 02 марта 2020

Предпочитают композицию наследованию. Подклассы конкретного класса (за исключением Object, хотя то, что бетон является своего рода "устаревшим" в данный момент) обычно не велика.

Fruit должен иметь FruitType (или лучше). При необходимости делегируйте.

Также обратите внимание, в исходном коде, что Runnable ( Edit: Thread с переопределенной нулевой точкой run) будет создан в контексте оригинальный экземпляр Fruit. Кроме того, поток первоначально увидит Fruit, который не гарантируется полностью инициализирован.

0 голосов
/ 02 марта 2020

Что касается одновременной модификации, используйте Collections.synchronizedMap или ConcurrentHashMap.

Что касается упрощения создания, можете ли вы указать, что хотите сделать проще? Чтобы не приходилось писать конструктор?

...