2011-01-24 2 views
2

У меня есть класс:Как узнать, какой класс называется статическим методом?

class Superclass { static List list() { ... } } 

и подклассы:

class Subclass extends Superclass { ... } 
class Subclass2 extends Superclass { ... } 

Я хочу, чтобы вызвать list метод, как это: Subclass.list() или Subclass2.list(), и сделать что-то другое, на основании которого подкласс вызвавшего его ,

Есть ли способ определить, какой подкласс вызывает метод list?

Примечание: Я не хочу переопределять метод list в каждом из подклассов.

ОБНОВЛЕНИЕ: Все говорят, что это плохой дизайн, и в большинстве случаев я думаю, что это будет так, но я не думаю, что это в моем случае. Мой ORM определяет методы, которые принимают в java.lang.Class. Я хочу предоставить сокращение для своих методов ORM, чтобы я мог сказать User.list(...) вместо ORM.list(User.class, ...).

+5

переопределение в подклассах, кажется, как правильно делать. Почему вы не хотите этого делать? –

+0

@ Oli - метод Superclass.list в основном либо будет вызывать getFromDatabase (Subclass.class), либо getFromDatabase (Subclass2.class) и т. Д. Я хочу, чтобы любые классы, которые были получены из «Суперкласса», чтобы иметь возможность сказать 'Subclass.list()', чтобы просто получить список своего типа из базы данных. 'list' - не единственный метод' Superclass', поэтому я не хочу переопределять 5 разных методов в каждом подклассе. – Kyle

+3

@Kyle: вместо некоторого простого шаблона в каждом производном классе вам понадобится поддерживать кучу проверок типа 'if-else' в каждом методе базового класса. Это безумие! –

ответ

1

Звучит как проблема интерфейса/реализации.

Создайте интерфейс для метода list(), а затем напишите две реализации, Subclass использует реализацию1, Subclass2 использует реализацию2.

UPDATE

Посмотрите на мой комментарий, проверить этот вопрос How do I find the caller of a method using stacktrace or reflection?

Как все комментарии, я думаю, нужно пересмотреть свой дизайн и либо Переопределение методов в подклассах как государств Оли или создать интерфейса и реализации.

+0

Я не хочу писать код в подклассах. Метод 'Superclass.list' в основном либо будет вызывать' getFromDatabase (Subclass.class) ', либо' getFromDatabase (Subclass2.class) ' – Kyle

+0

Взгляните на http://stackoverflow.com/questions/421280/in-java -how-do-i-find-the-call-of-a-method-using-stacktrace-or-reflection, я не думаю, что это хорошая модель/дизайн в вашей ситуации. –

0

Вы могли бы сделать метод списка принять ARG, вызовите метод как

Subclass.list(type) 

, а затем проверить тип. Это своеобразная мысль. Возможно, вы захотите рассмотреть другой вариант дизайна. Может быть, лучше создать

listForSubclass1 

или

listForSubclass2 

методы, но даже тогда это не кажется правильным ...

+0

Да, я думал, что могу просто передать тип класса, но это дополнительная работа каждый раз, когда я хочу позвонить. В основном я хочу, чтобы это было так красиво. – Kyle

+0

@kyle, он не должен быть типом. также, что делает список? – hvgotcodes

+0

См. Обновление, которое я написал на мой вопрос. – Kyle

1

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

Или вы имеете в виду переопределение статического метода? Это невозможно, по крайней мере, не в значимом ключе. Вы можете попытаться скрыть статический метод суперкласса, определив его в подклассе, но это не истинное отношение наследования.

+0

Метод получает список из базы данных нужного типа. Он не полагается на какие-либо переменные-члены, поэтому я думаю, что он должен быть статичным. В основном я пытаюсь сделать то, что делает инфраструктура Grails, и предоставить всем моим классам моделей возможность сказать 'User.list()', чтобы получить список пользователей из базы данных. Или 'Post.list()' и т. Д. – Kyle

0

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

1

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

Следующий фрагмент должен напечатать

SuperClass.list() - вызывается Подкласс
или
SuperClass.list() - вызывается Subclass2

... 
    static List list() { 
     System.out.println("SuperClass.list() - called by "+Thread.currentThread().getStackTrace()[3].getClassName()); 
//[3] because you want to skip these last three calls to get to this information -:) 
    } 
... 
+0

Я рассматривал этот маршрут, однако я использую Groovy, и индекс на трассе стека, вероятно, будет сильно отличаться из-за динамической природы языка. – Kyle

+0

Возможно, вы можете создать небольшую оболочку, которая выполняет итерации над Thread.currentThread(). Элементы getStackTrace() и разбивают на/возвращает первое появление подкласса Суперкласса. –

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