final关键字
final可以修饰类、属性、方法和局部变量
在某些情况下,程序员可能有以下需求,就会使用到final:
- 当不希望类被继承时,可以用final修饰.
- 当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字修饰。
- 当不希望类的的某个属性的值被修改,可以用final修饰
- 当不希望某个局部变量被修改,可以使用final修饰
注意事项和细节:
-
final修饰的属性又叫常量,一般用XX_XX_XX来命名
-
final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一【选择一个位置赋初值即可】:
①定义时:如public final double TAX_RATE=0.08;
②在构造器中
③在代码块中
总之,对象建立时final定义的属性必须有值
-
如果final修饰的属性是静态的,则初始化的位置只能是①定义时②在静态代码块,不能在构造器中赋值。
-
final类不能继承,但是可以实例化对象。
-
如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承。
-
一般来说,如果一个类是final类,方法就没必要写成final方法了
-
final不能修饰构造方法
-
final和static往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理
-
包装类(Integer、Double、Float、Boolean等)、String都是final
抽象类
当父类的某些方法需要声明,但是又不确定如何实现时,可以将该方法设计为抽象方法。所谓抽象方法就是没有实现的方法。所谓没有实现就是指没有方法体。当一个类中存在抽象方法时,需要将该类声明为抽象类。一般来说,抽象类会被继承,由其子类实现抽象方法。
-
介绍
-
用abstract关键字修饰一个类时,这个类就叫抽象类
访问修饰符 abstract 类名 { }
-
用abstract关键字修饰一个方法时,这个方法就叫抽象方法
访问修饰符 abstract 返回类型 方法名(参数列表);//没有方法体
-
抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类
-
抽象类是考官爱问的知识点,在框架和设计模式使用较多
-
-
注意事项和细节
-
抽象类不能被实例化
-
抽象类不一定要包含抽象方法,可以没有抽象方法
-
一旦类包含了抽象方法,则这个类必须被声明为抽象类
-
abstract只能修饰类和方法,不能用于他处
-
抽象类可以有任意成员(抽象类还是类),比如非抽象方法、构造器、静态属性等等
-
抽象方法不能有主体,即不能实现
-
如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为抽象类
-
抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的
private:不允许类外访问,自然不能继承
final:不可继承
static:static和abstract是非法组合,抽象类是不能实例化的,即不能被分配内存;而static修饰的方法在类实例化之前就已经别分配了内存,存在矛盾;定义抽象方法的目的是重写此方法,但如果定义成静态方法就不能被重写
-
抽象类最佳实践—模板设计模式
接口
实现接口,本质就是把接口的方法实现。
在接口中,抽象方法可以省略abstract关键字。
-
基本介绍
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来
语法:
interface 接口名{
//属性
//方法(包括抽象方法、默认实现方法、静态方法)
}
class 类名 implements 接口{
自己属性;
自己方法;
必须实现的接口的抽象方法;
}
小结:
- 在jdk7.0前,接口的所有方法都没有方法体,即都是抽象方法
- jdk8.0后接口可以有静态方法、可以有默认实现方法(需要使用default关键字修饰),也就是说接口中可以有方法的具体实现
-
注意事项和细节
-
接口不能被实例化
-
接口中的所有方法是public方法,接口中抽象方法,可以不用abstract修饰
void aaa(); //实际上是 abstract void aaa();
-
一个普通类实现接口,就必须将该接口的所有方法都实现,可以使用alt+enter快捷键来解决
-
抽象类实现接口,可以不用实现接口的方法
-
一个类可以同时实现多个接口
-
接口中的属性,只能是final 的,而且是public static final 修饰符
interface IB{ int n1 = 100; //相当于 public static final int n1 = 100; }
-
接口中属性的访问形式:接口名.属性名
-
接口不能继承其他的类,但是可以继承(extends)多个别的接口
interface A extends B,C {}
-
接口的修饰符只能是public和默认,这点和类的修饰符是一样的
-
-
实现接口 vs 继承类
实现机制是对单继承机制的一种补充
当子类继承了父类,就自动拥有了父类的功能
如果子类需要扩展功能,可以通过接口的方式扩展
-
继承的价值主要在于:解决代码的复用性和可维护性
接口的价值主要在于:设计,设计好各种规范(方法),让其他类去实现这些方法,即更加的灵活
-
接口比继承更加灵活
接口比继承更加灵活,继承是满足is-a的关系,接口只需满足like-a 的关系
-
接口在一定程度上实现代码解耦(即:接口规范性+动态绑定机制)
-
-
接口的多态特性
-
多态参数(形参是接口,实参是实现接口的类的对象实例)
-
多态数组
Usb[] usbs = new Usb[2]; usbs[0] = new Phone_(); usbs[1] = new Camera_(); //接口类型的变量可以指向实现了该接口的类的对象的实例 interface Usb{} class Phone_ implents Usb{} class Camera_ implents Usb{}
-
多态传递
IG ig = new Teacher(); IH ih = new Teacher(); //爷爷辈也可以指向孙子辈的对象 interface IH {} interface extends IH {} class Teacher inplements IG {}
-
-
练习
interface A{ int x = 0;//public static final x = 0; } class B{ int x = 1; } class C extends B implements A{ public void printX(){ System.out.println(x);//错误,编译时分不清是哪个x //输出接口A的x System.out.println(A.x); //输出父类B的x System.out.println(super.x); } }
类五大成员:
- 属性
- 方法
- 构造器
- 代码块
- 内部类(难)