Как наследование работает в этом фрагменте кода? - PullRequest
1 голос
/ 24 февраля 2020

Итак, ребята, я играл с наследованием и наткнулся на эту программу:

public class HelloWorld {
    static class A {
        void f() { System.out.println("A"); }
    }

    static class B extends A {
        void f() { System.out.println("B"); }
    }

    static class C {
        void func(B b) { b.f(); }
    }

    static class D extends C {
        void func(A a){ a.f(); }
    }

    public static void main(String args[]) {
        ( (new D())).func( (A) (new B()));
        A a =  new B();
        a.f();
        B b = new B();
        C c = new D();
        c.func(b);
    }
}

Так почему же, несмотря на то, что A и C реализованы точно так же, как в финале В нескольких строках методы A переопределяются B, но C не переопределяются D? Программа печатает следующим образом: B B B

Ответы [ 2 ]

2 голосов
/ 24 февраля 2020

Поскольку определение функции класса D является более общим, чем C. Функция C принимает параметр типа B, но функция D принимает параметр типа A, который является родительским для B. Она является более общей, чем функция, определенная в C.

static class D extends C {
    void func(A a){ 
        a.f(); 
    }
}

  B b = new B();
  C c = new D();
  c.func(b);

Переменная c указывает на объект D, поэтому c .fun c (b) вызывает метод, определенный в D. A является родителем B, поэтому вызывается метод B. То же, что и при использовании ссылки A, как показано ниже.

  A a =  new B();
  a.f();
0 голосов
/ 24 февраля 2020

Это потому, что метод func в D не переопределяет то же значение C, что и изменение подписи.

static class C {
    void func(B b) { b.f(); }
}
static class D extends C {
    void func(B a){ a.f(); }
}

Это приведет к переопределению метода

...