Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как узнать класс объекта? 
V
    Опции темы
ElKa
Дата 17.8.2008, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: 2
Всего: 4



есть список объектов разных классов, поэтому в качестве класса указан Object
надо для каждого из них вызвать метод getName(), который есть в каждом классе 
но для этого надо указать класс ((...)object).getName()
как можно его узнать? 
PM   Вверх
yar
Дата 17.8.2008, 01:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 8.9.2007
Где: Одесса, Украина

Репутация: 1
Всего: 8



Класс объекта узнать можно с помощью рефлексии. Однако сделать так как ты хочешь нельзя - привести объект к неизвестному на этапе компиляции классу. Здесь можно поступить несколькими способами.

1. Реализовать в каждом классе некий интерфейс, имеющий необходимый метод. Затем приводить наши Object-ы к этому интерфейсу и вызывать метод...

2. Вызвать метод с помощью рефлексии

Код

        Object obj = ...;
        Class<?> class = obj.getClass();
        Method method = c.getMethod("getName", null);
        m.invoke(method, null);


3. Или использовать "утиную типизацию" (если нет возможности реализовать в классах интерфейс); как её можно эмулировать в Java я описал вот тут.

--------------------
Если бы строители возводили здания так, как программисты пишут программы, первый же дятел уничтожил бы мировую цивилизацию.Джеральд Вайнберг
PM MAIL WWW   Вверх
ElKa
Дата 17.8.2008, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: 2
Всего: 4



yar, 

спасибо! 

Я реализовала так:

Код


Object var = varList.get(i);
if(var instanceof Class1) str = ((Class1)var).getName();
if(var instanceof Class2) str = ((Class2)var).getName();
if(var instanceof Class3) str = ((Class3)var).getName();
 


Это нормально? Как я понимаю, проще нельзя. 
PM   Вверх
Ortega
Дата 18.8.2008, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 5.11.2005
Где: Харьков, Украина

Репутация: 4
Всего: 6



Цитата(ElKa @ 17.8.2008,  10:07)
yar, 

спасибо! 

Я реализовала так:

Код


Object var = varList.get(i);
if(var instanceof Class1) str = ((Class1)var).getName();
if(var instanceof Class2) str = ((Class2)var).getName();
if(var instanceof Class3) str = ((Class3)var).getName();
 


Это нормально? Как я понимаю, проще нельзя.

Это путь наименьшего сопротивления и его право на жизнь зависит от масштабов того, частью чего этот код является.
В принципе, это неправильно, и вся моя ООП сущность против такого издевательства. Однако если речь идет о (относительно) небольшой программке, то можно и так.
Товарищ yar предложил два отличных способа. Причем первый - предпочтительнее. 
Вам можетбыть лень так делать, однако поверьте мне - потом может быть значительно хуже smile
--------------------
Всему свое время (с) ЧайфНе парься, будь счастлив (с) Пеппи Длинный Чулок
PM MAIL WWW ICQ Skype GTalk   Вверх
alexadr
Дата 18.8.2008, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 25.9.2006

Репутация: 4
Всего: 4



Однозначно 1-ый вариант описанный yar

А вот это 
Цитата(ElKa @  17.8.2008,  10:07 Найти цитируемый пост)

Я реализовала так:
Код

 Object var = varList.get(i);
if(var instanceof Class1) str = ((Class1)var).getName();
if(var instanceof Class2) str = ((Class2)var).getName();
if(var instanceof Class3) str = ((Class3)var).getName();
 

лучше не использовать даже в маленьких программках, т.к. часто они очень быстро разрастаютсяsmile

PM MAIL   Вверх
Platon
Дата 18.8.2008, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Цитата(alexadr @  18.8.2008,  12:03 Найти цитируемый пост)
Однозначно 1-ый вариант описанный yar

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

Приведенный поход не развалится, если его правильно реализовывать. Я вижу правильный подход такой:

Код

public class NameFetchUtil {
    public static String getName(Object var) {
        if (var instanceof Nameable) return ((Nameable)var).getName();
        if (var instanceof Class1) return ((Class1) var).getName1();
        if (var instanceof Class2) return ((Class2) var).getName2();
        if (var instanceof Class3) return ((Class3) var).getName3();
        throw new IllegalArgumentException("Unsupported class type: " + var.getClass().getCanonicalName());
    }
}


т.е. такой черный ящичек. Когда нам надоест добавлять классы, мы сможем легко поменять на рефлексию.

Это сообщение отредактировал(а) Platon - 18.8.2008, 11:29
PM MAIL ICQ   Вверх
Platon
Дата 18.8.2008, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Причем мы видим преимущество приведенного мной подхода, мало того, что код легко поддерживать, и нам неважно как он работает, плюс наш метод работает еще и как адаптер.
PM MAIL ICQ   Вверх
ElKa
Дата 18.8.2008, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: 2
Всего: 4



я так ничего и не поняла 

как реализовать первый вариант? 

Это сообщение отредактировал(а) ElKa - 18.8.2008, 11:44
PM   Вверх
alexadr
Дата 18.8.2008, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 25.9.2006

Репутация: 4
Всего: 4



интервейс
Код

interface GetNameInterf {
    public String getName();
}


реализующие этот интерфейс классы:
Код

class FirstClass implements GetNameInterf {
    public String getName() {
        return "FirstClass_name";
    }
}

class SecondClass implements GetNameInterf {
    public String getName() {
        return "SecondClass_name";
    }
}

class ThirdClass implements GetNameInterf {
    public String getName() {
        return "ThirdClass_name";
    }
}


использование всего ентого добра:
Код

GetNameInterf  var = (GetNameInterf )varList.get(i);
String name = var.getName();


PM MAIL   Вверх
ElKa
Дата 18.8.2008, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: 2
Всего: 4



alexadr, 

то есть придется везде вместо Object писать GetNameInterf?
PM   Вверх
AxNe0
Дата 18.8.2008, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 24.4.2006
Где: St. Petersburg

Репутация: 4
Всего: 5



ElKa, если это для решения твоей задачи с вызовом toEffString(), то это неправильный подход с точки зрения ООП!

Это сообщение отредактировал(а) AxNe0 - 18.8.2008, 13:14


--------------------
SCJP 6, SCBCD 5, OCEWSD 6
blog
PM ICQ Skype   Вверх
ElKa
Дата 18.8.2008, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: 2
Всего: 4



AxNe0, 

какой подход неправильный? мой?
PM   Вверх
alexadr
Дата 18.8.2008, 13:16 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 25.9.2006

Репутация: 4
Всего: 4



Цитата(ElKa @  18.8.2008,  12:43 Найти цитируемый пост)
то есть придется везде вместо Object писать GetNameInterf? 

да!
PM MAIL   Вверх
AxNe0
Дата 18.8.2008, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 24.4.2006
Где: St. Petersburg

Репутация: 4
Всего: 5



ElKa, да.


--------------------
SCJP 6, SCBCD 5, OCEWSD 6
blog
PM ICQ Skype   Вверх
ElKa
Дата 18.8.2008, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 300
Регистрация: 1.2.2006

Репутация: 2
Всего: 4



Цитата(alexadr @ 18.8.2008,  11:56)
 
Код

class FirstClass implements GetNameInterf {
    public String getName() {
        return "FirstClass_name";
    }
}
 

 

а почему FirstClass_name, а не  FirstClass?
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0576 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.