2010-05-18 5 views
12

Есть ли способ узнать имя производного класса из экземпляра базового класса?Как найти подкласс из экземпляра базового класса?

.: например

class A{ 
    .... 
} 
class B extends A{ 
    ... 
} 
class c extends A{ 
    ... 
} 

теперь, если метод возвращает объект A, я могу узнать, если он имеет тип B или C?

+7

Обратите внимание, что [тип sniffing] (http://www.javapractices.com/topic/TopicAction.do?Id=3) - это немного запаха кода. Это не всегда неправильно, но это неправильный подход достаточно часто, чтобы вы внимательно изучили свой дизайн. Если возможно, полагайтесь на полиморфизм (но см. Также [Steve Yegge's [When Polymorphism Fails] (http://sites.google.com/site/steveyegge2/when-polymorphism-fails)). – outis

ответ

17

с использованием либо instanceof или Class#getClass()

A returned = getA(); 

if (returned instanceof B) { .. } 
else if (returned instanceof C) { .. } 

getClass() будет возвращать либо из: A.class, B.class, C.class

Внутри if-предложении вы должны обратное приведение - т.е.

((B) returned).doSomethingSpecificToB(); 

Тем не менее, считается, что использование instanceof или getClass() - это плохая практика. Вы должны использовать polymorphism, чтобы избежать необходимости проверки конкретного подкласса, но я не могу рассказать вам больше с предоставленной информацией.

+1

+1 за избиение меня. –

+1

Замечание об использовании полиморфизма в этой ситуации: у вас может быть метод 'getType()' или что-то подобное в реализации 'A' и переопределить этот метод в' B' и 'C'. Поскольку все методы являются виртуальными в java, вызов 'getType()' разрешает конкретный подтип. – aioobe

4

Вы пробовали использовать instanceof

например

Class A aDerived= something.getSomethingDerivedFromClassA(); 

if (aDerived instanceof B) { 

} else if (aDerived instanceof C) { 

} 

//Use type-casting where necessary in the if-then statement. 
2

Короткий ответ на ваш вопрос

Есть ли способ узнать имя производного класса из объекта базового класса?

не, супер-класс не имеет возможности сказать имя/тип суб-класса.

Вы должны допросить объект (который является экземпляром подкласса) и спросить, является ли он: instanceof конкретным подклассом или его метод getClass().

0

Есть 2 способа, я могу думать о 1) One с помощью Reflection API Java 2) Другое одно было бы с InstanceOf

Другой метод может быть Сравнение объектов к объектам, я не знаю, как это может быть, вы можете попробовать это

0

вы можете сделать это в подклассе конструктор

class A { 
    protected String classname; 
    public A() { this.classname = "A"; } 
    public String getClassname() { return this.classname; } 
} 
class B extends A { 
    public B() { 
     super(); 
     this.classname = "B"; 
    } 
} 

Так

A a = new A(); 
a.getClassname(); // returns "A" 
B b = new B(); 
b.getClassname(); // returns "B" 
((A)b).getClassname(); // Also returns "B" 

Поскольку он забрасывается в объект «A», он вызывается функцией «A» getClassname(), но возвращает значение, заданное конструктором, который был конструктором «B».

Примечание: Вызов super(); перед установкой его

0

Есть ли способ узнать имя производного класса из экземпляра базового класса?

Как ответил here, вы можете использовать этот чрезвычайно простой подход.

abstract class A { 
    public final String getName() { 
     return this.getClass().getName(); 
    } 
} 

class B extends A { } 

class C extends A { } 

затем просто распечатать текущую class имя:

B b = new B(); 
C c = new C(); 

System.out.println(b.getName()); 
System.out.println(c.getName()); 

Выход:

com.test.B 
com.test.C 

Там нет необходимости хранить дополнительные Strings, проверьте instanceof или override метода в любом подклассе.

Смежные вопросы