常见的访问修饰符的使用权限分类:ide
类内部 | 本包 | 子类 | 外部包 | |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default (缺省) | √ | √ | × | × |
private | √ | × | × | × |
其中,对于类的修饰,只能是 public 或者缺省。post
对于方法和成员变动的修饰,public是最宽容的,比较难理解的是projected。spa
显而易见的,对于同一个包里面,和子类里面,能够直接调用protected修饰的方法。可是当子类不在同一个包中时,就须要注意了,能够带着以下几个问题往下看:code
同一个包中, 子类对象能访问父类的 protected 方法吗? (能够)对象
不一样包下, 在子类中建立该子类对象能访问父类的 protected 方法吗?(能够)blog
不一样包下, 在子类中建立父类对象能访问父类的 protected 方法吗?(不能够)ci
不一样包下, 在子类中建立另外一个子类的对象能访问公共父类的 protected 方法吗?(不能够)编译器
父类 protected 方法加上 static 修饰符又会如何呢?编译
package a1;
public class ProTest { protected void say(){ System.out.println("Proteced say"); } public void laugh(){ System.out.println("Protest laugh"); } }
对于不在同一个包的类:是没法访问protected修饰的say()方法的,但能够访问 laugh();table
对于子类若不在同一个包中,只能在本类中访问父类的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 } }