简体   繁体   中英

Question about covariant parameters in Java

I have this piece of code:

class X {
    int x = 1;
}

class Y extends X {
    int y = 2;
}

class Z extends Y {
    int z = 3;
}


class A {
    public Y metodo1(Y y) {
        System.out.println("Metodo1 de A");
        return new Y();
    }

    public Y metodo2(Y y) {
        System.out.println("Metodo2 de A");
        return new Y();
    }
}

class B extends A {
    public X metodo1(Y y) {
        System.out.println("Metodo1 de B");
        return new X();
    }

    public Z metodo2(Y y) {
        System.out.println("Metodo2 de B");
        return new Z();
    }

    public void metodo3() {
        System.out.println("Metodo3 de B");
    }
}

class C extends A{
    public Y metodo1(X x) {
        System.out.println("Metodo1 de C");
        return new Y();
    }

    public Y metodo2(Z z) {
        System.out.println("Metodo2 de C");
        return new Z();
    }

    public void metodo3() {
        System.out.println("Metodo3 de C");
    }
}

public class DynamicBinding {
    public static void main(String[] args) {
        A b = new B();
        A c = new C();
        C c1 = new C();

        X x1 = b.metodo1(new Y());
        X x2 = b.metodo2(new Y());
        b.metodo3();

        X x3 = c.metodo1(new X());
        X x4 = c.metodo2(new Z());
        c.metodo3();

        X x5 = c1.metodo1(new Y());
        X x6 = c1.metodo1(new X());
    }
}

I know there are some errors like the covariant return type in

public X metodo1(Y y) {
      System.out.println("Metodo1 de B");
      return new X();
} 

or that b.metodo3(); doesn't exist, but my question is about this:

X x5 = c1.metodo1(new Y());
X x6 = c1.metodo1(new X());

Eclipse doesn't show me any errors, but I think that they have covariant arguments and that is not allowed in Java. What am I missing? (maybe in X x5 = c1.metodo1(new Y()); it calls the metodo1 of A, but I don't understand the other one).

Thanks!

A method in a sub class is not allowed to break the contract in a super class, so lets assume you have

Class SuperClass{
  ReturnType method(ParameterType p) {..}
}

then any SubClass must either override method with

ReturnType method(ParameterType p) {..}

or

ReturnTypeSubclass method(ParameterType p) {..}

This ensures that when the class is used, there's no issues with types. The contract isn't broken with covariant return types, because ReturnTypeSubClass is a ReturnType .


If you implement method in SubClass like so:

AnyType method(ParameterTypeSubClass p) {..}

..you're not overriding it. You're overloading it. Now there are two method in SubClass . One is inherited from SuperClass .

Imagine if it was overriding it and someone used the class like so:

Super s = new SubClass;
s.method(new ParameterType());

an error would be thrown, because the overriding method would not be able to take a ParameterType , and the contract would be broken.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM