0

(This is a follow up to this question, which itself was a follow up to this question.)

I have the following interfaces/classes (skeleton code below)

interface Copyable<C extends Copyable<C>>  {
   interface Validator<V extends Validator<V>> extends Copyable<V>  {
      interface ValidateValue<O> extends Validator<ValidateValue<O>>  {

abstract class AbstractValidator<V extends AbstractValidator<V>> implements Validator<V>  {
   class VVNull<O> extends AbstractValidator<VVNull<O>> implements ValidateValue<O>  {

This used to work just grand when Copyable was implemented without the <C extends Copyable<C>> but, as the two previous questions make clear to me, Copyable really needs those generics.

Unfortunately, now I can't compile VVNull.

C:\java_code\CopyableCProblem.java:23: error: Validator cannot be inherited with different arguments: <ValidateValue<O>> and <VVNull<O>>

This is line 23 in the below source-code:

class VVNull<O> extends AbstractValidator<VVNull<O>> implements ValidateValue<O>  {

VVNull<O> is a ValidateValue<O>. It passes itself up as a generic-parameter for goodness-sakes, and it implements ValidateValue<O>. The inheritance is completely linear--there's no "diamond" inheritance or anything, it's Copyable<--Validator<--ValidateValue<--VVNull.

I realize--or actually, I should say I think--that self-generics will work, that is, if you make every class self-genericized, such as

VVNull<O,V extends VVNull<O,V>>

but I am desperate to find another solution. Self-referential generics are a complete mess when you get down to sub-classes that need their own additional generics. That's why I only self-genericize through Validator, because it's the least-likely candidate to be directly used. ValidateValue and VVNull are frequently and directly used. I really really hope that there are other possibilites.

Comparable works just fine without requiring self-generics in all its implementing classes, so how can I make this work for Copyable?

Thank you for any advice.

public class CopyableCProblem  {
}

interface Copyable<C extends Copyable<C>>  {
   C getObjectCopy();
}

interface Validator<V extends Validator<V>> extends Copyable<V>  {
}

interface ValidateValue<O> extends Validator<ValidateValue<O>>  {
   @Override
   ValidateValue<O> getObjectCopy();
   boolean isValid(O o_o);
}

abstract class AbstractValidator<V extends AbstractValidator<V>> implements Validator<V>  {
}

class VVNull<O> extends AbstractValidator<VVNull<O>> implements ValidateValue<O>  {
   @Override
   public VVNull<O> getObjectCopy()  {
      return  this;
   }
   public boolean isValid(O o_o)  {
      return  (o_o != null);
   }
}
Community
  • 1
  • 1
aliteralmind
  • 19,847
  • 17
  • 77
  • 108
  • Did you try doing `interface ValidateValue> extends Validator` – ced-b Jan 31 '14 at 03:21
  • Added the answer to my post. Should have thought about it before. – aliteralmind Jan 31 '14 at 03:33
  • "but, as the two previous questions make clear to me, Copyable really needs those generics." Well, they are wrong. Those bounds are not used in your code. It works equally without them. – newacct Feb 01 '14 at 03:18
  • "Those bounds are not used in your code." I don't understand this part. I'm getting the impression that self referential generics force all implementing classes to also have self-referential generics, which becomes an enormous mess the deeper you get into your hierarchy. – aliteralmind Feb 01 '14 at 13:41
  • Your class `VVNull` is trying to implement `Validator` through two different paths with different type arguments; one by subclassing `AbstractValidator>` (which implements `Validator>`), the other by implementing `ValidateValue` (which extends `Validator>`). A class cannot implement an interface with two different type arguments at the same time. – newacct Oct 10 '14 at 08:12

0 Answers0