一、抽象类
1.abstract修饰的方法/类 public abstract void work();
2. 方法体中没有东西,子类必须重写(统一)
3. 类中有抽象方法,这个类必须也为抽象类
4. 注意事项:
(1)抽象类不能实例化(实例化:创建对象)
(2)抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
(3)可以有构造方法(作用:当子类创建对象的时候,给属性赋值的)
(4)抽象类的子类:要么重写抽象类中的所有抽象方法,要么是抽象类
二、接口
1. 父类:整个体系的共性 接口:某几个类的共同方法
2. 接口就是一种规则,是对行为的抽象
3.使用规则:
(1)接口用关键字interface来定义 public interface 接口名{}
(2)接口不能实例化
(3)接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名 {}
(4)接口的子类(实现类)要么重写接口中的所有抽象方法、要么是抽象类
(如果两个接口中的方法重名,不用重复重写)
注意1:接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名1,接口名2 {}
注意2:实现类还可以在继承一个类的同时实现多个接口。
public class 类名 extends 父implements 接口名1,接口名2 {}
4. 成员变量:只能是常量、默认修饰符:public ststic final
没有构造方法
成员方法:只能是抽象方法、默认修饰符:public abstract
5. 接口和接口之间的关系:继承(可单可多)
6. 调用接口中的方法: Inter.show();
调用实现类中重写的方法: ii.show();
7. JDK8之后:可以在接口中定义有方法体的方法了,这样避免每次在接口中添加功能,在它的每 个实现类中都要重写新增的方法
①默认方法default修饰 当两个接口中的方法重名时,就必须重写了
②静态方法static修饰 不能重写
③私有方法private修饰 (JDK9)
private void show(){} 给默认方法使用的
静态私有方法private static void show(){} 给静态方法使用的
8. 适配器Adapter
其实就是在接口和实现类中间加了第三者(Adapter实现Inter,Impl继承Adapter)
作用:简化代码,易于阅读
补充:Adapter写成抽象类,避免被创建对象(没有意义)
三、内部类
1. 在类的内部创建的类,叫内部类 (举例:Car 内部类Engine)
2. 内部类可以直接使用外部类的成员,包括私有
而外部类不能直接使用内部类的成员,必须先创建对象
3. 分类:
(1)成员内部类
写在成员位置的,属于外部类的成员(它和外部类中其他成员地位相同)
1.Outer.Inner oi = new Outer().new Inner();
2. Outer.this 外部类的地址值 this 内部类的地址值
(2)静态内部类
用static修饰的,他只能访问外部类的静态变量/方法,
如果要访问非静态的,需要创建外部类的对象
1. Outer.Inner oi = new Outer.Inner();
(3)局部内部类
定义在方法里面的
1. 外界无法直接使用局部内部类,需要在方法内部创建对象并使用
2. 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
(4)匿名内部类:
隐藏了名字的内部类(看P143)(一般用于测试类中)
new 类名或接口名(){
· 重写方法
};
其实他是匿名内部类的对象 { }里面的才是真正的匿名内部类
理解:为什么要用匿名内部类?
如果想重写接口中的方法,需要新建一个类再实现接口,再重写 如果我只想用一次,就没 必要这么麻烦
可以在Test类中,写一个匿名内部类并创建它的对象
public class Test { public static void main(String[] args) { /** * 要实现method方法, * 以前的方法: * 创建一个Dog类,让Dog类继承Animal,然后在Test类中,创建Dog类的对象 * 再把这个对象传递给method,去调用method方法 */ // Dog d = new Dog(); // method(d); /** * 用匿名内部类: * * { }中是匿名内部类, * 它继承了Animal类,并且重写了Animal类中的方法 * new Animal(){} 表示:创建了这个类的对象 相当于上面的 d * 然后把这个对象当作参数传递到 method方法中 * Animal a = 子类的对象 形成了多态 */ method( new Animal(){ @Override public void eat() { System.out.println("狗吃骨头"); } } ); } public static void method(Animal a) { a.eat(); } }
补充:
1. 可以把这个对象赋值给Swim类型的一个变量s --> 接口多态
Swim s = new Swim(){
重写方法;
};
2. 用这个对象调用方法
new Swim(){
重写方法;
}.swim(); 它调用了自己类里面的方法