零基础学JAVA--Day23(final关键字+抽象类及应用模板设计模式)
final关键字
final 可以修饰类、属性、方法和局部变量.
在某些情况下,程序员可能有以下需求,就会使用到final:
1)当不希望类被继承时,可以用final修饰.
2)当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字修饰。
3)当不希望类的的某个属性的值被修改,可以用final修饰.
4)当不希望某个局部变量被修改,可以使用final修饰【案例演示: final doubleTAX RATE=0.08
一些细节
final使用注意事项和细节讨论
1) final修饰的属性又叫常量,一般用大写英文字母来命名
2)final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一【选择一个位置赋初值即可】:
①定义时:如 public final double TAX_RATE=0.08;
②在构造器中
③在代码块中
public final double TAX_RATE
3)如果final修饰的属性是静态的,则初始化的位置只能是:
①定义时②在静态代码块,不能在构造器中赋值。
4)final类不能继承,但是可以实例化对象是可以的。
如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承。
5)一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法。
6)final不能修饰构造方法(即构造器)
7)final和static往往搭配使用,效率更高,底层编译器做了优化处理。
//主程序调用
Systom.out.println(BBB.num);//情况一
class BBB {public static int num = 10000;//静态变量不被final修饰static{System.out.println("BBB静态代码块被执行");}
}//输出
BBB代码块被执行
10000=>会导致静态代码块执行//情况一
class BBB {public final static int num = 10000;//静态变量被final修饰static{System.out.println("BBB静态代码块被执行");}
}//输出
10000=>不会导致静态代码块执行,实现代码优化,效率提升7)包装类,String类都是final类
抽象类
当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类。
class Animal {private String name;public Animal(string name){this.name = name;}//思考:这里eat这里你实现了,其实没有什么意义//即:父类方法的不确定性public void eat(){Systom.out.println("动物吃东西,但吃什么不知道")}
}//改为抽象类和抽象方法abstract class Animal {private String name;public Animal(string name){this.name = name;}//抽象方法//由子类实现具体的eat方法public abstract void eat();
}抽象类的介绍
1)用abstract关键字来修饰一个类时,这个类就叫抽象类
访问修饰符 abstract 类名();
2)用abstract关键字来修饰一个方法时,这个方法就是抽象方法
访问修饰符 abstract 返回类型 方法名(参数列表) ;//没有方法体
3)抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类
4)抽象类,是考官比较爱问的知识点,在框架和设计模式使用较多
抽象类的细节
1)抽象类不能被实例化,不能被new
2)抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
3)一旦类包含了abstract方法,则这个类必须声明为abstract
4)abstract只能修饰类和方法,不能修饰属性和其它的
5)抽象类可以有任意成员【抽象类还是类】,比如:非抽象方法、构造器、静态属性等等
6)抽象方法不能有主体,即不能实现,如图所示

7)如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类。

8)抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的。本质上抽象类的存在就是为了子类或者其他,对其重写,使得方法更加灵活,而上述关键字抑制了方法重写的性质,与抽象类相违背。
抽象类的最佳实践---模板设计模式
优化前
package com.abstractDetail;public class Job {public static void main(String[] args) {AA aa = new AA();BB bb = new BB();aa.jobaa();bb.jobbb();}
}class AA{public void jobaa(){long start = System.currentTimeMillis();//记录程序开始时间long num = 0;for (int i = 1; i < 10000000; i++) {num+=i;}long end = System.currentTimeMillis();//记录程序结束时间System.out.println("AA执行时间为"+(end-start));}
}public class BB {public void jobbb() {long start = System.currentTimeMillis();//记录程序开始时间long num = 0;for (int i = 1; i < 10000000; i++) {num *= i;}long end = System.currentTimeMillis();//记录程序结束时间System.out.println("BB执行时间为" + (end - start));}
}//问题:代码冗余,重复代码太多需要优化
优化后
//创建一个父类,用于存放模板
public abstract class TimeTemple {public abstract void job();public void time() {long start = System.currentTimeMillis();//记录程序开始时间job();//这里放抽象方法便于子类对其重写,同时动态绑定,找子类的重写long end = System.currentTimeMillis();//记录程序结束时间System.out.println("执行时间为" + (end - start));}
}//AA和BB都继承父类,并且按照各自的任务重写job方法
package com.abstractDetail;class AA extends TimeTemple {@Overridepublic void job() {//实现了父类的抽象job方法long num = 0;for (int i = 1; i < 10000000; i++) {num += i;}}
}package com.abstractDetail;public class BB extends TimeTemple {@Overridepublic void job() {long num = 1;for (int i = 1; i < 100000; i++) {num *= i;}}
}//测试
package com.abstractDetail;public class Job {public static void main(String[] args) {AA aa = new AA();BB bb = new BB();aa.time();bb.time();}
}________________________________________
Day23 End
整个课程已经过半了,说实话,掌握的可能还是比较欠,这两周应该是我这学期最忙的时候,很多考试,还要对论文进行复现,这些都没学,还要健身......加油吧!
离回家还有67天~
