Переопределение метода Java

Я плохо знаком с 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 ()"; более универсальный для использования названия текущего класса. Это возможно?

5
задан Kara 28 June 2017 в 20:39
поделиться

6 ответов

Этот код выведет B, если вы:

(new B()).run();

Какова бы ни была проблема, она не в том коде, который вы процитировали.

Обновление (после редактирования)

Если сторонняя программа вызывает A.main(), то в B нет ничего (разумного), что можно было бы сделать в B, что впрыснуло бы себя в A. Пока A.main делает новую A().run(), в ней будет экземпляр A, а не экземпляр B. Нет никакого "текущего имени класса", или если есть (зависит от вашей точки зрения), то это A, а не B.

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

Надеюсь, это поможет.

6
ответ дан 18 December 2019 в 13:14
поделиться

работает для меня.

Вот мой код для 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».

2
ответ дан 18 December 2019 в 13:14
поделиться

Я попробовал ваш пример, и мой выход был 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();
    }
}
1
ответ дан 18 December 2019 в 13:14
поделиться

Если ваша внешняя программа инсантаит А, у вас будет 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();

}
1
ответ дан 18 December 2019 в 13:14
поделиться

Я попытался, поместив два ваших класса в два файла, и он сработал хорошо, выведя "B". Я вызвал :

 B b = new B();
 b.run();

UPDATED : Также работает как (потому что это тот же самый экземпляр среды выполнения):

 A a = new B();
 a.run();
3
ответ дан 18 December 2019 в 13:14
поделиться

Это зависит от реализации. Попробуйте это:

 A v1 = new A();
 A v2 = new B();
 B v3 = new A();
 B v4 = new B();

 v1.run()
 v2.run()
 v3.run()
 v4.run()
1
ответ дан 18 December 2019 в 13:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: