博客
关于我
4.10 访问权限
阅读量:323 次
发布时间:2019-03-04

本文共 5116 字,大约阅读时间需要 17 分钟。

  • 修饰变量和方法
  • public类和友好类

 

一:修饰变量和方法

注意:protected中的子孙类(不同包)可以是Y也可以是N(下面解释一下)

创建一个基类TestObject(注意包是cn.aa)

package cn.aa;//基类public class TestObject {    protected void f() {        System.out.println("基类的受保护方法f");    }}

创建一个子类Son(注意包是cn.test)

package cn.test;import cn.aa.TestObject;//子类Son,子类和基类TestObject不在同一包中public class Son extends TestObject {}

创建一个测试类Testone(注意包是cn.aa)

package cn.aa;import cn.test.Son;public class Testone {    public static void main(String[] args) {        new Son().f();     // 该代码正常执行,代码相当于下面两句//        Son a=new Son();//        a.f();    }}

成功运行,输出:基类的受保护方法f

创建另外一个测试类(包是cn.test)

package cn.test;public class Testtwo {    public static void main(String[] args) {        // 在子类的包中调用子类实例的f方法        new Son().f(); // 编译失败    }}

运行失败

结论:基类TestObject 的方法f的可见性是包cn.aa及其子类,所以testone可以testtwo不行

 

重要概念:protected的可见性在于两点:

  • 基类的protected成员是包内可见的,并且对子类可见;
  • 若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。

 

第一条我是能理解的,上面那个就是一个简单的例子,但是第二条我有点乱,特别是而不能访问基类实例的protected方法这句搞不懂。

在涉及下面的实例前百度了一些概念:

(1)基类就是父类,派生类就是子类

(2)Clone()在Object类里面是protected权限

(3)所有的类都是Object的子类,java.lang.Object为默认父类

在碰到涉及protected成员的调用时,首先要确定出该protected成员来自何方,其可见性范围是什么,然后就可以判断出当前用法是否可行了。

实例一:

package p1;public class Father1 {        protected void f() {}    // 父类Father1中的protected方法} package p1;public class Son1 extends Father1 {} package p11;public class Son11 extends Father1{} package p1;public class Test1 {            public static void main(String[] args) {                Son1 son1 = new Son1();                son1.f(); // Compile OK            ----(1)                son1.clone(); // Compile Error     ----(2)                 Son11 son = new Son11();                    son11.f(); // Compile OK           ----(3)                son11.clone(); // Compile Error    ----(4)        }}

f()方法从类Father1继承而来,其可见性是包p1及其子类Son1和Son11(其实Father1类也是可以调用方法f()的)

首先看(1)(3),而由于调用f()方法的类Test1所在的包也是p1,因此(1)(3)处编译通过。

其次看(2)(4),其中的clone()方法的可见性是java.lang包及其所有子类,对于语句"son1.clone();"和"son11.clone();",二者的clone()在类Son1、Son11中是可见的,在Son1或者Son11类里面创建实例都是可以访问clone()的,但在Test1类中创建Son1或者Son11就不能,因此(2)(4)处编译不通过,当然了,如果是在Test1中创建该类的实例也是能访问clone()方法。

 

 

实例二:

package p2;class MyObject2 {    protected Object clone() throws CloneNotSupportedException{       //super可以调用父类的方法       return super.clone();    }}package p22;public class Test2 extends MyObject2 {    public static void main(String args[]) {       MyObject2 obj = new MyObject2();       obj.clone(); // Compile Error         ----(1)       Test2 tobj = new Test2();       tobj.clone(); // Complie OK           ----(2)    }}

对于(1)而言,clone()方法来自于类MyObject2本身,因此其可见性为包p2及MyObject2的子类,虽然Test2是MyObject2的子类,但在Test2中不能访问基类MyObject2的protected方法clone(),因此编译不通过;

对于(2)而言,由于在Test2中访问的是其本身实例的从基类MyObject2继承来的的clone(),因此编译通过。

 

 

注意实例三和实例四的区别

实例三:

package p3;class MyObject3 extends Test3 {}package p33;public class Test3 {  public static void main(String args[]) {    MyObject3 obj = new MyObject3();    obj.clone();   // Compile OK        ------(1)  }}

对于(1)而言,clone()方法来自于类Test3,因此其可见性为包p33及其子类MyObject3,而(1)正是在p33的类Test3中调用,属于同一包,编译通过。

 

实例四:

package p4;class MyObject4 extends Test4 {  protected Object clone() throws CloneNotSupportedException {    return super.clone();  }}package p44;public class Test4 {  public static void main(String args[]) {    MyObject4 obj = new MyObject4();    obj.clone(); // Compile Error      -----(1)  }}

对于(1)而言,clone()方法来自于类MyObject4,因此其可见性为包p4及其子类(此处没有子类),而类Test4却在包p44中,因此不满足可见性,编译不通过。

 

 

实例五:

package p5;class MyObject5 {    protected Object clone() throws CloneNotSupportedException{       return super.clone();    }}public class Test5 {    public static void main(String[] args) throws CloneNotSupportedException {       MyObject5 obj = new MyObject5();       obj.clone(); // Compile OK        ----(1)    }}

 对于(1)而言,clone()方法来自于类MyObject5,因此其可见性为包p5及其子类(此处没有子类),而类Test5也在包p5中,因此满足可见性,编译通过。

 

 

实例六:

package p6;class MyObject6 extends Test6{}public class Test6 {  public static void main(String[] args) {    MyObject6 obj = new MyObject6();    obj.clone();        // Compile OK   -------(1)  }}

对于(1)而言,clone()方法来自于类Test6,因此其可见性为包p6及其子类MyObject6,而类Test6也在包p6中,因此满足可见性,编译通过。

 

 

 

实例七:

package p7;class MyObject7 extends Test7 {    public static void main(String[] args) {        Test7 test = new Test7();        test.clone(); // Compile Error   ----- (1)  }}public class Test7 {}

对于(1)而言,clone()方法来自于类Object,因此该clone()方法可见性为包java.lang及其子类Test7,由于类MyObject7不在此范围内,因此不满足可见性,编译不通过。

 

 

子类能访问 protected 修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。

下面的父类使用了 protected 访问修饰符,子类重写了父类的 openSpeaker() 方法。

class AudioPlayer {   protected boolean openSpeaker(Speaker sp) {      // 实现细节   }} class StreamingAudioPlayer extends AudioPlayer {   protected boolean openSpeaker(Speaker sp) {      // 实现细节   }}

如果把 openSpeaker() 方法声明为 private,那么除了 AudioPlayer 之外的类将不能访问该方法。

如果把 openSpeaker() 声明为 public,那么所有的类都能够访问该方法。

如果我们只想让该方法对其所在类的子类可见,则将该方法声明为 protected。

 

 

private修饰的变量:私有类变量(静态成员变量)。如果是public的类变量(static),那么可以通过类名去操作该类变量,同理,类方法也一样。访问限制修饰符按访问权限从高到低的排列顺序是public,protected,default,private。类和接口不能声明为 private。protected不能修饰类(内部类除外)

 

二:public类和友好类

class B {}

 在另外一个类中使用友好类创建对象时,要保证他们在同一个包中。

 

public class B {}

 

转载地址:http://mjsh.baihongyu.com/

你可能感兴趣的文章
JAVA高并发集合详解
查看>>
解决Spirng注入时名称下的红色波浪线
查看>>
操作系统知识概述
查看>>
读懂操作系统(x64)之堆栈帧(过程调用)
查看>>
仓储模式到底是不是反模式?
查看>>
VS2015安装EF Power Tools
查看>>
Web APi之捕获请求原始内容的实现方法以及接受POST请求多个参数多种解决方案(十四)
查看>>
ASP.NET MVC之JsonResult(六)
查看>>
SQL Server之深入理解STUFF
查看>>
EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public?
查看>>
使用mybatis-generator生成底层
查看>>
Android APK 重签名
查看>>
Mybatis【3】-- Mybatis使用工具类读取配置文件以及从属性读取DB信息
查看>>
Mybatis【5】-- Mybatis多种增删改查那些你会了么?
查看>>
Mybatis【7】-- Mybatis如何知道增删改是否成功执行?
查看>>
Mybatis【9】-- Mybatis占位符#{}和拼接符${}有什么区别?
查看>>
计算输入的一句英文语句中单词数
查看>>
zabbix系列之十——添加短信告警
查看>>
docker复制文件到宿主机
查看>>
lvs+keepalive构建高可用集群
查看>>