Search code examples
javaoopinheritanceoverriding

Method overriding error with base class as an argument


I have the following code:

interface Entity {
    
}
class Student implements Entity{
    
}
class Course implements Entity{
    
}

interface BaseRepository {
    public void save(Entity entiy);
}

class StudentRepository implements BaseRepository {
    @Override
    public void save(Student student) {
        // student validation code
        // save the entity
    }
}
class CourseRepository implements BaseRepository {
    @Override
    public void save(Course course) {
        // course validation code
        // save the entity
    }
}

When I try to compile it, gives me the following error: StudentRepository is not abstract and does not override abstract method save(Entity) in BaseRepository

Doesn't java accept a 'Base' class as an argument? What is the reason? Is there any alternate way to write the code?


Solution

  • An overriding method must:

    • have the exact same name
    • have the exact same argument types; sub types won't work!
    • have a visibility that is the same or broader (so protected -> public is allowed, protected -> private isn't)
    • have a return type that is the same or a sub type

    You're violating the second rule here. Fortunately, you can use generics to fix this:

    interface BaseRepository<E extends Entity> {
        public void save(E entiy);
    }
    
    class StudentRepository implements BaseRepository<Student> {
        @Override
        public void save(Student student) {
            // student validation code
            // save the entity
        }
    }
    class CourseRepository implements BaseRepository<Course> {
        @Override
        public void save(Course course) {
            // course validation code
            // save the entity
        }
    

    }

    Now, the method that a BaseRepository<Student> should override is not public void save(Entity) but public void save(Student). Similarly, the method that a BaseRepository<Course> should override is not public void save(Entity) but public void save(Course).