Вызов метода суперкласса без его экземпляра с использованием отражения - PullRequest
3 голосов
/ 19 марта 2012

Пожалуйста, примите во внимание приведенный ниже код, демонстрирующий наследование и отражение:

    /*Parent class*/

    package basics;

    public class Vehicle {

        private void parentPrivateMethod() {
            System.out.println("This is the child private method");
        }

        public void print() {
            System.out.println("This is a Vehicle method");
        }

        public void overrideThisMethod() {
            System.out.println("Parent method");
        }

    }


    /*Child class*/

    package basics;

    public class Car extends Vehicle {

        private void childPrivateMethod() {
            System.out.println("This is the child private method");
        }

        public String returnCarName() {
            return "Manza";
        }

        @Override
        public void overrideThisMethod() {
            //super.overrideThisMethod();/*NOTE THIS*/
            System.out.println("Child method");
        }

    }


    /*Tester class*/
    package basics;

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;

    public class NewTester {

        /**
         * @param args
         * @throws NoSuchMethodException
         * @throws SecurityException
         * @throws InvocationTargetException
         * @throws IllegalAccessException
         * @throws IllegalArgumentException
         * @throws InstantiationException
         */
        public static void main(String[] args) throws SecurityException,
                NoSuchMethodException, IllegalArgumentException,
                IllegalAccessException, InvocationTargetException, InstantiationException {
            // TODO Auto-generated method stub

            Car carInstance = new Car();

            /* Normal method invocation */
            carInstance.overrideThisMethod();

            /* Reflection method invocation */
            Method whichMethod = Car.class.getSuperclass().getMethod(
                    "overrideThisMethod", null);
            whichMethod.invoke(carInstance, null);

            /* Work-around to call the superclass method */
            Method superClassMethod = Car.class.getSuperclass().getMethod(
                    "overrideThisMethod", null);
            superClassMethod.invoke(Car.class.getSuperclass().newInstance(), null);
        }

    }

Выход (с комментированной частью «NOTE THIS»):

        Child method
        Child method
        Parent method

В случае, еслиЭТА часть не закомментирована, метод суперкласса будет вызван, давая вывод:

        Parent method
        Child method
        Parent method
        Child method
        Parent method

Когда создается экземпляр Car, конструктор Vehicle запускается первым.Следовательно, я полагаю, что также создается экземпляр Vehicle, ссылка на который экземпляр Car хранится через «super».

Вопрос : Как вызвать версию суперкласса overrideThisMethod'без использования / * Обходного пути для вызова метода суперкласса * /?

Я что-то пропускаю здесь / делаю неправильные предположения здесь?

Ответы [ 2 ]

3 голосов
/ 19 марта 2012

Когда создается экземпляр Car, конструктор Vehicle запускается первым. Следовательно, я полагаю, что создается экземпляр Vehicle, чья ссылка на экземпляр Car хранится в «super».

Это не совсем правильно; создается только один объект. Конструктор Vehicle запускается, потому что он является экземпляром Vehicle и Car. Отдельного объекта Vehicle не существует, и super - это не ссылка на объект, а ключевое слово. Например, вы не можете передать super в методы в качестве аргумента.

Ключевое слово super позволяет сообщить компилятору, что вы хотите вызвать метод из суперкласса, не проверяя, переопределен ли метод в подклассах. Для этого компилятор генерирует вызов метода с инструкцией invokespecial JVM. Обычно компилятор выдает команду invokevirtual.

0 голосов
/ 19 марта 2012

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

Vehicle v = new Vehicle();
v.overrideThisMethod();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...