Final关键字
使用情况:
1. 不希望类被继承,该类用final修饰
2.不希望类的某个方法被子类重写,可以将该方法用final修饰(final修饰 方法不可以被重写但是可以被重载)
3.不希望类的某个属性值被修改/不希望局部变量被修改 ,用final修饰
细节:
1.final修饰的属性又称为常量,一般用XX_XX_XX命名
2.final修饰的属性在定义时,必须赋值并且之后不可修改,赋值操作可以在以下任一位置(选择一个位置赋初值即可):
①定义时,如:public final double TAX_RATE = 0.08;
②在构造器中 ③在代码块中
3.当final修饰的属性是静态的,则初始化位置只能是 ①定义时 ②在静态代码块中,不能在构造器中赋值
4.final类不能被继承,但是可以创建对象
5.类不被final修饰,但是类中的方法是final修饰,则该方法不可被重写,但是可以被继承
6.如果一个类已经被final,其中的类内方法就不需要被final修饰,因为类已经不能被继承了,方法就不可能被重写, 因此不需要用final修饰
7.构造器不允许被final修饰
8.final和static通常搭配使用,效率更高,不会导致类被加载public class A{ public static void main(String[] args) { AA a = new AA(); System.out.println(a.name); System.out.println(a.age); } } class AA { public final static String name = "am"; public static int age = 18; static{ System.out.println("haha"); } }9.包装类和String都是final修饰,不可被继承
抽象类
引出抽象类:如果父类的一些方法不能确定,或者说你实现了方法体但是并没有什么意义,可以考虑将该方法用abstract修饰为抽象方法,抽象方法就是没有方法体的方法,当一个类中存在抽象方法时,就需要将该类用abstract修饰为抽象类,一般来说,抽象类会被继承,其抽象方法由子类实现 【抽象类的更多作用在于设计,在设计者设计好之后,由子类继承实现】
细节:
1.抽象类不能被实例化
2.抽象类可以没有抽象方法,如果一个方法为抽象方法,则包含该方法的类就必须为抽象类
3.abstract只能用来修饰类和方法,不能用来修饰属性和其他
4.抽象类可以有任意成员(抽象类还是类),比如非抽象方法,静态属性,构造器
5.抽象方法不能有主体, abstract public int kk(){}; × abstract public int kk(); √ 相反的对于非抽象方法就必须实现方法体
6.如果一个类继承了抽象类,那它就必须实现全部抽象方法,除非他自己也声明为抽象类
7.抽象方法不能被final, private,static来修饰,因为这些关键字修饰的方法都不可以被重写,对于抽象类则不能被final修饰【static修饰的方法属于类成员,不能被重写,只能被重新定义】
模板设计模式【抽象类最佳实践】
抽象类作为子类的模板,当功能内部一部分实现是确定的一部分是不确定,则将不确定的方法暴露给子类,让其实现。编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或者多个抽象方法留给子类让其实现,就是模板设计模式
需求:有多个类完成不同的任务,要求统计出各自完成任务的时间:
package example12; abstract class Template { abstract public void job(); public void currenttime(){ Long start = System.currentTimeMillis(); job();//动态绑定机制 Long end = System.currentTimeMillis(); System.out.println("任务执行时间:" + (end - start)+ "毫秒"); } } class A extends Template{ @Override public void job() { int k = 0; for (int i = 0; i < 1000000; i++) { k ++; } } } class B extends Template{ @Override public void job() { int k = 0; for (int i = 0; i < 9000000; i++) { k ++; } } }//测试类 public class test { public static void main(String[] args) { A a = new A(); B b = new B(); a.currenttime(); b.currenttime(); } }
接口 :给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再把这些方法实现
在jdk7.0之前,接口中的方法都没有实现,没有方法体,即都是抽象方法
jdk8.0后,接口中可以有静态方法,默认方法(default),就是说可以有方法的具体实现。
public interface inface { //写属性 属性都是默认public static final修饰,所以必须赋初值 int age = 10; //写方法,抽象方法可以省略abstract关键字 public void job(); //默认方法 default修饰, jdk8 后 default public void say(){ System.out.println("say"); } //静态方法,jdk8 后 public static void say1(){ System.out.println("say1"); } }
注意事项和相关细节:
1.接口不能被实例化
2.接口中的所有方法都是public,其抽象方法可以不用abstract修饰
3.一个普通类实现接口,必须实现全部抽象方法
4.抽象类实现接口,可以不用实现方法
5.一个类可以实现多个接口
6.接口中的属性都是默认public static final修饰,所以必须赋初值。
7.接口中的属性的访问形式:接口名.属性名
8.一个接口不能继承其他的类,但是可以继承多个别的接口
9.接口的修饰符只能是public或者默认
10.接口具有多态特性,接口A的引用可以指向其实现类的对象,同时接口多态还具有传递性,如果该接口A继承了接口B则可以让接口B的引用指向接口A实现类的对象。
11.假如: class B extends A implements C, 实现类B访问接口C的属性用 C.变量名,访问A的属性就用super.xx