访问修饰符--protected
常见的访问修饰符的使用权限分类:
类内部 | 本包 | 子类 | 外部包 | |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default (缺省) | √ | √ | × | × |
private | √ | × | × | × |
其中,对于类的修饰,只能是 public 或者缺省。
对于方法和成员变更的修饰,public是最宽容的,比较难理解的是projected。
显而易见的,对于同一个包里面,和子类里面,可以直接调用protected修饰的方法。但是当子类不在同一个包中时,就需要注意了,可以带着如下几个问题往下看:
-
同一个包中, 子类对象能访问父类的 protected 方法吗? (可以)
-
不同包下, 在子类中创建该子类对象能访问父类的 protected 方法吗?(可以)
-
不同包下, 在子类中创建父类对象能访问父类的 protected 方法吗?(不可以)
-
不同包下, 在子类中创建另一个子类的对象能访问公共父类的 protected 方法吗?(不可以)
-
父类 protected 方法加上 static 修饰符又会如何呢?
可以参考链接:https://juejin.im/post/5a1fdfad5188253e2470c20d
package a1;
public class ProTest { protected void say(){ System.out.println("Proteced say"); } public void laugh(){ System.out.println("Protest laugh"); } }
对于不在同一个包的类:是无法访问protected修饰的say()方法的,但可以访问 laugh();
对于子类若不在同一个包中,只能在本类中访问父类的protected方法
不同包下,在子类中通过父类引用不可以访问其 protected 方法
package a2; import a1.ProTest; public class Tester { public static void main(String arg[]){ ProTest p = new ProTest(); p.laugh();//ok p.say();//编译器提示无法访问 } }
package a2; public class Effect extends ProTest { public static void main(String args[]){ ProTest p = new ProTest();
Effect e = new Effect() e.say();// ok
p.say();//编译不通过,无论是创建 ProTest 对象还是通过多态创建 Effect 对象, 只要 ProTest 引用, 则不可访问, 编译器会提示错误。
}
}
这时,对于同在a2包中的其它类,对于子类和父类的say()方法均不能调用,
静态方法直接通过类名访问
无论是否同一个包,在子类中均可直接访问
package a2; import a1.ProTest; public class Tester { public static void main(String arg[]){ ProTest p = new ProTest(); Effect effect = new Effect(); p.say(); //编译不通过 ,但是父类中如果是静态的方法,那么可以访问 effect.say(); // 编译不通过 } }
如果子类覆盖了say()方法,则可以在a2包中使用子类的say()方法:
package a2; import a1.ProTest; public class Effect extends ProTest { @Override public void say(){ System.out.println("effect say"); } }
package a2; import a1.ProTest; public class Tester { public static void main(String arg[]){ Effect effect = new Effect(); ProTest p = new Effect(); effect.say(); // 输出 effect say p.say(); //编译错误 ,如果把父类放到同一个a2包下,则这里可以调用,但是输出的是effect say } }