1.1🍒final的定义
final在中文中的意思就是最后的、最终的
final在Java中可以修饰类、属性、方法、局部变量
(1).当不希望一个类被继承时,可以用final修饰
(2).当不希望一个父类的某个方法被子类重写,可以用final使这个方法不能被重写
(3).当不希望某个属性被修改,可以用final修饰
(4).当不希望某个全局变量被修改,可以用final修饰
// >(1).当不希望一个类被继承时,可以用final修饰
final class A{}
//class B extends A{ //err
//}
// >(2).当不希望一个父类的某个方法被子类重写,可以用final使这个方法不能被重写
class C{
public final void m1(){}
}
class D extends C{
// @Override
// public void m1(){} // err
}
// >(3).当不希望某个属性被修改,可以用final修饰
class E{
// 无法修改
public final double TAX_RATE = 0.08;
}
// >(4).当不希望某个全局变量被修改,可以用final修饰
class F{
public void cry(){
// 局部常量
final double NUM = 0.01;
// NUM = 0.9; // err
}
}
1.2🍿final细节
1
.final所修饰的属性,会被称作常量,命名规范XXX_XXX_XXX_
2
.final所修饰的属性必须赋初始值,可以在以下3个方面进行初始化
(1). 定义时:如 public final double TAX_RATE=0.08;
(2). 在构造器中
(3). 在代码块中
3.
如果final修饰的属性是静态的,则初始化的位置只能是
1 定义时 2 在静态代码块 不能在构造器中赋值。
4.
final类不能继承,但是可以实例化对象
5.
如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承
6.
一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法
7.
包装类,String 是final类,不能被继承
8.
final不能修饰构造器
9.
final 和 static 往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理
class AA {
/*
1. 定义时:如 public final double TAX_RATE=0.08;
2. 在构造器中
3. 在代码块中
*/
public final double TAX_RATE = 0.08;//1.定义时赋值
public final double TAX_RATE2 ;
public final double TAX_RATE3 ;
// public final double TAX_RATE4 ; // final所修饰的变量必须初始化
public AA() {//构造器中赋值
TAX_RATE2 = 1.1;
}
{//在代码块赋值
TAX_RATE3 = 8.8;
}
}
class BB {
/*
如果final修饰的属性是静态的,则初始化的位置只能是
1 定义时 2 在静态代码块 不能在构造器中赋值。
*/
public static final double TAX_RATE = 99.9;
public static final double TAX_RATE2 ;
static {
TAX_RATE2 = 3.3;
}
// err
// public BB() {
// TAX_RATE2 = 3.4;
// }
}
解析
这个好理解,因为是static变量,是在类加载的时候就完成了初始化,再加上final关键字, 必须要创建对象前完成初始化,所以就不能在构造器中进行构造器初始化了
class DD {
public final void cal() {
System.out.println("cal()方法");
}
}
class EE extends DD { }
public class FinalDetail02 {
public static void main(String[] args) {
System.out.println(BBB.num);
//包装类,String 是final类,不能被继承
}
}
//final 和 static 往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理
class BBB {
public final static int num = 10000;
static {
System.out.println("BBB 静态代码块被执行");
}
}
final class AAA {
//一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法
//public final void cry() {}
}
这里可以看到,一个变量被final和static所修饰时,如果想调用它,不会导致类加载,比如这个静态代码块就没被执行,
从而提升了效率
1.3🍷final练习
说说下面代码哪里错了?
public class FinalExercise02 {
public int addOne(final int x) {
//错误,原因是不能修改 final x的值
++x; // err
//这里是可以.只是返回值并未修改值
return x + 1;
}
}
2.1🍫抽象类的定义
父类方法不确定性的问题 考虑将该方法设计为抽象(abstract)方法
abstract class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
//这里eat 这里你实现了,其实没有什么意义
//即: 父类方法不确定性的问题
//===> 考虑将该方法设计为抽象(abstract)方法
//===> 所谓抽象方法就是没有实现的方法
//===> 所谓没有实现就是指,没有方法体
//===> 当一个类中存在抽象方法时,需要将该类声明为abstract类
//===> 一般来说,抽象类会被继承,有其子类来实现抽象方法.
// public void eat() {
// System.out.println("这是一个动物,但是不知道吃什么..");
// }
public abstract void eat() ;
}
比如这个eat方法,不知道要实现什么功能,可以用abstract所修饰,这样可以不用写方法体了
2.2🥒抽象类的细节
(1)抽象类,不能被实例化
(2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
可以有自己的方法。
(3)一旦类包含了abstract方法,则这个类必须声明为abstract
(4)abstract 只能修饰类和方法,不能修饰属性和其它的
public class AbstractDetail01 {
public static void main(String[] args) {
//(1)抽象类,不能被实例化
//new A();
}
}
//(2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
//可以有自己的方法。
abstract class A {
public void hi() {
System.out.println("hi");
}
}
//(3)一旦类包含了abstract方法,则这个类必须声明为abstract
abstract class B {
public abstract void hi();
}
//(4)abstract 只能修饰类和方法,不能修饰属性和其它的
class C {
// public abstract int n1 = 1;
}
(1)抽象类的本质还是类,所以可以有类的各种成员
(2)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
(3)抽象类的方法不能有方法体
(4)抽象方法不能使用private、final 和 static来修饰,因为这些关键字都是和重写相违背的
//(1)抽象类的本质还是类,所以可以有类的各种成员
abstract class D {
public int n1 = 10;
public static String name = "abc";
public void hi() {
System.out.println("hi~");
}
public abstract void hello();
public static void ok() {
System.out.println("ok~");
}
}
//(2)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
abstract class E {
// (3)抽象类的方法不能有方法体
public abstract void hi();
}
abstract class F extends E {
}
class G extends E {
//这里相等于G子类实现了父类E的抽象方法,所谓实现方法,就是有方法体
@Override
public void hi() {
}
}
//(4)抽象方法不能使用private、final 和 static来修饰,因为这些关键字都是和重写相违背的
abstract class H {
public abstract void hi();//抽象方法
}
解析
(1)如果一个类的方法被private修饰,说明这个方法只能在本类使用,子类就不能重写了
(2)不能用final关键字好理解,因为用了final关键字就不能继承这个类,从而不能重写这个方法了
(3)static修饰的是静态方法,可以直接被调用;而abstract修饰的类中只有方法声明,没有方法实现,不能被直接调用。所以二者冲突,不能共存。