Примечание: код с последовательностями «if (x instanceof MyClass)
» обычно указывает, что вы недостаточно используете полиморфизм. Код, как правило, может быть реорганизован, чтобы избавиться от необходимости проверить это. Но я проигнорирую это, чтобы ответить на заданный вопрос.
Вы можете делать то, что вы пытаетесь сделать, но не без каких-либо изменений кода. Перегрузка метода не может делать то, что вам нужно, потому что в Java перегрузка метода определяется во время компиляции. Таким образом, если у вас есть два метода в классе, где оба метода имеют одинаковое имя, одинаковый тип возвращаемого значения, но разные типы параметров, тогда любой код, вызывающий этот перегруженный метод, должен указывать, какой из них будет вызываться. Ваш текущий код делает это с теми типами, которые он предоставляет из-за использования явных приведений, но полностью динамическая версия этого не делает. Если перегрузка метода была определена во время выполнения, то ваш код будет делать то, что вы хотите. Но поскольку во время компиляции решено, ваш код не компилируется.
Чтобы решить вашу проблему, вы можете использовать дженерики, или вы можете перестроить свой код. Сначала я познакомлю тестовую, которая показывает очень упрощенную версию того, что вы начинаете с:
public class Test {
public void test(Object obj) {
if (obj instanceof Horse) {
Horse c = (Horse) obj;
noise(c);
}
if (obj instanceof Cow) {
Cow c = (Cow) obj;
noise(c);
}
}
public void noise(Horse h) {
System.out.println("Neigh");
}
public void noise(Cow c) {
System.out.println("Moo");
}
public static void main(String[] args) {
Object o1 = new Horse();
Object o2 = new Cow();
Test tester = new Test();
tester.test(o1);
tester.test(o2);
}
}
class Horse {}
class Cow {}
Этот код работает и делает то, что можно было бы ожидать. Он печатает «Neigh», а затем «Moo».
Вы пытаетесь заменить
if (obj instanceof Horse) {
Horse c = (Horse) obj;
noise(c);
}
с
if (obj instanceof Horse) {
handleNoise(obj, Horse.class);
}
, а затем добавить метод для обработки его (упрощенно):
void handleNoise(Object obj, Class clazz) {
noise(clazz.cast(obj));
}
и, как я уже говорил, не работает, перегрузка noise
определяется во время компиляции. Компилятор видит, что вы выполняете кастинг, но во время компиляции не знаете, что такое тип. Поэтому он не может выбрать перегрузку и компиляцию.
Лучший способ решить это с помощью полиморфизма, поскольку полиморфизм определяется во время выполнения. То есть, все эти классы реализуют некоторый интерфейс, а затем перемещают рассматриваемый код в отдельные классы. Вот пример, который делает это:
public class Test {
public void test(Animal obj) {
obj.noise();
}
public static void main(String[] args) {
Animal o1 = new Horse();
Animal o2 = new Cow();
Test tester = new Test();
tester.test(o1);
tester.test(o2);
}
}
interface Animal {
void noise();
}
class Horse implements Animal {
public void noise() {
System.out.println("Neigh");
}
}
class Cow implements Animal {
public void noise() {
System.out.println("Moo");
}
}
Обратите внимание, насколько проще метод тестирования!Если вы можете иметь каждый элемент реализовать интерфейс, который обрабатывает то, что вы называете stringProp ниже, то вы можете упростить часть пути:
if (obj instanceof Cust) {
loopOverSet(c.getCustPhonSet());
} else if (obj instanceof Name) {
loopOverSet(c.getCustNameSet());
}
// and so on for the rest...
, а затем добавить метод:
void loopOVerSet(Set cxSet) {
if (cxSet != null && cxSet.size() > 0) {
Iterator cxSetIterator = cxSet.iterator();
while (cxSetIterator.hasNext())
{
((StringProp)cxSetIterator.next()).stringProp();
}
}
}
Это предполагает, что previously- перегруженные методы stringProp
были перемещены в отдельные классы CustPhone
и CustName
и т. д. и что эти классы реализуют некоторый интерфейс, который я назвал StringProp
, где этот интерфейс определяет метод stringProp()
. Поскольку этот код использует , переопределяя вместо перегрузкой, это будет определено во время выполнения.
Код, который я написал, должен был объяснить, что я хотел. В любом случае, я хочу набирать вывод из набора. Но имя класса, используемое для typecast, получает динамически, то есть (clsname) hritr.next() вместо (Horse) hritr.next() .. где clsname = «Лошадь» .. Я думаю, что у меня появилась моя точка зрения ... Я не могу использовать общий набор ... – msher420
Нет, я еще не понял вашу точку зрения. Почему динамическое имя класса? Имеют ли эти классы общий базовый класс? Все возможные имена классов известны во время компиляции? – Darron
Фу! кажется, что мы не можем динамически придумать объект .. в любом случае посмотрим последнее сообщение, которое я добавил .. Извините, если я тупой .. очень любитель, пытаясь экипировать себя ... спасибо – msher420