Я плохо знаком с Java, и я перечитал по некоторым учебным руководствам на методах переопределения, но пример, на который я смотрю, не прокладывает себе путь, я ожидаю. Например, у меня есть код:
public class A{
public void show(){
System.out.println("A");
}
public void run(){
show();
}
public static void main( String[] arg ) {
new A().run();
}
}
public class B extends A{
@Override
public void show(){
System.out.println("B");
}
}
Когда я инстанцирую и называю B.run (), я ожидал бы видеть произведенный "B". Однако я вижу вместо этого. Что я делаю неправильно?
Править: Да, классы находятся в двух отдельных файлах. Их показывают вместе для краткости.
Править: Я не уверен, как B инстанцируют, поскольку он делается сторонней программой с помощью classloader.
Править: Больше информации о сторонней программе. Это запускается путем вызова A.main (), который я первоначально не показал (извините). Я предполагаю, что должен сделать "новым () .run ()"; более универсальный для использования названия текущего класса. Это возможно?
Этот код выведет B
, если вы:
(new B()).run();
Какова бы ни была проблема, она не в том коде, который вы процитировали.
Обновление (после редактирования)
Если сторонняя программа вызывает A.main()
, то в B
нет ничего (разумного), что можно было бы сделать в B
, что впрыснуло бы себя в A
. Пока A.main
делает новую A().run()
, в ней будет экземпляр A
, а не экземпляр B
. Нет никакого "текущего имени класса", или если есть (зависит от вашей точки зрения), то это A
, а не B
.
Вы должны заставить стороннюю программу каким-то образом вызвать B
, а не A
, или просто изменить A
напрямую (например, полностью избавиться от B
). Вы делаете , а не , чтобы модифицировать A
, чтобы заставить его использовать B
; это плотно связывает его с потомком и делает разделение между ними в значительной степени бессмысленным.
Надеюсь, это поможет.
работает для меня.
Вот мой код для A и B:
package so;
public class A{
public void show(){
System.out.println("A");
}
public void run(){
show();
}
}
class B extends A{
@Override
public void show(){
System.out.println("B");
}
}
вот моя точка входа:
package so;
public class EntryPoint {
public static void main(String[] args) {
B b = new B();
b.run();
}
}
он печатает «B».
Я попробовал ваш пример, и мой выход был B .
Как вы создаете создание? Вот точный код, который я побежал.
public class Test {
public static class A {
public void show() {
System.out.println("A");
}
public void run() {
show();
}
}
public static class B extends A {
@Override
public void show() {
System.out.println("B");
}
}
public static void main(String args[]) {
A a = new B();
a.run();
}
}
Если ваша внешняя программа инсантаит А, у вас будет A, а не B.
, но вы можете попробовать что-то вроде этого, используя некоторые размышления и пропуск «com.mypackage.A» или "com.mypackage.b" как аргументы к вашей программе.
С помощью этого кода отсутствует исключение), вы сможете распечатать «A» или «B» в зависимости от параметра String.
public static void main( String[] arg ) {
String className = arg[0];
Class myClass = Class.forName(className);
Constructor cons = myClass.getConstructor(new Class[0]);
A myObject = (A) cons.newInstance(new Object[0]);
myObject.show();
}
Я попытался, поместив два ваших класса в два файла, и он сработал хорошо, выведя "B". Я вызвал :
B b = new B();
b.run();
UPDATED : Также работает как (потому что это тот же самый экземпляр среды выполнения):
A a = new B();
a.run();
Это зависит от реализации. Попробуйте это:
A v1 = new A();
A v2 = new B();
B v3 = new A();
B v4 = new B();
v1.run()
v2.run()
v3.run()
v4.run()