Home > Net >  Inherit variables from abstract superclass
Inherit variables from abstract superclass

Time:01-19

I'm trying to implement a BuilderPattern, where a subclass must extend a superclass.

Superclass:

@Getter
public abstract class CommonValidatorConfig<VC extends CommonValidatorConfig<VC>> {

    private boolean canBeNull;
    private boolean canBeEmpty;
    
    public static abstract class CommonValidatorConfigBuilder<VC, VCB extends CommonValidatorConfigBuilder<VC, VCB>> {
        
        protected boolean canBeNull;
        protected boolean canBeEmpty;
        
        @SuppressWarnings("unchecked")
        public VCB canBeNull(boolean canBeNull) {
            this.canBeNull = canBeNull;
            return (VCB) this;
        }
        
        @SuppressWarnings("unchecked")
        public VCB canBeEmpty(boolean canBeEmpty) {
            this.canBeEmpty = canBeEmpty;
            return (VCB) this;
        }
        
        @SuppressWarnings("unchecked")
        public VCB setDefault() {
            this.canBeNull = false;
            this.canBeEmpty = false;
            return (VCB) this;
        }
        
        public abstract VC build();
        
    }
    
}

Subclass:

@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class StringValidatorConfig extends CommonValidatorConfig<StringValidatorConfig> {
    
    public static class StringValidatorConfigBuilder extends CommonValidatorConfigBuilder<StringValidatorConfig, StringValidatorConfigBuilder> {

        @Override
        public StringValidatorConfig build() {
            return new StringValidatorConfig(false, false); // ERROR
        }
        
    }
    
}

The AllArgsConstructor AccessLevel is set to PRIVATE because I want to create a new instance using only Builders.

I was expecting an AllArgsConstructor for StringValidatorConfig with two variables (canBeNull and canBeEmpty), but the AllArgsConstructor takes no arguments for the constructor.

this means that the variables of the CommonValidatorConfig are not inherited.

Any help, also tutorials/docs/references or improvements of code are welcomed.

CodePudding user response:

StringValidatorConfig extends from CommonValidatorConfig and this class does not have parameterized constructor.

I think you can do something like this:

    @Override
    public StringValidatorConfig build() {
        return new StringValidatorConfig().canBeNull(false).canBeEmpty(false);
    }

// did not try this in ide, just typed here.

CodePudding user response:

I'm not sure if this is the best way, but I solved it by doing:

Superclass:
I added an AllArgsConstructor with AccessLevel PROTECTED.

@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class CommonValidatorConfig<VC extends CommonValidatorConfig<VC>> {

    private boolean canBeNull;
    private boolean canBeEmpty;
    
    public static abstract class CommonValidatorConfigBuilder<VC, VCB extends CommonValidatorConfigBuilder<VC, VCB>> {
        
        protected boolean canBeNull;
        protected boolean canBeEmpty;
        
        @SuppressWarnings("unchecked")
        public VCB canBeNull(boolean canBeNull) {
            this.canBeNull = canBeNull;
            return (VCB) this;
        }
        
        @SuppressWarnings("unchecked")
        public VCB canBeEmpty(boolean canBeEmpty) {
            this.canBeEmpty = canBeEmpty;
            return (VCB) this;
        }
        
        @SuppressWarnings("unchecked")
        public VCB setDefault() {
            this.canBeNull = false;
            this.canBeEmpty = false;
            return (VCB) this;
        }
        
        public abstract VC build();
        
    }
    
}

Subclass:
1 - Removed lombok AllArgsConstructor.
2 - Declared the AllArgsConstructor and passed the variables to superclass constructor.
3 - Access to superclass variables using super keyword.

@Builder
public class StringValidatorConfig extends CommonValidatorConfig<StringValidatorConfig> {
    
    private StringValidatorConfig(boolean canBeNull, boolean canBeEmpty) {
        super(canBeNull, canBeEmpty);
    }
    
    public static class StringValidatorConfigBuilder extends CommonValidatorConfigBuilder<StringValidatorConfig, StringValidatorConfigBuilder> {

        @Override
        public StringValidatorConfig build() {
            return new StringValidatorConfig(super.canBeNull, super.canBeEmpty);
        }
        
    }
    
}
  • Related