final、权限、内部类
final关键字概念与四种用法
final关键字代表最终的、不可变的。
final关键字的常用四种用法:
- 用来修饰一个类:不能有子类,所以其中所有的方法都不能被覆盖重写。
- 用来修饰一个方法:方法就无法被覆盖重写。
- 用来修饰一个局部变量:一次赋值,终生不变。
- 用来修饰一个成员变量:一次赋值,终生不变。没有默认值,需要自己手动赋值。
基本类型数据值不可变;引用类型地址值不可变。
final关键字用于修饰类
一旦一个类使用了final关键字,那么这个类就无法拥有任何子类。
这样的类,叫做“太监类”。
final关键字和abstract关键字冲突,不能同时使用。
final关键字用于修饰成员变量
final用来修饰一个成员变量,也是一次赋值,终生不变。
基本数据类型,数据值不变;引用数据类型,地址值不变。
成员变量本来是有默认值的。
但是,一旦final修饰了成员变量,那么将不再具有默认值。
这样的成员变量必须进行赋值,两种方式:
- 直接在定义的时候赋值
- 通过构造方法赋值
final关键字用于修饰局部变量
final用来修饰一个局部变量,那么这个局部变量:一次赋值,终生不变。
当使用final关键字的时候,需要注意:
对于基本类型来说,不能变的是【数据值】
对于引用类型来说,不能变的是【地址值】
final关键字用于修饰成员方法
如果final关键字用来修饰了成员方法,那么这样的方法就无法被覆盖重写。
四种权限修饰符
注意事项:
- (default)并不是关键字default,而是什么都不写。
- 虽然demo02是sub的父包,但是在demo02当中如果需要使用sub的内容,仍然需要导包。
内部类的概念和分类
内部类概念:在一个类的里面再定义一个类,里面的类就叫做内部类。
内部类的分类:
- 成员内部类
- 局部内部类(包含匿名内部类)
成员内部类的定义
成员内部类:定义在类当中,在方法外。
成员内部类的定义格式:
修饰符 class 外部类名称 {
修饰符 class 内部类名称 {
// …
}
}
成员内部类的使用
使用方式:
- 间接使用:在外部类的成员方法当中,创建一个内部类的对象。只管调用外部类对象的外部成员方法即可。
- 直接使用:直接使用Heart内部类对象,记住一个公式:
外部类.内部类 对象名 = new 外部类().new 内部类();
备注:
- 外部类和内部类仍然可以继续定义成员变量、成员方法,而且用本类当中的东西,仍然是随便用。
- 内部类如果访问外部类的内容,可以随意。
- 外部类访问内部类的内容,必须有一个内部类的对象才行。
- 编译生成的.class文件名称为“外部类$内部类.class”
内部类的同名变量访问
如果内部类当中定义的方法,需要访问外部类的成员变量,怎么办?
外部类名称.this.成员变量名
外部类.内部类 对象名 = new 外部类().new 内部类();
局部内部类定义
局部内部类:定义在方法里,只有本方法才可以用。
局部内部类的final问题
在Java 7或者更早版本中,如果局部内部类访问所在方法的局部变量,那么这个局部变量一定需要是有效final的才行。
从Java 8开始,只要这个局部变量是有效final的,就可以省略final关键字。
为什么?
因为局部变量和内部类创建的对象生命周期不同。
匿名内部类
匿名内部类。
格式:
接口名称 对象名 = new 接口名称() {
// 实现所有抽象方法
};
解析:
new:创建对象的意思。
右侧的接口名称:匿名内部类所实现的接口名
右侧的{}:匿名内部类
匿名内部类的好处:省去了单独定义一个XxxImpl实现类的麻烦。
匿名内部类适合创建那种只需要一次使用的类,创建匿名内部类是会立即创建一个该类的实例,这个类立即消失,匿名内部类不能重复使用。
匿名内部类的注意事项
- 匿名内部类的使用前提:必须产生继承关系或者接口的实现关系。
- 匿名内部类可以使用接口,也可以使用抽象类,也可以使用普通的类。只要不是final的,就可以。
- 匿名内部类(局部内部类)编译之后因为没有名字,所以产生的字节码文件是“外部类名称$1.class”。
类作为成员变量类型
接口作为成员变量类型
接口作为方法的参数或返回值
总结
总结一下各种class定义的时候,权限修饰符的用法:
- 外部类:public、(default)
- 成员内部类:public、protected、(default)、private
- 局部内部类:什么都不能写,而且这并不是(default)权限。