抽象类
- 抽象类的由来是,当多个子类都有同一种行为,但是行为的具体内容又不完全一样,就是希望,父类不定义具体的方法体,但是子类必须重写父类的方法,这种需求就诞生了抽象方法,抽象方法是没有方法体的,但是非抽象的子类,必须重写父类的抽象方法
- 要注意,有抽象方法的类,一定是抽象类,而抽象类不一定有抽象方法
- 抽象类不可以被实例化
- 抽象类是可以有构造方法的,需要子类调用父类的构造方法,完成对父类的成员变量初始化
- 抽象类可以被抽象类继承,这种情况可以不用重写父类的抽象方法
- 但是非抽象类继承了抽象类后,必须重写父类的所有抽象方法
接口
- 接口的由来是,多个类共有的行为,但是这些类不属于某个大类,但是希望以相同的规则定义共有行为,此时就用到了接口,它其实是定义一种规则。
- 要注意,接口的关键字是interface
- 接口不能被实例化
- 接口如果被抽象类实现,这种情况不用重写接口的抽象方法
- 接口如果被非抽象类实现,必须实现接口的所有抽象方法
- 实现的关键字是implements
- Java是支持多实现的
- Java的继承一个父类的同时,实现多个接口
接口的成员特点
- 成员变量默认都是常量,自动追加public static final前缀
- 成员方法默认都是抽象方法,自动追加public abstract
- 没有构造方法
接口与接口的关系
- 类和类之间是继承关系
- 类和接口之间是实现关系
- 接口与接口之前是继承关系
- 当一个类实现了多个接口,接口中有重复的抽象方法,只需要实现一个
- 当接口继承了接口,类在实现子接口时,需要重写子接口和父接口的所有的抽象方法
接口相关拓展
- JDK7以前,包括JDK7,接口中的方法只有抽象方法,public abstract可以默认不写
- JDK8后,为了在项目过程中,新增接口方法的时候,不需要立即重写,引入的默认方法,public default 返回值类型 方法名(形参){方法体;}
- 默认方法也可以被实现类重写,重写的时候实现类就需要去掉default关键字了
- 如果实现的多个接口中有重名的默认方法,则实现类必须重写默认方法
- JDK8后,接口还引入的静态方法,静态方法的static关键字不可以被省略,接口中的静态方法必须用接口名.方法名调用,无法被重写
- JDK9后,引入了私有方法和私有静态方法,分别是为默认方法和静态方法服务,私有方法提取共同的代码,不被其他类调用
- 接口代表规则,是行为的抽象,类需要哪些行为就实现哪些接口
- 接口多态就是 变量的类型是接口,接收的对象时任意一个实现类,遵从的也是编译看左边,运行看右边
设计模式
- 设计模式是一套惯用的代码编写套路
适配器设计模式
- 场景是一个实现类不想实现xxx接口所有的抽象方法,可以使用适配器设计模式
- 中间抽象类xxxAdapter实现xxx接口,重写的方法默认为空方法体,继承实际实现类的父类,没有则不需要继承
- 实际实现类继承中间抽象类xxxAdapter,对指定的方法再次重写
内部类
- 类的五大成员:属性,方法,构造方法,代码块,内部类
- 内部类是类里面定义的类
- 内部类是外部类的一部分,并且单独存在没有意义,像是汽车的发动机,ArrayList的迭代器,人的心脏等。
- 内部类分为四种成员内部类,静态内部类,局部内部类,匿名内部类
成员内部类
- 成员内部类是定义在外部类中,外部类的方法之外的类
- 成员内部类的对象的创建分为两种情况,当成员内部类是私有的,外部类需要提供一个public方法,返回成员内部类的对象。当成员内部类是非私有的,可以直接创建,外部类.内部类 变量名 = new 外部类().new 内部类();
- 成员内部类的方法如何调用重名的外部类的成员 :外部类.this.成员
- 成员内部类和外部类在加载到元空间的时候,是独立的两部分,具体可以看编译后生成的字节码文件
- 成员内部类的字节码文件名:外部类$内部类.class
- 成员内部类直接创建对象时,外部类会开辟一个堆内存空间,内部类会开辟一个堆内存空间,内部类的堆内存空间会存储一个外部类的地址值,存入this中,内部类的地址值给定义的变量来接收,形成完整的数据连接
静态内部类
- 静态内部类是成员内部类的一种,用static修饰的成员内部类是静态内部类
- 静态内部类中只能访问外部类的静态成员
- 静态内部类的创建: 外部类.静态内部类 变量名 = new 外部类.静态内部类();
- 调用静态内部类中的成员方法,需要先实例化静态内部类,然后调用
- 调用静态内部类的静态方法,格式:外部类.静态内部类.静态成员
局部内部类
- 定义在方法里面的类就是局部内部类
- 局部内部类不可以在方法外被实例化
- 局部内部类相当于局部变量,局部变量可以被什么修饰,局部内部类就可以被什么修饰
- 方法里需要实例化才可以调用局部内部类的方法
- 局部内部类中的方法可以访问外部类的成员和声明好的局部变量
匿名内部类
- 没有名字的内部类是匿名内部类
- 可以定义在成员位置或者是方法内部
- 格式: new 接口名/父类名(){重写方法};
- {重写方法}是实际的匿名类,整体其实是匿名内部类的对象
- 格式细节:包含继承或实现关系,重写方法,创建对象
- 匿名内部类在字节码文件中的名称体现为:外部类$序号.class 序号从1开始
- 使用场景:一个接口或抽象类作为参数,程序只用一次,则不需要定义一个实现类,直接写成匿名内部类对象形式赋值即可,简化代码开发