一.抽象类和抽象方法
1.抽象方法
使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
2.抽象类
包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
3.看看具体实现
1 | /** |
4. 抽象类的注意事项:
1. 抽象类也可以定义普通的字段属性
2. 抽象类可以包含构造方法,但是我们不能调用这个构造方法,会报错
3. 如果一个类中有抽象方法,那么这个类一定是抽象类
4. 抽象类中可以有普通方法,就跟我们平常的类一样
二.接口
1.为什么需要接口?接口和抽象类的区别?
接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。抽象类还提供某些具体实现,接口不提供任何实现,接口中所有方法都是抽象方法。接口是完全面向规范的,规定了一批类具有的公共方法规范。
接口和实现类不是父子关系,是实现规则的关系。比如:我定义一个接口Runnable,Car实现它就能在地上跑,Train实现它也能在地上跑,飞机实现它也能在地上跑。就是说,如果它是交通工具,就一定能跑,但是一定要实现Runnable接口。
接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。
### 2.如何定义和使用接口?
#### 2.1 声明格式
1 | [访问修饰符] interface 接口名 [extends 父接口1,父接口2…] { |
#### 2.2 定义接口的详细说明
1. 访问修饰符:只能是public或默认。
2. 接口名:和类名采用相同命名机制。
3. extends:接口可以多继承。
4. 常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。
5. 方法:接口中的方法只能是:public abstract。 省略的话,也是public abstract。
#### 2.3 注意
1. 子类通过implements来实现接口中的规范。
2. 接口不能创建实例,但是可用于声明引用变量类型。
3. 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
4. JDK1.7之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。
5. JDK1.8后,接口中包含普通的静态方法。
#### 2.4 具体使用
1 | /** |
#### 2.5 接口的多继承
1 | /** |
## 三.内部类
一般情况,我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类的内部定义,称为内部类(innerclasses)。
内部类可以使用public、default、protected 、private以及static修饰。而外部顶级类(我们以前接触的类)只能使用public和default修饰。
内部类只是一个编译时概念,一旦我们编译成功,就会成为完全不同的两个类。对于一个名为Outer的外部类和其内部定义的名为Inner的内部类。编译完成后会出现Outer.class和Outer$Inner.class两个类的字节码文件。所以内部类是相对独立的一种存在,其成员变量/方法名可以和外部类的相同。
1 | /**外部类Outer*/ |
1.内部类分类
在Java中内部类主要分为成员内部类(非静态内部类、静态内部类)、匿名内部类、局部内部类。
2.成员内部类
成员内部类(可以使用private、default、protected、public任意进行修饰。 类文件:外部类$内部类.class)
2.1 非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)
- 非静态内部类必须寄存在一个外部类对象里。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象。
- 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员。
- 非静态内部类不能有静态方法、静态属性和静态初始化块。
- 外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。
成员变量访问要点:
- 在内部类中访问内部类里方法的局部变量:直接写变量名即可。
- 在内部类中访问内部类属性:要写this.变量名。
- 在内部类中访问外部类属性:要写外部类名.this.变量名。
1 | /** |
2.2 静态内部类
定义方式:
1 | static class ClassName { |
注意:
- 当一个静态内部类对象存在,并不一定存在对应的外部类对象。 因此,静态内部类的实例方法不能直接访问外部类的实例方法。
- 静态内部类看做外部类的一个静态成员。 因此,外部类的方法中可以通过:“静态内部类.名字”的方式访问静态内部类的静态成员,通过 new 静态内部类()访问静态内部类的实例。
1 | package yp.JavaSE.Review_05; |
3.匿名内部类
适合那种只需要使用一次的类。比如:键盘监听操作等等。
语法:1
2
3new 父类构造器(实参类表) \实现接口 () {
//匿名内部类类体!
}
匿名内部类的使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/**
* @author RickYinPeng
* @ClassName Test_08_anonymousInnerClass
* @Description 测试匿名内部类
* @date 2019/1/19/15:51
*/
public class Test_08_anonymousInnerClass {
public static void main(String[] args) {
Test_08_anonymousInnerClass.test01(new A() {
@Override
public void aa() {
System.out.println("匿名内部类");
}
});
}
public static void test01(A a){
a.aa();
}
}
interface A{
void aa();
}
注意:
- 匿名内部类没有访问修饰符。
- 匿名内部类没有构造方法。因为它连名字都没有那又何来构造方法呢。
4.局部内部类
还有一种内部类,它是定义在方法内部的,作用域只限于本方法,称为局部内部类。
1 | public class Test2 { |