十、抽象类
- 抽象类不能被实例化;抽象类不一定要包含abstract方法;abstract只能修饰类和方法
- 使用细节1:抽象方法不能有主体
- 使用细节2:一个类继承了抽象类就必须要实现抽象类中所有的方法,除非该子类也是一个抽象类
十一、接口
- 在接口中,方法默认是抽象的,abstract可以省略
- Jdk8之后,接口中的类也可以实现默认方法和静态方法:默认实现方法前面需要添加default;静态方法直接用public static就可以。接着正常些结构体就好
- 如果一个类实现接口需要将接口的所有方法都实现,抽象类实现接口就不用实现所有的方法
- 接口不能被实例化,并且接口中每个类都是public方法
- 接口中的属性:public static final,可以直接用接口名访问(实际上所有静态公共的属性都可以被直接访问)
- 一个类可以实现多个接口
- 接口的作用:子类继承了父类就会自动拥有父类的功能,但是需要给子类扩展功能就需要子类实现接口
- 接口多态的体现:多个类实现了同一个接口,那么有:编译类型(接口)=运行类型(实现接口的类1) 接口=运行类型(实现接口的类2)
- 接口具有多态传递:B类实现A接口,C类继承B类,那么相当于C类实现A接口,C类就能使用接口中的默认和静态方法了
十二、内部类
- 类的五大成员:属性、方法、构造器、代码块、内部类
- 内部类的最大特点:可以之间访问私有属性,体现类和类的包含关系
- 分类:
定义在外部类的局部位置(比如外部类的方法上):
1)局部内部类(有类名)
2) 匿名内部类(Primary.Anonymouslnner ->AnonymousInnerClass_class和AnonymousInnerClass_interface)
IA i1 = new IA(){ //(匿名内部类的写法)IA是接口,cry是匿名内部类实现的接口方法
public void cry(){
System.out.println("小狗汪汪");
System.out.println("小牛哞哞");
}
};
IA i3 = ()-> {System.out.println("小狗汪汪");System.out.println("小牛哞哞");
}(lambda表达式的写法)
i3.cry();
定义在外部类的成员位置上:
3)成员内部类(没用static修饰)
4)静态内部类(使用static修饰)
1)局部内部类特点:
->定义在外部类的局部位置:比如外部类的一个方法中或者外部类的一个代码块中
->可以直接访问外部类的所有成员,包含私有
->不能添加访问修饰符,因为局部类也是一个局部变量,局部变量不允许使用修饰符(public之类的),但是可以用final修饰
->作用域在定义它的方法或代码块中(因为局部内部类相当于局部变量,局部变量的作用域就在定义它的一对花括号里面,在代码块定义的局部变量就只能在代码块中使用,即实例化)
->要访问局部内部类,可以在外部类定义内部类的方法中实例化内部类对象,从而调用内部类的方法和属性
->外部其他类不能访问局部内部类,一个类中的局部变量不允许被其他类访问
->当外部类和局部内部类变量重名的时候,默认就近原则(即在外部类中方法重名属性,那么调用的就是外部类定义的成员),如果要在内部类中为访问外部类,就需要采用“外部类名.this.成员”
->调用方法(内部类通用),直在定义内部类的方法中创建内部类对象,通过内部类对象来调用内部类方法属性,再在主函数中调用外部类的方法即可。
3)成员内部类特点
->将内部类直接写道外部类里面,即直接class Inner01{},不用再放到外部类的方法中使用
->调用方法(内部类通用),给外部类中写一个方法,在该方法中实现创建内部类对象,然后调用内部类方法和属性,再在主函数中调用外部类的方法即可。
->可以任意添加修饰符,因为他就是一个成员
->可以访问外部类的所有成员
->独立类可以访问成员内部类中非私有的方法
->调用方法(成员内部类独有):
- 用一个外部类对象来new一个内部类:Outer01.Inner01 inner02 = outer01.new Inner01();
- 在外部类中写一个方法来返回内部类对象,在独立类中调用该方法
->如果外部类和内部类变量重名,仍遵守就近原则
4)静态内部类特点:
->放在外部类的成员位置并且用static修饰
->只能访问外部类的静态方法和属性
->因为是外部类的成员,因此可以添加权限修饰(public等)
->作用域同其他成员都在整个类体中
->调用方法(内部类通用):在外部类定义一个方法,在方法中new 静态内部类对象,然后用该对象访问方法
->调用方法(静态内部类独有):外部类名.内部类名
十三、异常
- 异常分类:1)错误Eroor(java虚拟机无法解决的严重问题,程序会崩溃)如:JVM内部错误、资源耗尽 2)Exception:其他因为编程错误或者偶然的外在因素导致的一般问题,可以使用针对性代码处理 Exception分为两类:运行时错误和编译时错误
- 异常体系图:
编译时异常举例:
- SQLException//操作数据库查询表时可能出现的错误
- IOException//操作文件时发生的错误
- FileNotFoundException//文件不存在异常
- ClassNotFound//加载类,但是类不存在时发生的异常
- EOFException//操作文件,到文件末尾发生的异常
- IllegalArgumentException//参数异常
- try-catch-finally
try中捕获到异常之后就会立马从该行异常产生代码跳转到catch进行异常处理,若没有异常就不会进入catch,finally无论是否有异常都会执行,一般指定的就是释放资源代码
- try-catch和throws:1)异常处理过程中二选一,但是编译时异常需要显式地在方法签名中使用 throws 关键字声明,而运行时异常不需要(默认有throws操作)(ThrowsTwoType.java) 2)每次throws都会把异常传递给 调用存在异常的方法 的 调用者方法(方法调用方法)3)throws后面可以接多个异常,即接异常处理列表 4)throws后面的异常可以是实际异常,也可以是他的父类 5)子类重写父类的方法时,对抛出的异常的规定:子类重写的方法抛出的类型是父类的异常,或者是其子类
- 如果一段代码有多个异常,可以写多个catch分别捕获,但是注意catch的顺序从上到下,异常的范围得从小到大。
- Try-finally结合使用,并没有捕获处理异常,发生异常直接崩溃,但是可以用来处理一些要求执行完一段代码之后必须执行另一段代码的情况(TryFinally.java)
- 用try-catch实现“循环输入,直到输入的是整数”(TryCatch.java)
- 自定义异常:继承Exception属于编译异常 继承RuntimeException属于运行异常(CustomException.java)一般自定义异常是运行时异常,因为不需要现实指出throw
十四、泛型
- 传统方法的问题:1)不能对放入Arrylist的数据类型进行约束 2)便利的时候需要进行类型转化,当数据量比较大的时候效率会很低(Introduction.java)
- 在类的声明时候class Person<E>{}写进去的泛型,可应用于类内变量,有参构造器的参数以及方法的返回值类型等(Example.java)
- 泛型的声明:interface 接口<T>{} class 类<K,V,T>{} List<E> HashSet<T> HashMap<T,K> (遍历HashMap的时候可以使用.entrySet()->.iterator(),拿到iterator之后,快捷键;itit+回车开始遍历)(Example02.java)
- 在指定泛型的具体类型之后可以传入该类型或者其子类型
- 泛型默认是Object类型
- 自定义泛型:基本形式class 类名<T,R...>
->使用泛型的数组不能初始化,因为数组在new的时候,不能确定类型,就无法分配合适的内存空间
->类中的静态属性和方法不允许使用泛型(静态属性和方法与类有关,因此可能存在类加载了,但是还没有创建类对象(一个例子是通过反射获取类的Class对象。在这种情况下,虽然类已经被加载到内存中,但是并没有显式地创建该类的实例),而类加载的过程中就会激活静态的属性和方法,但是没有个泛型指明具体类型,就无法初始化静态属性和方法的泛型)
- 自定义泛型接口:
->接口中静态成员不能使用泛型(因为接口的属性都是public static final类型的,因此U name;这种接口中的属性也是不被允许的)
->泛型接口的类型是在继承接口或者实现接口的时候指定的
->没有指定类型,默认是Object(class C implements Interface{} 其中Interface是泛型接口,C实现该泛型接口相当于在Interface后面跟着<Object,Object....>)
- 自定义泛型方法:(GenericMethod.java)
->泛型方法可以定义在泛型类中,也可以定义到普通类中
->当泛型方法被调用时,类型会被确定,你传入的参数是什么类型就会将泛型确定为什么类型
->方法使用了类声明的泛型和泛型类不一样 public void say(P p){};
->泛型方法,可以使用类声明的泛型,也可以使用自己方法声明的泛型,但是不允许使用类内未声明并且方法内也未声明的泛型
9、泛型不具备继承关系:List<Object> list = new ArrayList<String>()是不被允许的
10、泛型的继承和通配符:(GenericsAndWildcard.java)
十五、JUnit
可以一个方法一个方法的测试,而且不需要在主函数中写一个方法调用就可以实现方法测试(Junit.java)