目录
final 关键字
- 继承的出现提高了代码的复用性,并方便开发。但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写。可是当子类继承了这些特殊类之后,就可以对其中的方法进行重写,那怎么解决呢?要解决上述的这些问题,需要使用到一个关键字final,final的意思为最终,不可变
- final 是个修饰符,它可以用来修饰类,类的成员变量、方法,局部变量
- Java 中的 String 类以及 八大数据类型的包装类(Integer...)都是被 final 修饰的类。保护性
1.1 final 修饰类
final 修饰类的特点
- final 修饰的类不能够被继承,但是可以继承其他类
- final 修饰的类中所有方法都会隐式的加上 final 关键字(不包含成员变量)
示例
class A {}
//被 final 修饰的类
final class B extend A {}//可以继承A类
class C extends B {}//不能够继承B类
1.2 final 修饰方法
final 修饰方法的特点
- final 修饰的方法不能够被重写(覆写)!但父类中没有被 final 修饰方法,子类重写后可以加 final
- final 修饰的方法常用于模板方法——保护性
示例
class A {
//被 final 修饰的方法不能够被重写,但可以继承使用
public final void method1(){}
public void method2(){}
}
class B extends A{
//重写method2方法;可以选择性添加 final 修饰符
public final void method2(){}
}
1.3 final 修饰局部变量
final 修饰基本数据类型变量
- 被 final 修饰的基本数据类型变量称为常量,这些变量只能赋值一次
示例
final int a = 10;
a = 20;//赋值出错;被 final 修饰的局部变量只能被赋值一次
final 修饰引用数据类型
- 引用类型的变量值为对象的地址值,地址值不能更改,但是地址内的对象属性值可以修改
举例
final Person person1 = new Person();
Person person2 = new Person();
person1 = person2;//final 修饰的变量person1,所保存的地址不呢个改变
person1.name = "kobe";// 可以更改person1中对象的属性值
1.4 final 修饰类的成员变量
final 修饰类的成员变量
修饰类的成员变量时需要在创建对象前赋值,否则报错
成员变量的初始化方式有:
- 直接初始化:public static int a = 5;类中常量一般使用 final + static,描述全局变量
- 代码块初始化 { a = 5;}
- 构造方法初始化
示例
class Person{
//直接初始化
final String name = "kobe";
{
//代码块初始化
this.name = "gigi";
}
public Person(String name) {
//构造方法初始化
this.name = name;
}
}
static 关键字
- 当在定义类的时候,类中都会有相应的属性和方法。而属性和方法都是通过创建本类对象调用的
- 当在调用对象的某个方法时,这个方法没有访问到对象的特有数据时,方法创建这个对象有些多余
- 可是不创建对象,方法又调用不了,这时我们可以通过static关键字来实现。static它是静态修饰符,一般用来修饰类中的成员
2.1 static 修饰的对象特有数据
特点
被static修饰的成员变量属于类,不属于这个类的某个对象。(也就是说,多个对象在访问或修改static修饰的成员变量时,其中一个对象将static成员变量值进行了修改,其他对象中的static成员变量值跟着改变,即多个对象共享同一个static成员变量)
代码演示
class Person{
static int a = 10;
}
public class Test {
public static void main(String[] args) {
Person person1 = new Person();
Person person2 = new Person();
person1.a = 100;
System.out.println(person1.a);//结果为100
System.out.println(person2.a);//结果为100
}
}
2.2 static 注意事项_静态不能直接调用非静态
注意事项
- 被 static 修饰的成员可以并且建议通过类名直接访问
访问静态成员的格式
- 类名 . 静态数据变量名
- 类名 . 静态成员方法名(参数)
不建议的访问格式
- 对象名 . 静态成员变量名 ——不建议使用该方式,会出现警告
- 对象名 . 静态成员方法名(参数) ——不建议使用该方式,会出现警告
代码演示
class Person{
final String name = "kobe";
final static int a = 10;
public static void method(){
System.out.println("method");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println(Person.a);//建议访问格式
System.out.println(person.a);//警告
Person.method();//建议访问格式
person.method();//警告
}
}
注意:当使用对象的引用调用静态方法时 person.method(); 编译器就会默认为 Person.mothed();因此 person 是什么都是无所谓的,哪怕是 null 也依旧能够正确运行
2.3 static 静态的使用场景
使用场景
static 可以修饰成员变量和成员属性
什么时候使用 static 修饰成员变量?
- 加static修饰成员的时候,这个成员会被类的所有对象所共享。一般我们把共性数据定义为静态的变量
什么时候使用 static 修饰成员方法?
- 静态的方法只能访问静态的成员,如果静态方法中引用其他静态的成员,那么这个方法就需要声明为静态的方法
2.4 对象中的静态调用
对象的静态调用
- 在多态中,非静态编译看父类,运行看子类,父类没有编译失败
- 多态中的静态方法,编译看父类,运行仍然看父类,因为静态和对象没有关系,属于静态绑定
示例
class Fu{
static void show(){
System.out.println("Fu:show");
}
}
class Zi extends Fu{
public Zi() {
super();
}
public static void main(String[] args) {
Fu fu = new Zi();
fu.show();//父类的引用和父类的方法绑定,和对象无关,不会执行子类的同名方法
}
}
//执行结果:Fu:show
2.5 定义静态常量
静态常量
当我们需要在类中定义一个静态常量时,通常使用 public static final 来修饰变量来达到静态常量。习惯变量名字母都大写
定义格式
public static final 数据类型 变量名 = 值;
示例
class A {
public static final String NAME = "静态常量";
public static void method(){
System.out.println("静态方法method");
}
}
//当我们使用类的静态成员时 不需要new对象,直接使用类名调用即可
System.out.println(A.NAME);//打印静态常量
A.method();//静态方法method
注意
接口中的每一个成员变量默认使用 public static final 修饰
所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问
示例
interface Inter{
public static final int NUMBER = 100;
}
//访问接口中的静态变量
Inter.NUMBER 100