Java abstract method with abstract parameter and inheritance

Recently, I ran into a problem with the API and implementation, where the following type of code appeared:

API - abstract class:

public abstract class A {
 public A sum(A a) {
  System.out.println("A.sum(A) called");
  return null;
 }
}

The implementation is a simple class:

public class B extends A {
 public B sum(B b) {
  System.out.println("B.sum(B) called");
  return null;
 }
}

When it comes to using it, I write:

public class Main {

  public static void main(String args[]) {
    B b = new B();
    A basa = new B();

    b.sum(b);
    basa.sum(b);
    basa.sum(basa);
  }  
}

Result:

% java Main
B.sum(B) called
A.sum(A) called
A.sum(A) called

I understand that the sum B does not redefine the sum A, since its signature is different, but I would like to ensure an effective implementation of the sum for objects of effective type B. I think that this design is quite classic and would like now to develop my API and implementation so that it is effective.

, (A a) be , b Of B sum (B) super, , instanceOf ( , , "" .

+3
3

instanceof , . . , . abstract A, , .

, , accept . "Instanceof" -check . ( , , instanceof.)

interface Visitor {
    public A accept(A a);
    public B accept(B b);
}

class A {
    public A sum(A a) {
        System.out.println("A.sum(A) called");
        return null;
    }

    public A visit(Visitor sv) {
        return sv.accept(this);
    }
}

class B extends A {
    public B sum(B b) {
        System.out.println("B.sum(B) called");
        return null;
    }

    public B visit(Visitor sv) {
        return sv.accept(this);
    }
}

public class Test {

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        A basa = new B();

        a.visit(new SumVisitor(b));        // a.sum(b);
        b.visit(new SumVisitor(b));        // b.sum(b);
        basa.visit(new SumVisitor(b));     // basa.sum(b);
        basa.visit(new SumVisitor(basa));  // basa.sum(basa);
    }

    static class SumVisitor implements Visitor {
        A arg;
        SumVisitor(A arg) { this.arg = arg; }
        public A accept(A a) { return a.sum(arg); }
        public B accept(B b) { return b.sum(arg); }
    }
}

:

A.sum(A) called
B.sum(B) called
B.sum(B) called
B.sum(B) called

; , , , , ( ) . , :)

+3

B A myA.sum(myB), B sum , , sum -, .

UPDATE:

, . , :

public abstract class A {
    public <T extends A> T sum(T a) {
        System.out.println("A.sum(A) called");
        return null;
    }

    public static void main(String args[]) {
        B b = new B();
        b.sum(b);

        A basa = new B();
        basa.sum(b);
        basa.sum(basa);
    }

    public static class B extends A {
        @Override
        public <T extends A> T sum(T b) {
            System.out.println("B.sum(B) called");
            return null;
        }
    }
}

@aioobe , - . , .

+3

, , instanceof ? JDK, " " . : ", ".

0
source

Source: https://habr.com/ru/post/1752428/


All Articles