Модераторы: 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   Вверх
Ortega
Дата 18.8.2008, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Так нужно именно имя класса?  smile 
--------------------
Всему свое время (с) ЧайфНе парься, будь счастлив (с) Пеппи Длинный Чулок
PM MAIL WWW ICQ Skype GTalk   Вверх
ElKa
Дата 18.8.2008, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



все равно не получается
мне не стринг нужен, а класс
а стринг я не могу задать как имя класса

Код

String eclass = ((ClassNameInterface)prE).getClassName();
((eclass)prE).defOutVar();


defOutVar() в интерфейсе нет.. как мне его вызвать? 
PM   Вверх
Ortega
Дата 18.8.2008, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



ElKa, ОСТАНОВИСЬ! И сформулируй, пожалуйста, задачу.
--------------------
Всему свое время (с) ЧайфНе парься, будь счастлив (с) Пеппи Длинный Чулок
PM MAIL WWW ICQ Skype GTalk   Вверх
ElKa
Дата 18.8.2008, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



 
Ortega, 

ну я же сформулировала.. у меня объекты разных классов обрабатываются по очереди..
для каждого из них вызывается метод.. надо узнать их классы чтобы его вызывать..
я сделала интерфейс и в каждом классе добавила метод который возвращает имя класса как стринг..
но использовать этот стринг в других случаях я не могу.. 
если мне например надо для некоторых объектов вызвать другой метод которого нет у других..
получается опять та же проблема: как узнать класс? 
PM   Вверх
AxNe0
Дата 18.8.2008, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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


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


Опытный
**


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

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



AxNe0, 

у меня есть разные классы объектов.. для каждого из них  есть метод для печати.. 
для этого я сделала интерфейс и там этот метод задекларировала..
а потом в каждом классе заимплементировала..
это работает..


но еще например некоторые объекты могут быть двух видов..
например Предикат  это или if-выражение или определение переменной  x=...
и в этих двух классах есть метод которого нет в других..
и в этом общем объекте Предикат мне надо его вызвать..
как мне получить класс для этого..
мне что же теперь для каждого случая интерфейс создавать?
PM   Вверх
Ortega
Дата 18.8.2008, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



ElKa, без обид, пожалуйста, но мне кажется, что имеет место быть попытка удаления гланд через известное место. 
Я в том смысле, что возможно, тут можно оюойтись без извращений и все намного проще?
Давай ты расскажешь нам, чего именно ты пытаешься добиться этими манипуляциями.

Добавлено через 1 минуту и 55 секунд
Цитата(ElKa @ 18.8.2008,  15:54)
AxNe0, 

у меня есть разные классы объектов.. для каждого из них  есть метод для печати.. 
для этого я сделала интерфейс и там этот метод задекларировала..
а потом в каждом классе заимплементировала..
это работает..


но еще например некоторые объекты могут быть двух видов..
например Предикат  это или if-выражение или определение переменной  x=...
и в этих двух классах есть метод которого нет в других..
и в этом общем объекте Предикат мне надо его вызвать..
как мне получить класс для этого..
мне что же теперь для каждого случая интерфейс создавать?

А еще есть наследование....
Когда у классов, имеющих что-то общее, есть общий класс-предок.
Elka, почитай основы ООП.
--------------------
Всему свое время (с) ЧайфНе парься, будь счастлив (с) Пеппи Длинный Чулок
PM MAIL WWW ICQ Skype GTalk   Вверх
ElKa
Дата 18.8.2008, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ortega, 

у всех этих классов есть предок это узел синтаксического дерева.. они его наследуют..
так что еще одно наследование исключается..

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


Шустрый
*


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

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



Цитата(ElKa @  18.8.2008,  16:02 Найти цитируемый пост)
но неужели нет никакой относительно простой возможности узнать класс объекта??? 

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


Шустрый
*


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

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



Полиморфизм, полиморфизм и еще раз полиморфизм smile 
Вот примерно такая будет иерархия. 
user posted image
Код

((SyntaxTreeNode)obj).getOffString()


Код

((Predicate)obj).defOutVar()

--------------------
Всему свое время (с) ЧайфНе парься, будь счастлив (с) Пеппи Длинный Чулок
PM MAIL WWW ICQ Skype GTalk   Вверх
AxNe0
Дата 18.8.2008, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ElKa, ты не с той стороны пытаешься решить задачу. Хорошая, с точки зрения ООП, структура классов и интерфейсов может существенно облегчить жизнь. Раз мы выяснили-таки, что у классов есть что-то общее, что мешает создать нечто подобное:
Код
// узел синтаксического дерева
class Node { }
// предикат
class Predicate extends Node {
    void methodPredicate() { /* do smth*/ }
}
// if-предикат
class PredicateIf extends Predicate { }
// x=
class PredicateAssignment extends Predicate { }

а туда, где тебе надо вызывать methodPredicate(), передавай массив Predicate[] predicates. И все будет удобно, красиво и поддерживаемо.

Добавлено @ 16:26
Ortega, +1 smile в чем рисовал? 

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


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


Опытный
**


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

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



AxNe0, 

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

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

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


 




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


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

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