关于权限修饰符protected

权限修饰符

我们先回顾一下java中的权限修饰符

权限修饰符 同类 同包 子类 其他包
public
protected ×
default × ×
private × × ×

对于public和private大家都很了解了,但是对于protected,大家可能对它的概念可能就一句话:被protected修饰的成员对于本包和其子类可见。

该权限修饰符的关键是

  • 基类的protected成员属性是包内可见的,并且对所有子类可见
  • 若子类与基类不在同一包下,则在子类中,子类实例可以访问从基类继承来的protected方法,而不能访问基类实例的protected方法

遇到protected

首先思考这个protected来自何方

接着看其和这个地方是不是同包

最后看其是否有父子类关系

可以通过以下几个Test来掌握protected的用法

注意:观察包限定名

模型

1
2
3
4
5
6
7
8
9
10
package com.lizhi.protect.p1;

public class Feather1 {
protected void f(){}

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
1
2
3
4
package com.lizhi.protect.p1;

public class Son1 extends Feather1{
}
1
2
3
4
5
6
package com.lizhi.protect.p11;

import com.lizhi.protect.p1.Feather1;

public class Son11 extends Feather1 {
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.lizhi.protect.p1;

import com.lizhi.protect.p11.Son11;

public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Feather1 feather1 = new Feather1();
Son1 son1 = new Son1();
Son11 son2 = new Son11();
son1.f();//编译通过,因为该测试类与Feather1处于同一包下
son1.clone();//编译通过,因为该测试类与Feather1处于同一包下
son2.f();//编译通过,因为该测试类与Feather1处于同一包下
son2.clone();//编译通过,因为该测试类与Feather1处于同一包下
feather1.f();//编译通过,因为该测试类与Feather1处于同一包下
feather1.clone();//编译通过,因为该测试类与Feather1处于同一包下
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.lizhi.protect.p11;

import com.lizhi.protect.p1.Feather1;
import com.lizhi.protect.p1.Son1;
import com.lizhi.protect.p11.Son11;

public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Feather1 feather1 = new Feather1();
Son1 son1 = new Son1();
Son11 son2 = new Son11();
son1.f();//编译不通过,因为该测试类与Feather1处于不同一包下,该类也不是Feather1的子类
son1.clone();//编译不通过,因为该测试类与Feather1处于不同一包下,该类也不是Feather1的子类
son2.f();//编译不通过,因为该测试类与Feather1处于不同一包下,该类也不是Feather1的子类
son2.clone();//编译不通过,因为该测试类与Feather1处于不同一包下,该类也不是Feather1的子类
feather1.f();//编译不通过,因为该测试类与Feather1处于不同一包下,该类也不是Feather1的子类
feather1.clone();//编译不通过,因为该测试类与Feather1处于不同一包下,该类也不是Feather1的子类
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.lizhi.protect.p11;

import com.lizhi.protect.p1.Feather1;
import com.lizhi.protect.p1.Son1;

public class Son11 extends Feather1 {
public static void main(String[] args) throws CloneNotSupportedException {
Feather1 feather1 = new Feather1();
Son1 son1 = new Son1();
Son11 son2 = new Son11();
son2.f();//编译通过,因为该测试类所在的地方是Feather1的子类
son2.clone();//编译通过,因为该测试类所在的地方是Feather1的子类
feather1.f();//编译不通过,因为该测试类与Feather1处于不同一包下
feather1.clone();//编译不通过,因为该测试类与Feather1处于不同一包下
son1.f();//编译不通过,因为该测试类与Feather1处于不同一包下
son1.clone();//编译不通过,因为该测试类与Feather1处于不同一包下
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.lizhi.protect.p1;

import com.lizhi.protect.p11.Son11;

public class Feather1 {
protected void f(){}

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Feather1 feather1 = new Feather1();
Son1 son1 = new Son1();
Son11 son2 = new Son11();
son2.f();//编译通过,因为该测试类是Son1和Son11的父类
son2.clone();//编译通过,因为该测试类是Son1和Son11的父类
feather1.f();//编译通过,因为该测试类是Son1和Son11的父类
feather1.clone();//编译通过,因为该测试类是Son1和Son11的父类
son1.f();//编译通过,因为该测试类是Son1和Son11的父类
son1.clone();//编译通过,因为该测试类是Son1和Son11的父类
}
}

测试

1
2
3
4
5
6
7
8
9
10
package com.lizhi.protect.p4;

import com.lizhi.protect.p44.Test4;

public class MyObject4 extends Test4{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
1
2
3
4
5
6
7
8
9
10
package com.lizhi.protect.p44;

import com.lizhi.protect.p4.MyObject4;

public class Test4 {
public static void main(String[] args) throws CloneNotSupportedException {
MyObject4 myObject4 = new MyObject4();
myObject4.clone();//编译不通过
}
}

说明:myobject4的clone直接来自MyObject4类本身

其范围是MyObjcet4的子类与其同包的类

Test4都不满足

所以编译不通过

测试

1
2
3
4
5
6
7
package com.lizhi.protect.p4;

import com.lizhi.protect.p44.Test4;

public class MyObject4 extends Test4{

}
1
2
3
4
5
6
7
8
9
10
package com.lizhi.protect.p44;

import com.lizhi.protect.p4.MyObject4;

public class Test4 {
public static void main(String[] args) throws CloneNotSupportedException {
MyObject4 myObject4 = new MyObject4();
myObject4.clone();//编译通过
}
}

说明:myobject4的clone直接来源于Test4

范围是Test4子类及其同包的类

满足与其同包

编译通过

给作者买杯咖啡吧~~~