第14章-final
概述
- final,最终的,就如字面意义,是Java语法中一个重要的关键字
- 主要作用有:
- 修饰类,表示该类为最终类,不能被继承
- 修饰变量,表示变量值不能被修改,转化成了常量
- 修饰方法,表示该方法不能被覆盖
修饰类
Java中的类,只要可访问,就能随意的扩展,定义其子类、孙子类等;但在有些情况下,我们是不希望某些类具备子类的;像String类
此时,就可以使用final关键字将类定义为最终类,让其不能被继承
应用实例
应用实例1,下面的代码是否正确?
package com.bjpowernode.demo;
/**
* 人类
*/
public final class People {
}package com.bjpowernode.demo;
/**
* 中国人类
*/
public class ChinaPeople extends People {
}
修饰变量
在一些应用场景,变量被赋值之后,希望不能被修改
此时,就可以使用final关键字将变量转换成常量,就具备了不可修改特性
常量名多使用全大写、下横线连接方式,如MIN_VALUE、HOST_URL_PREFIX等
常量主要应用
- 修饰局部变量,局部变量就变成了局部常量,只能赋值一次,且常量不能被修改
- 修饰类成员变量,必须赋初值,或使用延后赋值形式,在不同的构造方法中赋不同的值;如从的血型、参加工作时间等特征
- 注意:
- 引用类型的常量的子属性是可以修改
- 接口中的成员变量,是静态常量,使用public static final修饰
- 常量中尽量不要存放大对象
应用实例
应用实例1,修饰成员常量,下面2段代码,是否正确?为什么?
代码1
package com.bjpowernode.demo;
/**
* final示例,修饰成员常量
*/
public class FinalDemo {
//定义常量,url前缀
public final String URL_PREFIX;
}代码2
package com.bjpowernode.demo;
/**
* final示例,修饰成员常量,可直接初始化,也可以在构造方法中初始化,并且可以在不同的构造方法中初始化不同的值
*/
public class FinalDemo {
//修饰成员常量
public final String URL_PREFIX;
/**
* 无参构造方法
*/
public FinalDemo() {
URL_PREFIX = "http://www.baidu.com";
}
/**
* 有参构造方法
*/
public FinalDemo(String urlPrefix) {
URL_PREFIX = urlPrefix;
}
}应用实例2,修饰局部变量,基本数据类型常量,下面的代码是否正确?为什么?
代码1
package com.bjpowernode.demo;
/**
* final示例,修饰基本数据类型常量,可在定义时赋值,也可以定义后再赋值,但不能修改常量值
*/
public class FinalDemo {
/**
* 入口方法
*
* @param args
*/
public static void main(String[] args) {
//定义常量
final int intVariable;
//设置初始值
intVariable = 5;
//修改值,会有编译错误
intVariable = 20;
}
}实例3,修饰局部变量,引用数据类型常量,下面2段的代码,是否正确?为什么?
代码1
package com.bjpowernode.demo;
/**
* final示例,修饰引用数据类型,特点跟修饰基本数据类型常量一样,不能修改常量值
*/
public class FinalDemo {
//姓名
private String name;
/**
* 入口方法
*
* @param args
*/
public static void main(String[] args) {
//定义常量
final FinalDemo finalDemo;
//设置初始值
finalDemo = new FinalDemo();
//修改值,会有编译错误
finalDemo = new FinalDemo();
}
}代码2
package com.bjpowernode.demo;
/**
* final示例,修饰引用数据类型常量,虽然不能修改常量的值,但常量指向对象的子属性值可以修改
*/
public class FinalDemo {
//姓名
String name;
/**
* 入口方法
*
* @param args
*/
public static void main(String[] args) {
//定义常量
final FinalDemo finalDemo;
//设置初始值
finalDemo = new FinalDemo();
//修改常量子属性值,可以修改
finalDemo.name = "尼古拉斯";
finalDemo.name = finalDemo.name + ".赵四";
}
}实例4,接口(类)中的静态常量
工作接口
package com.bjpowernode.demo;
/**
* 工作接口
*/
public interface IWork {
//可以定义一些应用于工作实现类需要使用,与工作业务相关的静态常量,如一些阈值
int MIN_AGE = 0; //最小年龄
int MAX_AGE = 150; //最大年龄
int MIN_WORK_AGE = 16; //法定工作年龄
// int OTHER_AGE; //常量必须初始化,否则会报错
/**
* 操作
*/
void operating();
}工作接口示例
package com.bjpowernode.demo;
/**
* 工作接口示例
*/
public class WorkDemo {
public static void main(String[] args) {
// IWork.MIN_AGE = 33; //常量不能修改,会报错误
//使用接口静态常量
System.out.println("最小年龄:" + IWork.MIN_AGE);
System.out.println("最大年龄:" + IWork.MAX_AGE);
System.out.println("最小工作年龄:" + IWork.MIN_WORK_AGE);
}
}
修饰方法
在有一些应用场景中,在类可被任意扩展(被继承)的情况下,希望某些方法行为是不可被子类重新定义的(即不需要多态特性)
此时,也可使用final关键字修饰这些方法,使得子类不仅具备了该方法,且需要严格按照父类该方法的逻辑来完成业务
应用实例
应用实例1,下面的代码是否正确?
package com.bjpowernode.demo;
/**
* 人类
*/
public class People {
/**
* 打招呼
*/
public final void speakHi(){
System.out.println("打了个招呼。");
}
}package com.bjpowernode.demo;
/**
* 中国人类
*/
public class ChinaPeople extends People {
/**
* 打招呼
*/
public void speakHi() {
System.out.println("中国人打招呼。");
}
}
实战和作业
- 练习演示的内容,完成代码编写
- 重构程序,将第13章重构后的people项目中,做如下重构,要求如下
- 所有国家的人类都国际歌属性
- 每个国家人类都有国歌属性
- 中国人、越南人等国家的人,具备是否为社会主义国家属性,且值为是
- 给所有国家的人添加一种相同的鼓掌行为
- 创建一个新的国家类梵蒂冈,不具备派生能力