1

Error: m1() has protected access in A

When I try to using superclass reference variable (A obj=new B())

This is a first class in package pkg1;

package pkg1;
public class A {
    protected void m1() {
        System.out.println("protected method");
    }
}

This is a second class which is in another package pkg2 importing pkg1;

package pkg2;

import pkg1.A;
public class B extends A {
    @Override
    protected void m1() {
        System.out.println("override m1");
    }

    public static void main(String ar[]) {
        A obj=new B();
        obj.m1();
    }
}
  • 1
    You're trying to access `obj.m1()` and `obj` is of type `A`. So... – Denys Séguret Jan 13 '16 at 15:11
  • Indeed. Please explain why you *expect* that to work. (And in future, please pay more attention to code formatting. I've fixed it up now, but it was a mess before.) – Jon Skeet Jan 13 '16 at 15:15
  • @denys Seguret , @ jon Skeet if i'm not worng java gives the mechanism of dynamic method dispatch ,so i think i can access the m1() method which is overriden from A by using of reference varible of type A. – Pushpam Kumar Jan 13 '16 at 15:26

3 Answers3

1

I feel like you're still slightly confused with why protected m1() isn't visible.

You understand that main is a method in B and B is a subclass of A, therefore you feel like it should be accessible.

The key is obj is cast to be interpreted of type A. Then you try to call instance method m1 from static context in B (see this link above for why this is important). By class A definition, m1 is accessible through:

  1. Class definition itself on a given instance of itself.
//example 
package pkg1;

public class C {
    protected void m1() {
        System.out.println("protected method");
    }

   public static void callM1(C anInstanceOfC){
        anInstanceOfC.m1();
   }
}
package pkg2;

import pkg1.C;
public class D extends C {
    @Override
    public void m1() {
        System.out.println("override m1");
    }

    public static void main(String ar[]) {
        C obj=new D();
        C.callM1(obj);//output would be "override m1"
    }
}
  1. Instance methods (of course) of the class within itself and of subclasses.
//example 
package pkg1;

public class C {
    protected void m1() {
        System.out.println("protected method");
    }

    public void m2() {
        m1();//call to instance method m1
    }

   public static void callM1(C anInstanceOfC){
        anInstanceOfC.m2();
   }
}
package pkg2;

import pkg1.C;
public class D extends C {
    @Override
    public void m1() {
        System.out.println("override m1");
    }

    public void m3() {
        //super.m2()
        m2();//call to superclass method
    }

    public static void main(String ar[]) {
        D obj=new D();
        D.m3(); // output "override m1"
    }
}
Community
  • 1
  • 1
SGM1
  • 968
  • 2
  • 12
  • 23
0

protected keyword means that you can access protected-defined data from child classes. In example, you try to access protected data from non-child static context. You should probably try this:

package pkg2;

import pkg1.A;
public class B extends A {
    @Override
    public void m1() {
        System.out.println("override m1");
    }

    public static void main(String ar[]) {
        B obj=new B();
        obj.m1();
    }
}
SeniorJD
  • 6,946
  • 4
  • 36
  • 53
  • @ SeniorJD when i extends A in class B that means B is the child of class A. – Pushpam Kumar Jan 13 '16 at 15:35
  • But `main` method is not a part of B object actually. – SeniorJD Jan 13 '16 at 15:37
  • how main method is not a part of B object ? – Pushpam Kumar Jan 13 '16 at 15:44
  • You're confused with classes and objects concepts. `main` is a part of B class, but not a part of B object. – SeniorJD Jan 13 '16 at 15:47
  • @SeniorJD I've never really thought about static methods like that, but you're right. [Difference between Static methods and Instance methods](http://stackoverflow.com/questions/11993077/difference-between-static-methods-and-instance-methods) – SGM1 Jan 13 '16 at 15:51
  • sorry i'm new but i think i can access the child class member which are overriden from parent class by using parent type reference variable. – Pushpam Kumar Jan 13 '16 at 15:52
  • @Pushpam Kumar You can just not with the access modifier you are currently using for the `m1()` method. See other answers to your question to see how. – George Mulligan Jan 13 '16 at 15:56
  • @PushpamKumar You did effectively override the `m1` function, just not the modifier in class `A`. If pass you pass the `obj` back into a method in `A`, example. New method in `A`: `public void callM1(A a){m1();}`. Then in main: `obj.callM1(obj);`. The output: "override m1". You just do not have access to it from outside the `A` class context. – SGM1 Jan 13 '16 at 15:59
  • @SGM1 Sir What does this mean " just not the modifier in class A" How can we override the modifier?? – Pushpam Kumar Jan 13 '16 at 18:08
  • @PushpamKumar Modifiers mean "private", "protected", "public", and "default". You're not meant to change these properties as per the language construct. But, you can still manipulate them at a per instance level using reflection in Java. – SGM1 Jan 13 '16 at 18:58
  • @SGM1 but sir protected is allowed "different package subclass". – Pushpam Kumar Jan 13 '16 at 19:07
  • @PushpamKumar I was just stating, if you used [reflection](http://stackoverflow.com/questions/16288393/java-reflection-private-method-with-parameters-best-approach) to force the call to `m1` you would still get "override m1". – SGM1 Jan 13 '16 at 19:45
0

The access level of m1() is protected. Protected methods can only be accessed by subclasses or by other classes in the same package. From your static 'main' method, you can not call a protected instance method of a class in a different package. If class B was in the same package as class A, then you will have no error and your code would work fine.

sarumait
  • 66
  • 4