Java访问控制权限protected和default

Java基础之访问控制权限protected和default

包和类、接口的访问权限控制比较简单,在此不讨论。仅记录一下protected和default修饰的成员变量和成员方法的访问权限控制问题。

假设定义了一个顶层类:

 package com.zjc;
public class FatherClass{
    //保护类变量
    protected int protected_int;
    //保护类方法
    protected void display_protected(){
        System.out.println("这是保护类的方法");
    }
    //默认类变量
    int default_int;
    //默认类方法
    void display(){
        System.out.println("这是默认友好类的方法");
    }
    public int getProtected_int() {
        return protected_int;
    }
    public void setProtected_int(int protected_int) {
        this.protected_int = protected_int;
    }
    public int getDefault_int() {
        return default_int;
    }
    public void setDefault_int(int default_int) {
        this.default_int = default_int;
    }
}

主要分两种情况:

一、引用FatherClass的类与之在同一包下

1、FatherClass类的子类及其子类将继承protected、default型变量和方法;

2、FatherClass类、子类及其子类创建的实例可以直接访问protected、default型变量和方法。

//子类SonClass

package com.zjc;
public class SonClass extends FatherClass{
    public void sy(){
        //1、在同一个包中,子类体内部,保护和默认成员均可见。
      this.default_int = 1;
      this.protected_int = 2;
      this.display();
      this.display_protected();
    }
}

package com.zjc;

public class TestDefaultProtected {
    public static void main(String[] args) {
        // 创建实例对象
        FatherClass ft = new FatherClass();
        SonClass st = new SonClass();
        //2、在同一个包中,顶层类、子类创建的实例对象中保护型和默认型变量和方法均可见
        ft.default_int = 1;
        ft.protected_int = 2;
        ft.display();
        ft.display_protected();
        st.default_int = 1;
        st.protected_int = 2;
        st.display();
        st.display_protected();
    }

}

二、引用FatherClass的类与之不在同一包下   

1、子类及其子类将继承protected成员,不继承default成员;

2、FatherClass类、子类及其子类创建的实例均不能直接访问protected、default型变量和方法(子类体内创建实例除外);

3、可以通过Father类的public方法操纵protected/private/default变量。

//子类SonClassOnDiffPackage

package com.caimeng;

import com.zjc.FatherClass;
import com.zjc.SonClass;

class SonClassOnDiffPackage extends FatherClass{
    public void test(){
    //3、不同包下,FatherClass类的子类内,继承了保护型变量和方法、不继承默认型变量和方法
     this.protected_int = 2;
     this.display_protected();
     SonClassOnDiffPackage temp = new SonClassOnDiffPackage();

     temp.protected_int =3;    //5、子类体内创建的自身对象可以直接访问保护型变量
    }
}

//测试实例对象

public class UseDefaultProtected  {
    public static void main(String[] args) {
        FatherClass ft = new FatherClass();
        SonClassOnDiffPackage sd = new SonClassOnDiffPackage();
        SonClass sc = new SonClass();
        //4、在不同包中,FatherClass类、SonClassOnDiffPackage类、SonClass类
        //的实例对象中,保护型和默认型变量和方法均不能直接访问
        //6、可以通过Father类的public方法操纵protected/private/default变量
        ft.protected_int = 1; //编译错误
        sd.protected_int = 1; //编译错误
        sc.protected_int = 1; //编译错误
    }

}

结论:

1、在同一包中,protected和default修饰效果相同;即在子类均继承这些成员,顶层类、子类创建的实例

      均可以直接访问这些成员;

2、而在不同包下,子类只继承了protected成员,可以在子类体内直接访问这些成员,但顶层类、子类创建的实例均不能直接访问这些成员;

3、对于不同包下protected的访问权限,记住Java7规范中的一个原则即可

A protected member or constructor of an object may be accessed from outside
the package in which it is declared only by code that is responsible for the
implementation of that object.

也就是,只能在类的实现体内访问,类创建的实例内是不可达的。

猜你喜欢

转载自passion99.iteye.com/blog/2335593