#java #oop #for-loop
#java #ооп #for-цикл
Вопрос:
Я работаю над проектом Java, который имеет несколько классов, которые имеют переменную экземпляра объектов из других классов. Например, объект BigClassA содержит массив объектов SmallClassA; объект BigClassB содержит массив объектов SmallClassB.
Несмотря на то, что BigClassA и BigClassB имеют совершенно разные поля, они подвергаются аналогичным операциям с SmallClassA и SmallClassB. Пожалуйста, посмотрите код ниже:
public class BigClassA {
// initialize all instance variables to 0
double totValue = 0;
double totGainLoss = 0;
SmallClassA[] smallClassArray = new SmallClassA[2];
public BigClassA(int i, int j) {
smallClassArray[0] = new SmallClassA(i);
smallClassArray[1] = new SmallClassA(j);
for (int k; k<smallClassArray.length; k ) {
totValue = totSmallClassArray[k].getValue();
totGainLoss = totSmallClassArray[k].getGainLoss();
}
}
}
public class BigClassB {
// initialize all instance variables to 0
double totFoo = 0;
double totBar = 0;
double totPvsNP = 0;
SmallClassB[] smallClassArray = new SmallClassB[3];
public BigClassB (int p, int q, int r) {
smallClassArray[0] = new SmallClassB(p);
smallClassArray[1] = new SmallClassB(q);
smallClassArray[2] = new SmallClassB(r);
for (int k; k<smallClassArray.length; k ) {
totFoo = smallClassArray[k].getFoo();
totBar = smallClassArray[k].getBar();
totPvsNP = smallClassArray[k].getPvsNP();
}
}
}
Я думаю, что цикл for как в BigClassA, так и в BigClassB имеет достаточно схожие характеристики и может быть заменен общим кодом.
Может ли кто-нибудь посоветовать, как создать внешний метод, который может работать как два цикла for, описанных выше, без необходимости повторного написания цикла for для каждого класса? Или, возможно, какие-то другие способы сделать код более кратким? Заранее спасибо за вашу помощь!
Комментарии:
1. Это должно вам помочь.
2. 1. Есть ли в Java8 что-нибудь краткое для перебора массива и суммирования значений getter?
3. @MarounMaroun: Где бы вы представили здесь подклассы?
4. Создайте метод с массивом объектов в качестве параметра и выполните итерацию по массиву объектов. Проверьте наличие экземпляра каждого объекта с желаемым классом и укажите условие if для получения значений.
5. Я бы сказал, что это случай ложного рефакторинга. Любой метод, который вы могли бы придумать, вам пришлось бы передавать информацию о том, какое поле вы хотите обновить, и какие методы вы хотите вызвать, и передача всей этой информации более громоздка, чем того стоит. Не позволяйте поверхностному сходству в коде привести вас к рефакторингу вашего пути в глубокую яму.
Ответ №1:
Приведенный вами код не содержит достаточно общих частей, чтобы заслуживать такого рефакторинга, но есть способы для этого. Как предложил Марун Марун, вам придется использовать наследование, но есть много шагов :
- определите общий интерфейс или абстрактный класс между
SmallClassA
иSmallClassB
. В лучшем случае вы будете определять как интерфейс, содержащий все методы с общей сигнатурой, так и абстрактный класс, содержащий общий код. - определите общий общий абстрактный класс между
BigClassA
иBigClassB
, параметризованный с помощью<T extends CommonSmallInterface>
- make
class BigClassA extends CommonBigClass<SmallClassA>
и то же самое дляB
Таким образом, вы избежите дублирования кода ценой определенной сложности.
Примечание: в зависимости от того, как SmallClassA
SmallClassB
объявлены и, их общий интерфейс и / или суперкласс также могут быть общими.
Ответ №2:
Стандартный способ абстрагирования подобного поведения — использовать интерфейсы. В вашем случае вы хотите создать общее число по всем элементам списка.
Сначала создайте интерфейс
public interface Summable {
double getSum();
}
Теперь реализуйте этот интерфейс в SmallClassA и SmallClassB. Это переносит большую часть тел цикла на конкретные классы, например, для SmallClassA
public SmallClassA implements Summable{
public double getSum() {
return getValue() getGainLoss();
}
}
Теперь оба ваших цикла могут быть записаны как
for ( Summable summable : smallClassArray ) {
total = summable.getSum();
}
Вы также можете сделать это внешним методом.