protected 访问权限。
一:与父类处于不同包的子类只能通过super.method的方式来访问父类的protected实例方法,不能通过父类的实例来访问父类的protected实例方法。 与父类处于不同包的子类也能直接访问从父类继承而来的该protected实例方法,但与该子类同一个包的其他类不能访问该protected实例方法。
二:对于父类的protected静态方法/静态成员变量,不同包的子类可以通过【父类.protected静态方法/静态成员变量】的方式调用,也可以直接调用。但与该子类同一个包的其他类不能访问该protected静态方法/静态成员变量。
三:子类可以向上转型为父类,因此在父类中,父类的私有方法可以被访问。
四:不同包的子类可通过super.field方式来访问父类的protected实例成员变量,也可以通过该子类的实例来访问父类的protected实例成员变量,但不能通过父类的instance.field来访问。与该子类同一个包的其他类不能访问该protected实例方法。
◆ 访问权限要看该方法或字段定义的位置。
父类:
package package1;
import package1.package2.AccessPermissionTest01;
public class AccessPermissionTest {
public static void main(String[] args){
AccessPermissionTest a1 = new AccessPermissionTest();
a1.print();
//AccessPermissionTest a2 = new AccessPermissionTest01();
//a2.print();
//以下语句与上面被注释掉的语句作用相同
a1 = new AccessPermissionTest01();
//因为是在当前类本身,父类的protected方法可以被访问。但运行时方法为子类的方法(多态)。
a1.print();
//子类可以向上转型为父类,因此父类的私有方法可以被访问。
a1.print02();
//因为是静态方法,即使子类重写了该方法也不会调用子类重写的方法。静态方法没有多态
a1.print01();
}
protected void print(){
System.out.println("BASE_INSTANCE_PRINT!");
}
protected static void print01(){
System.out.println("BASE_STATIC_PRINT!");
}
private void print02(){
System.out.println("BASE_INSTANCE_PRINT02!");
}
protected void print03(){
System.out.println("BASE_INSTANCE_PRINT03!");
}
}
子类:
package package1.package2;
import package1.AccessPermissionTest;
public class AccessPermissionTest01 extends AccessPermissionTest {
public static void main(String[] args){
AccessPermissionTest a = new AccessPermissionTest();
//此处将报错,不能通过instance.method的方式来访问父类的protected方法。
// The method print() from the type AccessPermissionTest is not visible
//a.print();
AccessPermissionTest a2 = new AccessPermissionTest01();
//此处将报错,The method print() from the type AccessPermissionTest is not visible
//a2.print();
((AccessPermissionTest01)a2).print();//强制类型转换才可以
//对于父类的protected静态方法,子类通过[父类.protected静态方法]可以调用
AccessPermissionTest.print01();
//通过实例变量访问静态方法,本质还是通过声明该实例变量的类型来调用静态方法
//因为a2声明为AccessPermissionTest类型,所以下面这句和上面一句的调用是一样的
a2.print01();
//下面是将a2强制类型转换为AccessPermissionTest01,
// 所以,其实是通过AccessPermissionTest01来调用静态方法
((AccessPermissionTest01)a2).print01();
//下面这句和上面一句调用一样
AccessPermissionTest01.print01();
}
@Override
protected void print(){
AccessPermissionTest ac = new AccessPermissionTest01();
//ac.print();//此处也将报错,不能通过instance.method的方式来访问父类的protected方法。
super.print();//此处OK,可通过super.method方式来访问父类的protected方法。
System.out.println("SUB_INSTANCE_PRINT!");
}
//@Override 不能使用
public static void print01(){
System.out.println("SUB_STATIC_PRINT!");
}
public void print02(){
System.out.println("SUB_INSTANCE_PRINT02!");
}
}
五:Protected 修饰的构造函数可以在不同包中的子类的构造函数中通过super关键字调用,但在普通方法中不能通过new constructor的形式调用。
package package1;
import package1.package2.Sub;
public class Base {
protected int f = -1;
public Base(int a){
this.f = a;
}
//Protected 修饰的构造函数
protected Base(int a,int b){}
void method01(){
Sub s = new Sub();
}
}
-----------------------------------------------
package package1.package2;
import package1.Base;
public class Sub extends Base{
public Sub(){
super(2,3);//可以通过super关键字调用
}
void method01(){
//下面的语句会报错:The constructor Base(int, int) is not visible
//Base b = new Base(2,3);
{
int a = 3;
}
int a;
}
}
六:虽然子类的方法由于访问权限(protected权限)的原因,不能直接访问。但通过多态(polymorphism)可以调用。
七:静态方法只能被隐藏,不能被重写。"重写"只能适用于实例方法.不能用于静态方法.对于静态方法,只能隐藏(形式上被重写了,但是不符合的多态的特性),“重写”是用来实现多态性的,只有实例方法是可以实现多态,而静态方法无法实现多态。在Java中静态方法的选择是编译期就选择好的,是编译器自动根据声明类型帮我们选择的,它不依赖与任何对象。
从语义就可以看出static、final、private方法本身都是编译期绑定的(也叫前期绑定)这些方法不存在多态,他们是在还没有运行的时候,程序在编译器里面就知道该调用哪个类的哪个方法了,而其他可观察的普通方法的绑定是在运行的时候根据具体的对象决定的,因为从语义上看这些方法是可被继承的,有了多态而造成了不确定性。。。
八:defau修饰的类其他包中的类是不能访问的,即使其构造函数为public访问权限。