final关键字
- -用于修饰类、变量、常量、方法
- -final修饰类 为最终类 ,则不能给子类继承
- -final修饰方法,则该方法不能被重写
- -final修饰成员变量,要先进行赋值,赋值后该变量的值不能被修改
--类型为基本数据类型,赋值后该变量的值不能被修改
--类型为引用类型,则不能赋值一个新的对象,但是可以修改对象中成员变量的数值
- -final修饰局部变量,不要求先进行赋值,但是赋值后该变量的值不能被修改
//String类型是使用final修饰的最终类。
/**
* @author Lantzrung
* @date 2022年7月21日
* @Description
*/
package com.g0714work;
//String类型是使用final修饰的最终类。
//以下是String类型的部分源码展示
//public final class String
//@Stable
//private final byte[] value;//这些值都不能被修改的
//所以String类型的字符串的拼接是最耗费性能的,因为它本身是不可更改的对象,当我们进行字符串拼接的时候会产生一个新的字符串对象
//使用final修饰类,则不能被继承
//public final class Person {
//这里子类会出现报错 The type Student cannot subclass the final class Person
//类型Student不能将最后一个类Person子类化
public class Person {
// 使用final修饰成员变量(static 常量),必须要先进行初始化,则初始化后不能被修改
public final int item = 10;//成员变量
public final static int item2 = 10;//常量
//引用类型的变量,不可以修改,但是对象里面的数据可以进行修改
public final Student stu = new Student("张","nan",18);
// 通用eat方法 使用final修饰方法,则不能被重写
// 子类出现报错 子类不能被重写 Cannot override the final method from Person
public final void eat() {
// item = 15;//意思就是该成员变量不能再修改了The final field Person.item cannot be assigned
// item2 = 15;//与上面成员变量一样不能修改
// stu = new Student();//final修饰的对象 stu无法分配The final field Person.stu cannot be assigned
// stu.age = 19;//可以修改
// 使用final修饰局部变量,定义时可以不初始化,但是初始化后不能被修改
final int item3;
item3 = 15;
item3 = 10;//意思就是该成员变量已经给初始化过,无法再进行赋值操作了
//The final local variable item3 may already have been assigned
System.out.println("人吃饭的行为");
}
}
/**
* @author Lantzrung
* @date 2022年7月21日
* @Description
*/
public class Student extends Person {
public void eat() {
System.out.println("学生在饭堂吃饭");
}
}
编译时类型和运行时类型
Person p = new Student(); Student s = new Student();
引用变量定义的类型Person 为编译时类型
new 出来的对象类型Student 为运行时类型
1、方法调用时要注意是按照编译时类型来决定(编译时类型是决定你编程时是否会出现编译错误【语法】)
2、在运行程序时,是通过运行时类型来决定是否出错(对象转换时,对象类型是否兼容)
举例:动物里面有狗 、 猫
狗不能赋值给猫
/**
* @author Lantzrung
* @date 2022年7月21日
* @Description
*/
public class Test {
public static void main(String[] args) {
//引用类型是编译时类型 创建一个新的对象是运行时类型
Student p1 = new Student("zhang", "nan", 30);
Person p2 = new Student("li", "nan", 26);
//操作一:
p1.superEat();//人正在吃饭吃饭
//p2.superEat();//The method superEat() is undefined for the type Person_javac
//原因:在Java中先编译后运行的,父类中Person没有superEat()的方法,所以编译时不通过
p2.eat();//学生正在饭堂吃饭
//因为父类中有eat方法因此编译类型时通过,而且和子类中也有eat方法运行时通过,又因为运
//行时类型多态的应用把原本的编译时类型的Person给覆盖掉,故此输出出来的是子类Student
//运行时类型
//操作二:
//引用类型的转换:
//向上转型没有问题--可以的
//向下转型要强制类型转换--并不是所有的引用类型都可以做强制类型转换的
//要实现操作一中p2.superEat();达到输出的操作,可以使用向下转型进行强制转换类型
//从而达到编译运行操作结果
Student p3 = (Student) p2;
p3.superEat();//人正在吃饭吃饭
// //编译时通过,运行时不通过 并不是所有类型都是可以进行强制转换的
// //Exception in thread "main" java.lang.ClassCastException: Student cannot be cast
//to class Teacher
// Teacher p4 = (Teacher) p2;
//操作三:如何进行判断变量中的对象是否为某个类或者子类的对象
//instanceof用于判断引用变量中的对象是否为当前类或者当前类的子类的实例对象
//判断p2是否为Student的实例对象
// System.out.println(p2 instanceof Student);//true
// Student p3 = (Student) p2;
// p3.superEat();//人正在吃饭吃饭
//判断p2是否为Teacher的实例对象
// System.out.println(p2 instanceof Teacher);//false
// Teacher p4 = (Teacher) p2;
if (p2 instanceof Teacher) {
Teacher p4 = (Teacher) p2;
System.out.println(p4);
}else {
System.out.println("p2中不是Teacher类型的实例对象");
}//输出结果为:p2中不是Teacher类型的实例对象
}
}
/**
* @author Lantzrung
* @date 2022年7月21日
* @Description
*/
public class Student extends Person{
@Override
public void eat() {
System.out.println("学生正在饭堂吃饭");
}
public void superEat() {
super.eat();
}
public Student(String name, String age, int sex) {
super(name, age, sex);
}
public Student{
super();
}
}
/**
* @author Lantzrung
* @date 2022年7月21日
* @Description
*/
public class Teacher extends Person {
}
/**
* @author Lantzrung
* @date 2022年7月21日
* @Description
*/
public class Person {
public String name;
public String age;
public int sex;
public void eat() {
System.out.println("人正在吃饭吃饭");
}
public Person(String name, String age, int sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public Person {
super();
}
@Override
public String toString() {
return "Person_javac [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}