Search code examples
javaoopinheritancepolymorphismmutators

Overriding mutator methods for sake of validation


I am currently working on an Object Oriented Design project, and would like to know if there is a better way to validate data in mutators of subclasses.

For example, I have a Home class with the subclasses Apartment, Condo, and House. In the Home class, I would like to include the mutators for (private) fields that the subclasses share. Say one of the fields is squareFootage. Is there a way to make the mutator in Home generic enough so that the subclasses can then set their own valid values for squareFootage without having to override the mutator completely? That is, I want different valid ranges for squareFootage for each subclass.

I've tried setting possible range values in Home, then override them in the subclasses. Unfortunately, the mutator in Home still grabs from the Home class and not the subclass.

So, I've resorted to abstracting the mutators, but unfortunately this results in a lot of repeated code, since I can literally copy and paste the mutators in each subclass.

I want to make the possible range values static if possible, and I understand this may be possible with reflection, but I'd really like to avoid using it for this project.


Solution

  • I think is possible by adding an abstract "validator" method that have to be implemented in the subclasses, something like this:

    public class Home {
    
        private float squareFootage;
    
        public abstract void validateSquareFootage() throws MyValidationException; // you could throw an exception, runtime exception or return a boolean to indicate if value is valid or not
    
        public void setSquareFootage(float squareFootage) {
            validateSquareFootage(squareFootage); // again, throws exception or returns boolean, up to you
            this.squareFootage = squareFootage;
        }
    
        // ... rest of implementation
    }
    

    And in a subclase:

    public class Condo extends Home {
    
        @Override
        public void validateSquareFootage(float squareFootage) throws MyValidationException {
            // ... do validations
        }
    
    }
    

    and you don't have to override the mutator at all, just implement the correct validator.