给实验室干了好几天活,之后还要干,影响了一波进度。。。
=========================================================================
抽象模板模式
public class TestTemplate {
public static void main(String[] args) {
AA aa = new AA();
aa.caleTimes();
}
}
//====================================================
public abstract class Template { //抽象类-模板设计模式
public abstract void job(); //抽象方法
public void caleTimes() { //统计耗时多久
long start = System.currentTimeMillis();
job();
long end = System.currentTimeMillis();
System.out.println("执行时间" + (end - start));
}
}
//====================================================
public class AA extends Template {
public void job() { //重写Template的job方法
long num = 0;
for (int i = 0; i <= 100000; i++) {
num += i;
}
}
}
接口
接口就是给出一些没有实现的方法封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。
interface 接口名 {
//属性
//方法
}
class 类名 implements 接口 {
自己属性
自己方法
必须实现接口的抽象方法
}
1. 在Jdk7.0以前,接口里所有方法都是方法体,即抽象方法
2. Jdk8.0后接口可以有静态方法,默认方法,也就是接口中可以有方法的具体实现,需要使用default关键字,也可以使用静态方法
在接口中,可以省略abstract关键字
细节:
1. 接口不能被实例化
2. 接口中所有的方法都是public方法,抽象方法可以不用abstract修饰
3. 一个普通类实现接口,就要把该接口的所有方法都实现,使用Alt+Enter快速实现
4. 抽象类实现接口,可以不用实现接口里的方法
5. 一个类同时可以实现多个接口
6. 接口中的属性,只能是final的,而且是public static final修饰符(必须初始化)
7. 接口中属性的访问形式:接口名.属性名
8. 接口不能继承其他的类,但是可以继承多个别的接口
9. 接口的修饰符只能是public和默认。这点和类的修饰符一样
当子类继承父类,就自动拥有父类的功能
如果子类需要扩展功能,可以通过实现接口的方式扩展
可以理解实现接口是对java单继承机制的一种补充
继承的价值:解决代码的复用性和可维护性
接口的价值:设计好各种规范,让其他类去实现这些方法,即更加灵活
接口在一定程度上实现代码解耦[即 接口的规范性+动态绑定]
接口的多态
接口类型的变量 可以指向 实现了接口的类的对象实例
调用类的方法 可以向下转型
多态传递
例:IG继承IH接口,Teacher类实现IG接口,那么实际上相当于也实现IH接口
接口和父类都有x :用A.x 和 super.x
内部类!!!
一个类的内部嵌套了完整的类结构,被嵌套的类叫内部类
class Outer {//外部类
class Inner{ //内部类
}
}
class Other {//外部其他类
}
内部类的最大特点就是可以访问私有属性
可以体现类的包含关系
类的五大成员方法:属性、方法、构造器、代码块、内部类
内部类分类
定义在外部类局部位置上(比如方法内)
1. 局部内部类(有类名)
2. 匿名内部类(没有类名!!!!!)
定义在外部类成员位置上
1. 成员内部类(没有static修饰)
2. 静态内部类(有static修饰)
局部内部类
1. 可以访问外部类的所有成员,包括私有
2. 定义在外部类的局部位置,通常是方法
3. 不能添加访问修饰符,但是可以用final修饰,本质是一个类
4. 作用域:仅仅在他的方法或代码块中
5. 局部内部类可以直接访问外部类的成员
6. 外部类在方法中可以创建对象再访问(必须在作用域内)
7. 外部其他类不能访问局部内部类(局部内部类实际是局部变量)
8. 如果外部类和局部内部类成员重名时,遵循就近原则
如果想访问外部类成员,使用外部类名.this.成员去访问(本质是外部类的一个对象,即调用方法的)
匿名内部类!!!
(1)本质是类(2)内部类(3)该类没有名字(4)同时还是一个对象
基本语法
new 类或接口(参数列表) {
类体
};
public class AnonymousInnerClass {
public static void main(String[] args) {
Outer05 outer05 = new Outer05();
outer05.f1();
}
}
class Outer05 {
private int n1 = 5;
public void f1() {
//1. 创建一个基于类的匿名内部类
Person p = new Person() {
@Override
public void hi() {
System.out.println("匿名内部类重写hi方法");
}
};
p.hi();
//2. 也可以直接调用
new Person() {
@Override
public void hi() {
System.out.println("匿名内部类重写hi方法,哈哈哈");
}
}.hi();
}
}
class Person {
public void hi() {
System.out.println("Person hi()");
}
}
可以访问外部类的所有成员,包括私有
不能添加修饰符,因为它是局部变量
作用域:仅仅在定义它的方法和代码块中
匿名内部类可以访问外部类,外部其他类不能访问匿名内部类
重名遵守就近,想访问外部类成员,使用外部类名.this.成员
接口:外部类$1
类:外部类$2
public class AnonymousInnerClass02 {
public static void main(String[] args) {
CellPhone cellPhone = new CellPhone();
cellPhone.alarmClock(new Bell() {
@Override
public void ring() {
System.out.println("懒猪起床了");
}
});
cellPhone.alarmClock(new Bell() {
@Override
public void ring() {
System.out.println("小伙伴上课了");
}
});
}
}
interface Bell {
void ring();
}
class CellPhone {
public void alarmClock(Bell bell) {
bell.ring();
}
}
成员内部类
成员内部类是定义在外部类的成员位置,并且没有static修饰
1. 可以直接访问外部类的所有成员,包括私有的
2. 可以添加任意访问修饰符,因为本身就是成员
3. 作用域:在整个外部类体中
4. 成员内部类可以直接访问外部类成员,包括私有的
5. 外部类访问成员内部类:创建对象再访问
6. 外部其他类访问成员内部类:
(1)把new 内部类()当做外部类对象的成员
外部类.内部类.xx = 外部类对象.new 内部类();
Outer outer = new Outer();
Outer.Inter inner = outer.new Inner();
(2)在外部类中编写一个方法,可以返回内部类对象
public Inner getInnerInstance() {
return new Inner();
}
Outer.Inter inner = outer.getInnerInstance();
7. 重名遵循就近原则,同理用this
静态内部类
静态内部类是定义在外部类的成员位置,并且有static修饰
1. 可以直接访问外部类的所有静态成员,包括私有的,但不能直接访问非静态成员
2. 可以添加任意访问修饰符,因为它是成员
3. 作用域:整个类体
4. 静态内部类访问外部类:直接访问所有静态成员
5. 外部类访问静态内部类:创建对象再访问
6. 外部其他类访问静态内部类
(1)静态内部类通过类名直接访问,,前提满足访问权限(不能private)
Outer.Inner inner = new Outer.Inter();
(2)编写一个方法,返回静态内部类的对象实例
public (static) Inner getInner() {
return new Inner();
}
//Outer outer = new Outer();
//Outer.Inner inner =outer.getInner();
Outer.Inner inner = Outer.getInner();
7. 重名就近原则,访问外部类,用外部类.成员(不用this)
枚举
1. 构造器私有化
2. 本类内部创建对象
3. 对外暴露对象(public final static)
4. 可以提供get,不能提供set
public class Enumeration01 {
public static void main(String[] args) {
System.out.println(Season.SPRING);
System.out.println(Season.AUTUMN);
}
}
class Season {
private String name;
private String desc;
//定义了4个对象
public static final Season SPRING = new Season("春天","温暖");
public static final Season SUMMER = new Season("夏天","炎热");
public static final Season AUTUMN = new Season("秋天","凉爽");
public static final Season WINTER = new Season("冬天","寒冷");
//1. 将构造器私有化,防止直接new
//2. 去掉setXXX方法,防止属性被修改
//3. 在Season内部,直接创建固定的对象
//4. 可以再加入一个final修饰符
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
使用enum关键字实现枚举
public class Enumeration01 {
public static void main(String[] args) {
System.out.println(Season.SPRING);
System.out.println(Season.AUTUMN);
}
}
enum Season {
//1. 使用关键字enum替代class
//2. 常量名(实参列表)
//3. 如果有多个常量 使用,间隔
//4. enum定义枚举 要求定义常量对象 写在前面
//定义了4个对象
SPRING("春天","温暖"),
SUMMER("夏天","炎热"),
AUTUMN("秋天","凉爽"),
WINTER("冬天","寒冷");
private String name;
private String desc;
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
1. 当我们使用enum关键字开发一个枚举类,默认继承Enum类,而且是一个final类
2. 必须知道调用哪个构造器
3. 如果使用无参构造器创建枚举对象,则参数列表和小括号都可以省略
4.当有多个枚举对象要有逗号间隔,最后带分号
5. 枚举对象必须放在枚举类的行首
枚举类方法
public class EnumMethod {
public static void main(String[] args) {
Season autumn1 = Season.AUTUMN;
//输出枚举对象的名称
System.out.println(autumn1.name());
//输出该枚举对象的次序 从0开始编号
System.out.println(autumn1.ordinal());
//从反编译可以看到values方法 返回Season[]
//含有定义的所有枚举对象
Season[] values = Season.values();
for (Season season: values) { //增强for循环
System.out.print(season + " ");
}
System.out.println("\n=========================");
//将字符串转成枚举对象 要求字符串必须为已有常量名 否则报错
Season autumn2 = Season.valueOf("AUTUMN");
System.out.println(autumn2);
//比较两个枚举常量 前-后
System.out.println(Season.AUTUMN.compareTo(Season.SUMMER));
}
}
使用enum关键字后就不能继承其他类,因为enum会隐式继承Enum。而Java是单继承
enum实现的枚举类依然是一个类,所以还是可以实现接口
enum 类名 implements 接口{}
注解 (Annotation)
又称为元数据,用于修饰包、类、方法、属性、构造器、局部变量等数据信息
1) @Override:限定某个方法,是重写父类方法,该注解只能用于方法
2) @Deprecated: 用于表示某个程序元素(类,方法等)已过时
3) @SuppressWarnings:抑制编译器警告
1. @Override 注解放在fly方法上,表示子类的fly方法时重写了父类的fly
2. 这里如果没有写 @Override 还是重写了父类fly
3. 如果你写了@Override注解,编译器就会去检查该方法是否真的重写了父类的方法,如果的确重写了,则编译通过,如果没有构成重写,则编译错误
4. @Override只能修饰方法
如果发现 @interface表示注解类
@Target 修饰注解的注解称为元注解
1. @Deprecated 修饰某个元素,表示该元素已经过时
2. 即不在推荐使用,但是仍然可以使用
3.查看@Deprecated 注解类的源码
4. 可以修饰方法,类,字段,包,参数等等
5. @Deprecated 可以做版本升级过渡使用
1. 当我们不希望看到这些警告的时候,可以使用SuppressWarnings注解来抑制警告信息
2. 在{" "}中,可以写入你希望抑制(不显示)警告信息
3. 可以指定的警告类型有...~
4. 关于SuppressWarnings作用范围和放置的位置相关
@SuppessWarnings({"all"})
JDK的元Annotation
1. Retention//指定注解作用范围,三种SOURCE,CLASS,RUNTIME
2. Target//指定注解可以在哪些地方使用
3. Documented//指定该注解是否在javadoc中体现
4. Inherated//子类会继承父类注解