java基础总结(二十五)--访问修饰符protected

三. protected 关键字的真正内涵

  很多介绍Java语言的书籍(包括《Java编程思想》)都对protected介绍的比较的简单,基本都是一句话,就是:被protected修饰的成员对于本包和其子类可见。这种说法有点太过含糊,常常会对大家造成误解。实际上,protected的可见性在于两点:

  • 基类的protected成员是包内可见的,并且对子类可见;

  • 若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法而不能访问基类实例的protected方法

我们可以通过以下几个关于protected方法可见性的例子来进一步掌握protected关键字。在碰到涉及protected成员的调用时,首先要确定出该protected成员来自何方,然后确定可见性范围,然后就可以判断出当前用法是否可行了。

 

在访问四个访问修饰符中default与protected区别有点混淆,所以从这个角度出发编写该文章

 

用代码理解下“若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法”这句话

   创建一个子类

package pri.lsx.test.xiushifu.protected1;

import pri.lsx.test.xiushifu.protected2.TestObjectOne;

public class son1 extends TestObjectOne {}

  在子类的包中创建一个测试类

package pri.lsx.test.xiushifu.protected1;

public class TestProtectedSon1 {

    public static void main(String[] args) {

        // 在子类的包中调用子类实例的methodOne方法
         new son1().methodOne(); // 编译失败
    }
}


创建子类的基类 

package pri.lsx.test.xiushifu.protected2;

public class TestObjectOne {
    protected void methodOne() {
        System.out.println("TestObjectOne__protected_mehtodOne");
    }
}

在基类的包中创建一个测试类

package pri.lsx.test.xiushifu.protected2;

import pri.lsx.test.xiushifu.protected1.son1;

public class TestProtected {

    public static void main(String[] args) {
        new son1().methodOne();     // 该代码正常执行
    }
}

结果:在基类的包中调用子类实例methodOne方法则成功。说明若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法。

而在子类的包中调用子类实例的methodOne方法则失败。说明“若子类与基类不在同一包中,那么在子类中,不能访问基类实例的protected方法

 

用这个思路去分析:“先要确定出该protected成员来自何方,然后确定可见性范围,然后就可以判断出当前用法是否可行了

在子类中的methodOne方法来自基类,所以该methodOne方法可见的包是pri.lsx.test.xiushifu.protected2,类范围是子类son1,所以在子类所在的包中去掉用就会报错。

 

再说一下与default的区别。

根据菜鸟教程对java访问修饰符总结,defalut与protected一种情况才表现的不同即“子类与基类在不同的包中会表现的不一样”

现在具体来说一下,上面的代码若是把基类方法访问修饰改成了defalut,则无论是基类所在的包,还是父类所在的包,调用子类实例方法都会报错。因为此时的子类son1与基类不在他同一个包下面,无法继承到基类的methodOne方法,所以任何一个子类的实例都没有methodOne这个方法,会报错。

修改父类修饰符如下

package pri.lsx.test.xiushifu.protected2;

public class TestObjectOne {
     void methodOne() {
        System.out.println("TestObjectOne__protected_mehtodOne");
    }
}

父类所在的包调用此时会报错了

package pri.lsx.test.xiushifu.protected2;

import pri.lsx.test.xiushifu.protected1.son1;

public class TestProtected {

    public static void main(String[] args) {
        new son1().methodOne();     // 编译报错
    }
}

参考资料:

http://www.runoob.com/java/java-modifier-types.html#protected-desc

http://www.runoob.com/w3cnote/java-protected-keyword-detailed-explanation.html

https://blog.csdn.net/justloveyou_/article/details/61672133

猜你喜欢

转载自blog.csdn.net/lsx2017/article/details/81840046
今日推荐