2013-02-26 5 views
3

Как вызывать print *() всех классов в нижеприведенном сценарии, означает printA(), A B (B) печати B() и C printC() C внутри метода main().Способы вызова дочернего класса в java

class A 
{ 
    public void printA(){System.out.println("A.printA()");} 
} 

class B extends A 
{ 
    public void printB(){System.out.println("B.printB()");} 
} 

class C extends A 
{ 
    public void printC(){System.out.println("C.printC()");} 
} 
class DemoInheritence 
{ 
    public static void main(String[] str){ 
     printIt(new A()); 
     printIt(new B()); 
     printIt(new C()); 
    } 
    public static void printIt(A a) { 
     //Here I wants to call A's printA(), B's printB() and C's printC() 
     //So how can I do this 
    } 
} 

ответ

4

Для вас код, который вы могли бы использовать что-то вроде:

public static void printIt(A a) { 
    if(a instanceof B) { 
    ((B)a).printB(); 
    } else if(a instanceof C) { 
     ((C)a).printC(); 
    } else { 
     a.printA(); 
    } 

} 

Но это своего рода неправильно, вы должны пойдите с переопределением метода в дочерних классах A или еще лучше создайте интерфейс, который все ваши классы реализуют и используют этот интерфейс в вашем коде.

+0

Любое другое решение, а не использование 'instanceof' – user1041858

+0

@ user1041858, если вы хотите избежать использования «instanceof», вы должны перейти с переопределением метода печати, что означает, что класс A и его дети имеют метод, называемый print(), и его дети переопределяют этот метод (вы даже можете обеспечить его выполнение, создав метод и абстрактный абзац класса A). Но лучшим способом было бы создать интерфейс с методом печати и заставить все классы реализовать этот интерфейс. Таким образом, каждый класс будет иметь версию метода print(). Скажите, пожалуйста, если вы хотите, чтобы я объяснил это дальше. – comanitza

+0

@ user1041858 Если вы хотите определить, имеет ли объект определенный тип, скажите, пожалуйста, чтобы я мог объяснить это. – comanitza

11

Обычно, вы делаете что-то вроде этого, это называется переопределение:

class A 
{ 
    public void print(){System.out.println("A.printA()");} 
} 

class B extends A 
{ 
    public void print(){System.out.println("B.printB()");} 
} 

class C extends A 
{ 
    public void print(){System.out.println("C.printC()");} 
} 
class DemoInheritence 
{ 
    public static void main(String[] str){ 
     printIt(new A()); 
     printIt(new B()); 
     printIt(new C()); 
    } 
    public static void printIt(A a) { 
     a.print(); 
    } 
} 
+1

Но я не говорю об этом сценарии. Мой сценарий отличается от – user1041858

+1

Этот ответ получил большую поддержку, в то время как предложение было слишком простым и простым и не имело смысла для OP ..! –

+0

@ InfantPro'Aravind 'Я предполагаю, что это потому, что вопрос был недостаточно ясным. Я и 10 других людей неправильно поняли это –

0

Вы можете использовать API отражения, но тогда вы можете сделать некоторые предположения. Есть, по крайней мере 2 возможности:

Решение 1. Если метод печати называется «печать [имя класса]» вы получите метод по имени:

public static void printIt(Object o) { 
    Class objectClass = o.getClass(); 
    try { 
     Method printMethod = objectClass.getMethod("print" + objectClass.getName()); 
     printMethod.invoke(o); 
    } catch (NoSuchMethodException e) { 
     throw new IllegalStateException("Method print"+objectClass.getName()+"() doesn't exist", e); 
    } catch (InvocationTargetException e) { 
     throw new IllegalStateException("Problem calling method print"+objectClass.getName()+"()", e); 
    } catch (IllegalAccessException e) { 
     throw new IllegalStateException("Method print"+objectClass.getName()+"() is not accessible", e); 
    } 
} 

Решение 2. Если каждый класс всегда заявляет один метод вы берете первый метод, возвращаемый getDeclaredMethod класса пройденного объекта:

public static void printIt(Object o) { 
    Class objectClass = o.getClass(); 
    try { 
     Method printMethod = objectClass.getDeclaredMethods()[0]; 
     printMethod.invoke(o); 
    } catch (InvocationTargetException e) { 
     throw new IllegalStateException("Problem calling method print"+objectClass.getName()+"()", e); 
    } catch (IllegalAccessException e) { 
     throw new IllegalStateException("Method print"+objectClass.getName()+"() is not accessible", e); 
    } 
} 
+0

Вы не должны злоупотреблять отражением (java.lang.reflect) в этом тривиальном случае, особенно в производственном коде, он медленный, уродливый, слишком многословный и устаревший. – comanitza

+0

Я согласен, для этой точной проблемы, но мое решение является более общим, а затем проверяет instanceof, что может быть непригодно, если добавлены классы D, E и т. Д. Затем вам нужно изменить также метод printIt, который может быть не очевидным до тех пор, пока он не будет запущен, и это будет подвержено ошибкам. –

+0

И в первую очередь, данный случай в этом вопросе не является правильной архитектурой. Но иногда вам приходится работать в странной экосистеме. –

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