Java

搞懂了Java中的权限访问修饰符

1 public

所谓的public最简单,就是全开放,谁都可以访问。不管你是不是我的子类,也不管你是不是和我在同一个包,我都开放给你访问。

2 private

所谓的private则是最严格,只允许在我当前类的内部使用,离开了我这个类,谁也不能访问。private修饰的方法,不能被Override。

Q1:如果父类中有某个方法是private的,其子类中也有一个同名且相同签名的方法,那么这2个方法有什么关系?子类中的那个方法是Override父类的同名方法吗?

A1:它们没有任何关系,并不是覆写父类的同名方法。只是凑巧它们同名而已。

Q2:如果父类中有某个方法是private的,其子类中也有一个同名且相同签名的方法,但是子类的该同名方法访问修饰是public或者protected或者是default的package访问权限。子类中的该方法是Override父类的同名方法吗?

A2:依然不是,它们只是凑巧同名而已。

final and private

Any private methods in a class are implicitly final.Because you can’t access a private mehtod,you can’t override it.You can add the final specifier to a private method,but it doesn’t give that the method extra meaning.

This issue can cause confusion,because if you try to override a private method(which is implicitly final),it seems to work,and the compiler doesn’t give an error message.

“Overriding” can only occur if something is part of the base-class interface.That is,you must be able to upcast an object to its base type and call the same method.If a method is private,it isn’t part of the base-class interface.

If you create a public,protected,or packageaccess method with the same name in the derived class,there is no connection to the method that might happen to have that name in the base class.You havent overriden the mehtod;you’ve just create a new method.Since a private method is unreachable and effectively invisible out side of the base-class.

——–摘抄并稍微改写自《Thinking in Java》第4版 英文版P268-269

通常情况下:

  • 类中的字段都设置为private;
  • 如果有一些辅助性的方法,只是在当前类中使用的话,也要设置为private;
  • private一般不会用于去修饰一个类;

3 protected

这个就有点儿意思:意味着我用protected修饰的类、字段、方法,如果你想要访问的话:

  • 要么你是我的子类,不管你是不是和我在同一个包下,只要是我的子类即可;
  • 要么你就得和我在同一个package下。意思是,如果你不是我的子类的话,你如果还想要访问我,那么你就必须得和我在同一package下,没得任何商量余地。当然,如果你和我在同一个包下,不管你是不是我的子类,你都可以访问我。

4 default|package

如果一个类、字段、方法它们前面没有任何访问修饰符(public,private,proteced)的其中一个的话,就是默认修饰符,或者叫package修饰符。默认修饰符,意味着,被我修饰的类、字段、方法,你如果想有访问的话,你就不得不满足唯一的一个条件,那就是,你必须得和我在同一个package下。即使,你是我的子类,你也必须得和我在同一个package下。事实上,如果你不和我在同一package下,你也无法继承我。

5 样例代码

package ThinkingInJavaPractice.ReusingClasses;
/**
 * @Author:asher
 * @Date:2021/3/12 21:57
 * @Description:ThinkingInJavaPractice.ReusingClasses
 * @Version:1.0
 */
class WithFinals{
    private final void f() {
        System.out.println("WithFinals.f()");
    }
​
    private void g() {
        System.out.println("WithFinals.g()");
    }
}
​
class OverridingPrivate extends WithFinals {
    private final void f() {
        System.out.println("OverridingPrivate f()");
    }
​
    private final void g() {
        System.out.println("OverridingPrivate g()");
    }
}
​
class OverridingPrivate2 extends OverridingPrivate{
    public final void f() {
        System.out.println("OverridingPrivate2 f()");
    }
    public final void g(){
        System.out.println("OverridingPrivate2 g()");
    }
}
public class FinalOverridingIllusion {
    public static void main(String[] args) {
        OverridingPrivate2 op2 = new OverridingPrivate2();
        op2.f();
        op2.g();
        //you can upcast,
        OverridingPrivate op = op2;
        //but you cant call the methods:
        //不注释下面的2行代码,编译器将报错
        //op.f();
        //op.g();
        //同样的道理,虽然op2可以upcast成WithFinals父类,但是并不能调用父类中的方法,f()和g()
        WithFinals wf = op2;
        //wf.f();
        //wf.g();
    }
}
//输出结果
//OverridingPrivate2 f()
//OverridingPrivate2 g()
​

留言