java 中 private public protected default 访问权限的区别

看到网上有很多关于java访问权限的文章,发现要么是错的,要么就是讲的不清不楚,我特地去国外论坛看了下,现将清晰且正确的说法展示给大家,希望各位友人少走弯路。
不同元素的访问权限
class \ have access toprivate
elements
default
elements
(no modifier)
protected
elements
public
elements
own class (Base)yesyesyesyes
subclass - same package (SubA)noyesyesyes
class - same package (AnotherA)noyesyesyes
subclass - another package (SubB)nonoyes/no *yes
class - another package (AnotherB)nonono

yes

*与基类不在同一个包中的子类,只能访问自身从基类继承而来的受保护成员,而不能访问基类实例本身的受保护成员。

举个例子说明:

package package1;

public Class Base{

           protected int i=5;}


package package2;

public Class SubB extends Base{

           public static void main(String arg[]){

                       SubB subb = new SubB();

                       subb.i=6;

                       System.out.println(sub.i);// 正确     与基类不在同一个包中的子类,可以访问自身从基类继承而来的受保护成员

                       Base base=new Base();

                       base.i=6;

                       System.out.println(base.i);//错误     与基类不在同一个包中的子类,不能访问基类实例本身的受保护成员

}

}

其实default(friendly)与protected的区别就在于,与基类不在同一个包中的子类可以继承基类的protected元素,却无法继承default元素。看到很多人说

 
public
protected
default
private
同类
T
T
T
T
同包
T
T
T
 
子类(不同包)
T
T
 
 
不同包中无继承关系的类
T
 
 
 
其实这种说法是错误的,读过thinging in java的人都知道,里面有一句,“若新建一个包,并从另一个包中的某个类
中继承,这唯一能够访问的成员就是原来那个包中的public成员”,可见不同包中的子类是不能访问基类的protected成员的,只能继承。这是最容易混淆的地方。

其他如private和public我想大家应该清楚,我就不复述了。

参考资料(英文):http://bmanolov.free.fr/javaprotection.php#subb


Code Example

All lines with not accessible fields are commented.

package packageA;

public class Base {
    public String publicStr = "publicString";
    protected String protectedStr = "protectedString";
    String defaultStr = "defaultString";
    private String privateStr = "privateString";

    public void print() {
        System.out.println("packageA.Base has access to");
        System.out.println("    " + publicStr);
        System.out.println("    " + protectedStr);
        System.out.println("    " + defaultStr);
        System.out.println("    " + privateStr);

        Base b = new Base(); // -- other Base instance
        System.out.println("    b." + b.publicStr);
        System.out.println("    b." + b.protectedStr);
        System.out.println("    b." + b.defaultStr);
        System.out.println("    b." + b.privateStr);
    }
}

--------------------------------------------------------------------------------

package packageA;

public class SubA extends Base {
    public void print() {
        System.out.println("packageA.SubA has access to");
        System.out.println("    " + publicStr + " (inherited from Base)");
        System.out.println("    " + protectedStr + " (inherited from Base)");
        System.out.println("    " + defaultStr + " (inherited from Base)");
        // -- not accessible - private elements are even not inherited
        // System.out.println(privateStr);

        Base b = new Base(); // -- other Base instance
        System.out.println("    b." + b.publicStr);
        System.out.println("    b." + b.protectedStr);
        System.out.println("    b." + b.defaultStr);
        // -- not accessible
        // System.out.println(b.privateStr);
    }
}

--------------------------------------------------------------------------------

package packageA;

public class AnotherA {
    public void print() {
        System.out.println("packageA.AnotherA has access to");
        Base b = new Base();
        System.out.println("    b." + b.publicStr);
        System.out.println("    b." + b.protectedStr);
        System.out.println("    b." + b.defaultStr);
        // System.out.println(b.privateStr);
    }
}

--------------------------------------------------------------------------------

package packageB;
import packageA.Base;

public class SubB extends Base {
    public void print() {
        System.out.println("packageB.SubB has access to");
        System.out.println("    " + publicStr + " (inherited from Base)");
        // -- protectedStr is inherited element -> accessible
        System.out.println("    " + protectedStr + " (inherited from Base)");
        // -- not accessible
        // System.out.println(defaultStr);
        // System.out.println(privateStr);

        Base b = new Base(); // -- other Base instance
        System.out.println("    b." + b.publicStr);
        // -- protected element, which belongs to other object -> not accessible
        // System.out.println(b.protectedStr);

        // -- not accessible
        // System.out.println(b.defaultStr);
        // System.out.println(b.privateStr);
    }
}

--------------------------------------------------------------------------------

package packageB;
import packageA.Base;

public class AnotherB {
    public void print() {
        System.out.println("packageB.AnotherB has access to");
        Base b = new Base();
        System.out.println("    b." + b.publicStr);
        // -- not accessible
        // System.out.println(b.protectedStr);
        // System.out.println(b.defaultStr);
        // System.out.println(b.privateStr);
    }
}

--------------------------------------------------------------------------------

import packageA.*;
import packageB.*;

// -- testing class
public class TestProtection {
    public static void main(String[] args) {
        // -- all classes are public, so class TestProtection
        // -- has access to all of them
        new Base().print();
        new SubA().print();
        new AnotherA().print();
        new SubB().print();
        new AnotherB().print();
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值