Search code examples
javainheritancepolymorphismprotected

Restricted access on method call using Java polymorphism


I have some scenario like this:

public class BaseClass {
    protected void protectedMethod(OtherObject object) {
    ...
    }
} 

public class Child1 extends BaseClass {
    @Override
    protected void protectedMethod(OtherObject object) {
        super.protectedMethod(object);
        // Custom Child1 logic
        ...
    }
}

public class Child2 extends BaseClass {
    @Override
    protected void protectedMethod(OtherObject object) {
        super.protectedMethod(object);
        // Custom Child2 logic
        ...
    }
}

Then when i call the "protectedMethod" iterating through an array of "BaseClass" object, compiler gives me protected access error:

OtherObject other = new OtherObject();

BaseClass[] objects = {
    new Child1(),
    new Child2()
}

for (BaseClass object : objects) {
    object.protectedMethod(other); //this line gives me protected access error
}

But if i do the same in a different not polymorphism manner, it works fine.

OtherObject other = new OtherObject();

Child1 child1 = new Child1();
Child2 child2 = new Child2();

child1.protectedAccess(other);
child2.protectedAccess(other);

I don't get to tell what is the difference between the two ways.


Solution

  • In Java, the ''protected'' access qualifier allows access not only by subclasses, but by other classes in the same package.

    If your last code snippet is in the same package as Child1 and Child2, then it would have access to the protected methods in Child1 and Child2.

    EDIT:

    You can fix this problem and keep your polymorphism by introducing your own base class, in your own package.

     public MyBaseClass extends BaseClass { 
        @Override
        protected void protectedMethod(OtherObject object) {
            super.protectedMethod(object);
        }
     }
    
     public Child1 extends MyBaseClass { ... }
     public Child2 extends MyBaseClass { ... }
    

    And then work with a collection of your own base class type.

     NyBaseClass[] objects = {
        new Child1(),
        new Child2()
     }
    
     for (MyBaseClass object : objects) {
        object.protectedMethod(other); 
     }