访问控制(access control)及final、static关键字


访问控制很烦人,You're going to love this artical.


Access modifiers(from less restrictive to more restrictive): 

                     public、protected、default(package access)、private

Non-access modifiers(inluding final, abstract and strictfp)


1. class Accesses

(1) Default acess

A class with default access has no modifier preceding it in the declaration!

Think of default access as package-level access, because a class with default access can be seen only by classes within the same package. 


(2) Public access

A class declaration with the public keyword gives all classes from all packages access to the public class.


Remenber that  a class can use just two of the four access control levels :default or public !


(3) Other (Nonaccess) Class Modifiers

You can modify a class declaration using the keyword final,abstract.


(3-1)Final classes

 When used in a class declaration, the final keyword means the class can't be subclassed. In other words, no other class can ever extend (inherit from) a final class. The methods whose class arefinal are default final.


(3-2)Abstract Classes

An abstract class can never be instantiated.

The methods marked abstract end in a semicolon rather than curly braces. 

You can, however, put nonabstract methods in an abstract class.

 It is legal that an abstract class has no abstract methods.


2. Declare Class Members

(0)Access Modifiers

Whereas a class can use just two of the four access control levels (default or public), members can use all four:

public、protected、default、private


The default and protected access control types have almost identical behavior, except for one difference that will be mentioned later.


(1)Public Members

When a method or variable member is declared public, it means all other classes, regardless of the package they belong to, can access the member (assuming the class itself is visible).


(2)Private Members

Members marked private can't be accessed by code in any class other than the class in which the private member was declared. A private member isinvisible to any code outside the member's own class.


What about a subclass that tries to inherit a private member of its superclass?

When a member is declared private, a subclass can't inherit it.

A subclass can't see, use, or even think about the private members of its superclass. You can, however, declare a matching method in the subclass. But regardless of how it looks,it is not an overriding method! 


(3)Protected and Default Members

The protected and default access control levels are almost identical, but with one critical difference. A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.

Take a look at the following two classes:

package certification;                                                                      
public class OtherClass {
    void testIt() {     //No modifer means method has default access
        System.out.println("OtherClass");
    }
}

In another source code file you have the following:

package somethingElse;                                                                      
import certification.OtherClass;

class AccessClass {
    public static void main(String[] args) {
        OtherClass o = new OtherClass();
        o.testIt();
    }
}



From the preceding results, you can see that AccessClass can't use the OtherClass method testIt() because testIt() has default access, and AccessClass is not in the same package as OtherClass. So AccessClass can't see it, the compiler complains.

Default and protected behavior differ only when we talk about subclasses. If the protected keyword is used to define a member, any subclass of the class declaring the member can access it through inheritance. It doesn't matter if the superclass and subclass are in different packages, the protected superclass member is still visible to the subclass (although visible only in a very specific way as we'll see a little later).


NOW, let's see Protected Details.


3. Protected Details

What does it mean for a subclass-outside-the-package to have access to a superclass (parent) member? It means the subclass inherits the member. It does not, however, mean the subclass-outside-the-package can access the member using a reference to an instance of the superclass. In other words, protected = inheritance.


Protected does not mean that the subclass can treat the protected superclass member as though it were public. So if the subclass-outside-the-package gets a reference to the superclass (by, for example, creating an instance of the superclass somewhere in the subclass' code), the subclass cannot use the dot operator on the superclass reference to access the protected member. 


To a subclass-outside-the-package, a protected member might as well be default (or even private), when the subclass is using a reference to the superclass. The subclass can see the protected member only through inheritance.


package certification;
public class Parent {
    protected int x = 9;    // protected access
} 

package other;
import certification.Parent;

class Child extends Parent {
    public void testIt() {                                                                  
        System.out.println("x is " + x);    // No problem, Child inherites x
        Parent p = new Parent();    // Can we acess x using the p reference ?
        System.out.println("x in parent is " + p.x); // compiler error!
    }
}

The compiler is more than happy to show us the problem:



For a subclass outside the package, the protected member can be accessed only through inheritance.


Can access modifiers be applied to local variables? NO!
There is never a case where an access modifier can be applied to a local variable.


4. Nonaccess Member Modifiers:final

(1) Final Methods

The final keyword prevents a method from being overridden in a subclass.

The special method constructor can not be final !


(2)Final Fields or local Variables

A final variable has kind of types:

1)It can be a compile-time constant that won't ever change.

2)It can be a value initialized at run time that you don't want changed.

也算就是说final变量要么在声明时赋值(此时为编译时常量),要么在使用之前赋值(此时为运行时常量,编译器保证这一点)。因此final并不意味着变量的值一定实在运行时已知的。


如果是运行时常量,它们初始化的地方有限制:

instance final field 使用之前只能在构造函数或instance block中初始化,不能在实例方法中初始化。

static final filed 只用之前只能在static block初始化。


public class Final {
    final int x = 2;    // compile-time constant
    final int y;        // blank final, It must be initialized before used, and 
                        // the compiler ensures this
    final int z;                                                                            
    static final int a;
    static {
        a = 8;
        System.out.println("a is initialized to " + a);
    }
    {
        z = 4;
        System.out.println("z is initialized to " + z);
    }
    Final() {
        y = 6;
        System.out.println("y is initialized to " + y);
    }
    public void testFinal() {
        final int h;    //It must be initialized before used, and
                        // the compiler ensures this
        h = 6;
        System.out.println("h is initialized to " + h);
    }
public static void main(String[] args) {
        new Final().testFinal();
    }
} 


output:



(3) Final Arguments

Method arguments are essentially the same as local variables.

Method argument is declared as final, which of course means it can't be modified within the method.


5. Nonaccess Member Modifiers:static

Things you can mark as static:

Methods
Variables(Non-local)
A class nested within another class, but not within a method.
Initialization blocks


Things you can't mark as static:

Constructors (makes no sense; a constructor is used only to create instances)

Classes (unless they are nested)
Interfaces
Method local inner classes 
Inner class methods and instance variables
Local variables


You must never, ever, ever mark a class as both final and abstract. They have nearly opposite meanings.



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值