Java编程思想(六)

访问权限控制

修饰符范围
public范围最大,共有的,不管是谁都可以用
protectd范围次之,受保护的,只能是我的子孙后代可以用
包权限范围在次之,只能在同一个包内,才可以用
private范围最小,我的就是我的,谁都不给

一些使用Tips:

  • 子类可以放大父类的访问权限。列如,父类的方法是protected修饰的,在子类可以把修饰符改成public。就是说,儿子从老子那里接过来的传家宝,儿子觉得这什么都不是,当什么传家宝,就公开给狐朋好友调用了。但是子类不能缩小父类的访问权限。列如:父类的方法是public修饰的,子类不能改成protected。就是说,老子已经公开了,儿子不能去抢回来当传家宝了。
  • 除内部类,类的修饰符只能有public和包权限。接口申明的方法只能是public的,抽象类的抽象方法不能是private

final关键字

根据语义表达的就是“这是无法改变的”。不想改变就两个理由:设计、效率。分下面三种情况:数据,方法,和类

  • final数据,用来告诉编译器一块数据是恒定不变的。主要两个作用:

    1. 一个永不改变的编译时常量
    2. 一个在运行是被初始化的值,不希望程序把它改变

    对于编译期常量,编译器在编译的时候,可以将该常量值带入任何可能用到它的计算式中。当final修饰的对象引用的时候,则表示对此对应引用保持恒定不变。但是这个对象本身是可以变动的。一个被final和static同时修饰的变量则表示这是一块固有的、不能改变的。

  • final 方法

    1. 锁定方法,不让子类重写
    2. 效率问题,但是在Java SE5版本之后已经将这部分工作转到编译器和JVM优化中。

    类中所有的private方法都隐式的指定为final的。所以private方法不存在是不是final类型的方法的问题

  • final类
    final修饰类的时候则表示这个类不可以被继承。

类初始化顺序

我们来通过一个例子进行理解

/**
 * 注释里面的四位数字代表这个语句执行的位置
 */
class Child {
    private int i = 9;
    protected int j;
    //4444
    private int m = printInit("Child m initialized");
    Child() {
        //5555
        System.out.println("i = " + i + ", j = " + j + ", m= " + m);
        j = 39;
    }
    //1111
    private static int x1 = printInit("static Child.x1 initialized");

    public static int printInit(String msg) {
        System.out.println(msg);
        return 47;
    }
}

class Parent extends Child {
    //6666
    private int k = printInit("Parent k initialized");

    public Parent() {
        //7777
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }
    //2222
    private static int x2 = printInit("static Parent.x2 initialized");

    public static void main(String[] args) {
        //3333
        System.out.println("Parent constructor");
        Parent classOrder = new Parent();
    }
}

我在上面的代码标注了输出的顺序,是不是有点蒙。我们一步一步来。
1. 程序需要执行,需要加载类,所以我们需要加载Parent和Child的类。加载class的时候就会把static对象加载。然后Parent继承与Child,所以Child会先一步加载,Parent会后一步加载。当然我们也可以知道如果Child还继承与别的Class的话,别的Class肯定是先于Child类加载的。所以到现在输出了上面1111,和2222语句对应内容
2. 调用Parent的构造函数,这个没得说。3333得以输出
3. 在实例化对象的时候,会调用构造函数这没得说。那为什么不是先输出6666对应的语句,反而是4444对应的语句呢。是因为子类在构造函数的第一句执行的是调用的父类的构造函数,所以Child的构造函数会被先调用。然后4444是在成员变量块,5555是在构造函数中。所以4444,5555输出出来了。然后才轮到Parent他自己初始化。所以6666,7777语句得以输出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值