какая функция используется в этих расширенных классах? - PullRequest
1 голос
/ 03 июля 2019

Я пытаюсь понять полиморфизм и наследование.Поэтому я написал некоторый код и попытался проследить, что происходит.

Я просто не понимаю, почему три последних метода также не выводят «B».Переменная-ссылка объекта всегда Top, а параметры всегда являются объектами классов, расширяющих Top.И если эти последние три метода выведите C, K и X: не должно быть tm.m (mm);напечатать J?Я не понимаю, может кто-нибудь объяснить мне?

public class polymorphie
{
    class Top
    {
        public void m( Top p ) { System.out.print("B"); }
        public void m( Bottom p ) { System.out.print("C"); }

    }

    class Middle extends Top
    {
        public void m( Bottom p ) { System.out.print("K"); }
        public void m( Middle p ) { System.out.print("J"); }       
    }

    class Bottom extends Middle
    {
        public void m( Middle p ) { System.out.print("W"); }
        public void m( Bottom p ) { System.out.print("X"); }
    }


        public void run()
        {
            Top tt = new Top();
            Top tm = new Middle();
            Top tb = new Bottom();
            Middle mm = new Middle();
            Middle mb = new Bottom();
            Bottom bb = new Bottom();

            tt.m(tt);                       // B
            tt.m(tm);
            tt.m(tb);
            tt.m(mm);
            tt.m(mb);
            tm.m(tt);
            tm.m(tm);
            tm.m(tb);
            tm.m(mm);                       // why not J?
            tm.m(mb);
            tb.m(tt);
            tb.m(tm);
            tb.m(tb);
            tb.m(mm);         
            tb.m(mb);               

            System.out.println();            

            tt.m(bb);                       // C 

            tm.m(bb);                       // K   

            tb.m(bb);                       // X
        }      
}

1 Ответ

1 голос
/ 05 июля 2019

В результате вывод строки tm.m(mm); равен B, потому что вызванный метод - public void m( Top p ) класса Top .

Здесь две концепции:

  1. в строке Top tm = new Middle();, даже если вы соединили tm с калькулятором среднего класса, это все равно ссылка на объект типа Top , поэтому методы tmОбъектом будут методы класса Top .Реализация этих методов заключается в том, что они написаны в верхнем классе, если они не переопределены в своем подклассе.
  2. Сигнатура вовлеченного метода не совпадает в верхнем классе Top и егоподкласс Middle : метод public void m( Top p ) не существует в среднем классе.Таким образом, метод высшего класса не переопределяется методом его подкласса.

Вы должны посмотреть на строки

 tm.m(bb);                       // K   
 tb.m(bb);                       // X

в качестве примера того, что я говорю.На самом деле tm является Top, но метод public void m(Bottom) существует в обоих классах Top и Middle, поэтому используется реализация класса Middle, и метод выводит «K» вместо «C».Та же причина для tb : это ссылка на объект Top, но в классе Top "granmother" метод public void m( Bottom p ) переопределяется, поскольку он находится в обоих классах с одинаковой сигнатурой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...