概要
这一章的复习主要涵盖 抽象类,接口,作用域,内部类 尤其是 匿名内部类的性质。这里整理的都是个人觉得比较重要重新认真分析的东西,不一定全部为基础,如果有不准确的地方,还望大佬从评论区指出,感激不尽。
文章中的所有的自定义的测试都在自己的 java-review
仓库中,本文对应的链接:
抽象类和抽象方法
抽象类中可以没有抽象方法,但有抽象方法的类必须是抽象类
- 抽象类和普通的类,在继类的承和接口的实现上的规范是基本相同的,都采用 单继承
abstract
关键字可以指定一个类或方法为抽象的,表示类或方法不完整,使得必须- 子类继承抽象类
- 重写方法 (因为必须重写,所以方法必须暴露给子类,所以不能使用
private
修饰,私有化方法就会必须重写暴露给子类矛盾)
- 重写方法 (因为必须重写,所以方法必须暴露给子类,所以不能使用
- 抽象类无法直接创建对象实例
接口
接口的性质
接口中的方法
- 接口中的方法的权限都是
public
- 在实现接口的时候,根据方法重写的规则,必须将方法的权限设置为
public
接口中的成员变量
interface
产生一个 完全抽象的类,它内部的所有的方法必须都是抽象的,所有成员变量都是public static
default
jdk 8
的新特性中,default
关键字可以在接口中中添加默认方法,default
关键字 只能用于接口中,该方法为 非静态方法,只有通过实例对象才能访问
接口的 default
方法的性质测试
1 | // test |
default
和普通类中的非静态方法基本一致default
方法可以被接口的抽象方法所覆盖
接口嵌套
- 接口的默认修饰为
static
,注意是是接口的修饰,而不是接口内部的属性 - 又因为接口内部的成员变量都是
public static
,所以接口的嵌套就很理所当然
1 | // test |
接口继承和实现
- 接口使用
extends
来继承其他接口,完成接口的组合,接口支持多继承 - 一个 类/抽象类 可以
implements
实现多个接口
测试接口的继承和实现
1 | // test |
测试的情况
- 接口多继承中有重复的方法
- 抽象方法之间重复
default
默认方法之间重复- 抽象方法 和
default
默认方法之间的重复
- 类/抽象类实现多个接口 ,接口中存在重复方法的情况
- 抽象方法之间重复
default
默认方法之间的重复- 抽象方法 和
defautl
方法之间重复
结论
但凡是存在 default
方法冲突的时候,必须重写该方法
- 接口继承的冲突中,实现继承的接口中,重写为 抽象 和
default
方法 均可 - 类/抽象类实现多个接口出现冲突的时候,类必须重写为类的非静态方法,抽象类 还可以重写为 抽象方法
作用域
作用域级别 | 区域的位置 |
---|---|
类级 | 类的 static 变量 |
对象实例级 | 成员变量 |
方法级 | 方法内部 |
块级 | 块内部的声明周期,比如 if 等大括号包围的区域 |
1 | // test |
其实我感觉应该都是块级的作用域…
无非就是括号的范围造成的影响除了成员变量级之外,作用域以外都不能使用该作用域内部的变量
内部类
下面所有的所有的类中,除了匿名内部类意外,其他的所有的内部类,都和普通的类一样,可以寄继承其他的类/抽象类,实现接口
1 | // test |
作用域内部类
每个 { }
中间的区域其实都是一个域,只不过通常将除了类的域以外的,都称为 局部
成员内部类
作为 类成员变量 中
- 一个类或者抽象类声明在了另一个类的内部,此时他就相当于一个类的内部成员变量
- 使用
static
关键字可以使它和外部类断开联系独立出来,通过new OutClass.InnerClass()
就可以访问
局部内部类
方法内部 或者 作用域(包括 方法内部,初始化块,静态代码块) 中
匿名内部类
- 匿名内部类同样可以使用 带有参数的构造器 进行初始化
- 匿名内部类中就不能自定义构造器了,但是可以直接使用所在的外部域的属性进行初始化
匿名内部类测试
1 | public class Anonymous { |
创建匿名内部类相当于实现、继承的作用,访问成员变量和方法的时候跟前面 继承中访问成员变量和方法 的情况是完全一致的,区别只是创建出的这个类,没有一个具体名字的而已
直接使用 匿名内部类 访问,相当于
1
2
3SubClass subClass = new SubClass();
subClass.xxx;
subClass.xxx();使用了 被实现的类型 作为引用,相当于
1
2
3
4/* 仅能访问父类中已有的成员变量和方法 */
SuperClass superClass = new SubClass();
superClass.xxx;
superClass.xxx();
默认访问对象
这里使用 父类引用 和 子类引用 来描述,因为匿名内部类的话我不知道该怎么描述
- 重写的方法。 不管是使用父类引用还是子类引用,都默认调用子类中重写的方法
- 成员变量。 父类引用和子类引用两者不冲突不会覆盖,通过对应的类型调用对应的成员变量