sshashank124
sshashank124

Reputation: 32189

Parameter type of method to correspond to inner class which extends super's inner class

I have some classes structured as follows:

class A {
    inner class B {}

    void func(B param) {}
}

class Asub extends A {
    inner class B extends A.B {}

    @Override
    void func(B param) {}      // problematic line
}

But the compiler doesn't allow it as a proper override and only allows it if I change (in Asub)

void func(B param)

to

void func(A.B param)

However I do not want to do that as I have some overriden functionality defined in Asub.B that I want to make use of but if I change the param type to A.B instead of B, the linter tells me that Asub.B is unused

I would appreciate any help in solving this issue or if it is not possible, a possible alternate approach to accomplish the functionality that I want

The actual context of this question has to do with Android RecyclerView.Adapters and ViewHolders but I don't think the problem resides there

Upvotes: 2

Views: 59

Answers (3)

Peter Kramer
Peter Kramer

Reputation: 192

I believe your best shot here is using generics.

Something along the lines of

abstract class A<T extends A.B> {
    class B {
      // ...
    }

    abstract void func(T param) {
      //..
    }
}

class Asub<Asub.B> extends A {
    class B extends A.B {
      // ...
    }


    @Override
    void func(Asub.B param) {
      // ...
    }
}

should probably do the job.

Upvotes: 1

zsmb13
zsmb13

Reputation: 89548

What language is this question for exactly? extends, void, and @Override are Java, while inner classis Kotlin.


Aside from that, it doesn't make sense to override a function and then restrict what it can take as its parameter. What do you expect to happen when someone does this?

A asub = new Asub();
asub.func(new A.B());

If you got what you wanted, this function call would no longer be valid - this is breaking the Liskov substitution principle, which basically prescribes "expect no more, provide no less". And thankfully, neither Java or Kotlin will allow this.

Upvotes: 2

kutschkem
kutschkem

Reputation: 8163

This has nothing to do with inner classes, the problem here is that you cannot override a function f(A) with f(B extends A), because all overridden methods have to be able to accept all parameter that would be allowed for the super method.

You can of course always cast to the subtype in the overriding method.

Upvotes: 2

Related Questions