2015-06-24 3 views
-2

говорят, что есть 2 класса ...Как узнать, какой класс называется абстрактным методом?

public class NotAbstract1 extends AnAbstract { 
    NotAbstract1() { super(); } 
} 

public class NotAbstract2 extends AnAbstract { 
    NotAbstract2() { super(); } 
} 

public abstract class AnAbstract { 
    AnAbstract() { //do something } 
    abstract void saySomething() { System.out.println("Something"); } 
} 

В этом примере NotAbstract1 и NotAbstract2 можно вызывать saySomething(). Как я могу, из метода saySomething()AnAbstract признать класс, который его назвал? Без указания класса или идентификатора.

Опять же, простым решением является изменение подписи метода saySomething(Class clazz), но я хотел бы не сделать это. У меня есть ощущение, что это можно сделать с отражением, поэтому я добавляю этот тег к вопросу.

+3

Возможно, ваш вопрос может быть проблемой [XY] (http://mywiki.wooledge.org/XyProblem), где вы спрашиваете «как исправить эту проблему с кодом», когда лучшим решением является использование другого подхода полностью , Подумайте, расскажите нам общую проблему, которую вы пытаетесь решить, а не как пытаетесь ее решить. –

+1

Что вы пытаетесь достичь? Как вы собираетесь использовать знания о типе экземпляра 'this'? Если у вас есть сценарий типа 'if (это NotAbstract1) {fooX();} else if (это NotAbstract2) {fooY();}', тогда вы должны просто добавить другой метод в 'AnAbstract', например' foo() ' и переопределить его в каждом не-абстрактном классе и переместить каждый 'fooX' и' fooY' в этот метод. Таким образом, в 'saySomething' вам просто нужно будет вызвать' foo() '. – Pshemo

+0

Вы спрашиваете о типе 'this'? Я не уверен, что ты есть. –

ответ

1

Вы можете позвонить this.getClass() в saySomething() - это вернет вам тип текущего экземпляра - либо notAbstract1 или notAbstract2.

+0

Что происходит, когда у вас есть два уровня подклассов, каждый из которых вызывает супер-реализацию 'saySomething'? –

+0

@SotiriosDelimanolis, 'getClass()' всегда возвращает текущий тип экземпляра, на него не влияет ни иерархия классов, ни метод, в котором он был вызван. – user3707125

+0

Вы меня неправильно поняли. Возьмите класс 'A', который расширяет класс' B', который расширяет класс 'AnAbstract'. Оба 'A' ​​и' B' переопределяют рассматриваемый метод, вызывая их реализацию 'super'. Если у вас есть экземпляр 'A', который делает это, он будет вызывать реализацию' B', которая будет вызывать реализацию 'AnAbstract'. 'getClass' вернет' A', но из формулировки OP вопроса, они хотят 'B'. –

0

Прежде всего, эта линия не будет компилироваться:

abstract void saySomething() { System.out.println("Something"); } 

Вы не можете использовать как abstract модификатора и обеспечиваете тело метода.

Для печати класс вызывающего абонента, вы можете написать:

void saySomething() { 
    System.out.println(this.getClass().toString()); 
} 
0

Абстрактный ключевое слово в

abstract void saySomething(); 

является держателем место. Не может быть связанного с ним кода. Что она делает это гарантировать, что

public class NotAbstract1 
public class NotAbstract2 

оба имеют реальные реализации как так

public class NotAbstract1 extends AnAbstract { 
    void saySomething() { 
    System.out.println("I'm NotAbstract1"); 
    } 
} 

public class NotAbstract2 extends AnAbstract { 
    void saySomething() { 
    System.out.println("I'm NotAbstract2"); 
    } 
} 

Компилятор делает эти проверки, что существует метод saySomething() в суб классы при компиляции NotAbstract1 и NotAbstract2.

Когда вы держите

AnAbstract object = .... get it from somewhere ... 

Вы будете проводить либо NotAbstract1NotAbstract2 или какой-либо другой подкласс AnAbstract, но вы будете проводить как AnAbstract типа.

Когда вы звоните

AnAbstract object = .... get it from somewhere ... 
object.saySomething(); 

Если объект был первоначально построен как NotAbstract1 вы бы запустить

System.out.println("I'm NotAbstract1"); 

Если объект был первоначально построен как NotAbstract2 вы бы запустить

System.out.println("I'm NotAbstract2"); 

Если объект был другим k ind AnAbstract, вы должны запускать все, что было в определении этого подкласса saySomething().

0

Хотя вы можете проверить, используя this.getClass() внутри saySomething(), но если вы хотите иметь другое поведение этого метода, основанное на том, какой класс он вызывается от вас, должно быть идеально переопределить метод saySomething() в этих классах ,

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