2014-11-26 4 views
3

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

public abstract class Foo

и единственный конструктор

public Foo() 
{ 
} 

Учитывая, что этот конструктор должен быть вызван из построение дочернего класса, есть способ восстановить имя этого дочернего класса в конструкторе Foo?

Я бы предпочел не сделать что-то злобное со следами стека.

+0

Без StackTrace, что довольно трудно, если, конечно, вы не передать его как парам – stealthjong

ответ

3

Если вы хотите, чтобы название класса, подобного getClass().getSimpleName(), достаточно просто использовать

public Foo() { 
    declaredClassname = this.getClass().getSimpleName(); 
} 

Из-за полиморфности он всегда будет вызывать getClass() из дочернего класса.

+0

Уверен, что я буду использовать его все время – for3st

+0

Да, я уверен, я использую его для объектов couchDb, где вам нужен атрибут типа, чтобы иметь возможность выбирать их, и я просто использую этот apporach (базовый класс, который устанавливает 'setDbType (this.getClass(). getSimpleName()); 'в конструкторе базового класса (поэтому супер-конструктор для всех объектов)), хотя его не абстрактно, но это не должно меняться – for3st

0

Вы можете получить его в конструкторе подкласса и передать его в виде строки в супер конструктор класса:

public foo(String className) 
{ 
} 

//subclass constructor 
public subclass() 
{ 
    super("subclass"); 
} 

Или вы могли бы сделать:

public foo(String className) 
{ 
} 

//subclass constructor 
public subclass() 
{ 
    super(this.getClass().getSimpleName()); 
} 
+0

Это действительно не является хорошим решением GetClass() getSimpleName() просто работает, как ожидалось. с дочерними классами – for3st

+0

@ for3st Почему это не хорошо? – brso05

+1

Это добавляет сложности, когда существуют более простые решения – for3st

1

Вы можете использовать следующее:

public Foo() 
{ 
    System.out.println(this.getClass().getSimpleName()) 
} 
1

Конечно:

getClass() 

Но обратите внимание, что экземпляр класса ребенок (т.е. его поля) до сих пор не инициализируется, и будет сделано после того, как конструктор базового класса. Также не вызывайте переопределяемые методы по той же причине.

Исполнение класса ребенка конструктор:

  1. супер() или супер (...) Конструктор
  2. полей, которые инициализируются Xxx xxx = ...;
  3. остальной код конструктора
0

В случае вы находитесь в иерархии классов и хотите знать класс, который на самом деле построен, вы можете использовать getClass(). Если вы хотите знать «самый верхний» класс вместо класса «самый нижний», перебирайте суперклассы, пока не найдете свой собственный класс.

import static java.lang.System.err; 
abstract class A { 
    protected A() { 
     err.format("%s %s%n", getClass().getName(), getTopMostSubclass().getName()); 
    } 
    Class<? extends A> getTopMostSubclass() { 
     Class<?> previousClass = getClass(), currentClass; 
     while (!A.class.equals(currentClass = previousClass.getSuperclass())) 
      previousClass = currentClass; 
     return (Class<? extends A>) previousClass; 
    } 
} 
class B extends A {} 
class C extends B {} 
public class Main { 
    public static void main(final String... args) { 
     new B(); // prints B B 
     new C(); // prints C B 
    } 
} 
0

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

abstract class ParentClass { 
    public ParentClass() { 
     System.out.println(this.getClass().getName()); 
    } 
    public String doSomething() { 
     return "Hello"; 
    } 
} 

class ChildClass extends ParentClass { 
} 

... 
... 

ChildClass obj = new ChildClass();// will output ChildClass 
Смежные вопросы