- 抽象类
父类的某些方法需要声明,但是又不确定实现时,就可以声明为抽象方法,这个类就是抽象类。
抽象方法没有方法体。
抽象类不能被实例化。
抽象类不一定包含抽象方法。但一旦包含抽象方法,就一定要声明为抽象类。
abstract只能修饰类和方法,不能修饰属性和其他的。
抽象类本质还是类,可以有任意成员。
一个类继承了抽象类,必须要实现抽象类的所有抽象方法,除非自己也声明为抽象类。
抽象方法不能使用private、static、final来修饰,因为这些关键字都是和重写相违背的。 - 接口
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用时,再根据具体情况把这些方法写出来。
interface 接口名 {
void hi();
}
class 类名 implements 接口{
}
- Jdk7.0之前,接口里所有的方法都没有方法体,都是抽象方法。
- Jdk8.0之后,接口里可以有静态方法、默认方法,可以有方法的具体实现。
- 接口中抽象方法可以省略abstract关键字。
- 接口不能被实例化。
- 接口中所有方法是public方法。
- 一个普通类实现接口,必须将接口的所有方法实现。
- 抽象类实现接口,可以不用实现接口的方法。
- 一个类同时可以实现多个接口。
- 接口中的属性只能是final的,而且是public static final 修饰符,且必须初始化。
- 接口中的属性访问形式:接口名.属性名
接口不能继承其他的类,但是可以继承多个别的接口
。- 接口的修饰符只能是public和默认,这点和类的修饰符是一样的。
- 实现接口是对java单继承机制的扩展。
- 接口vs继承
- 解决的问题不同
继承在于解决代码的复用性和可维护性
接口在于设计好各种规范和方法,让其他类实现这些方法,更加地灵活。
接口比继承更加灵活。继承是is - a的关系,接口是like - a的关系
接口在一定程度上实现代码解耦(接口规范性 + 动态绑定)
- 接口的多态体现
- 接口类型的变量可以指向实现了接口的对象实例。
- 多态数组,可以通过判断运行类型instanceof,运行接口实现类特有的方法。
- 多态传递:某一接口继承了多个接口,这些被继承的接口都可以指向实现该接口的类实例。
- 类的五大成员:成员属性、成员方法、构造方法、代码块、内部类
- 内部类
class Outer{ // 外部类
class Inner{ // 内部类
}
}
class Other{ //其他类
}
内部类最大的特点是可以直接访问私有属性,并且可以体现类与类之间的包含关系。 - 内部类的分类有4种
- 定义在外部类的局部位置上(比如方法内)
- 定义在外部类的成员位置上(属性或方法位置上)
- 成员内部类(没有static修饰)
- 静态内部类(用static修饰)
- 局部内部类
- 定义在外部类的局部位置上,比如方法内,相当于一个局部变量
- 不可以添加访问修饰符,但是不想被继承, 可以使用final修饰
- 作用域仅仅在定义它的方法或代码块中
- 可以直接访问外部类的成员
- 外部类访问局部内部类的成员:需要先创建对象,再访问,且必须在作用域内
- 总结:1. 定义在方法体/代码块中。2. 作用域在方法体中/代码块内。3. 局部内部类本质上还是一个类
- 局部内部类02
- 外部类和局部内部类的成员重名时,默认遵循就近原则。
- 如果想访问外部类的成员,使用
外部类名.this.成员名
去访问
- 匿名内部类
- 本质是类
- 是内部类
- 该类没有名字
- 同时还是一个对象
基本语法:
new 类或接口或抽象类(参数列表){
类体
} - 匿名内部类只会使用一次,后面不再使用,使用匿名内部类简化开发
- 要注意编译类型和运行类型,编译类型是等号左边的类/接口修饰符,运行类型是匿名内部类,使用getclass查看
- 底层会分配类名:外部类名+$+num
- 匿名内部类使用一次就不可以再使用,返回的实例可以多次调用
- 匿名内部类细节
- 可以直接访问外部类的所有成员,包括私有成员,访问外部类成员直接访问
- 不能添加访问修饰符,因为匿名内部类本身就是一个局部变量
- 外部其他类不能访问匿名内部类
- 外部类和局部内部类的成员重名时,默认遵循就近原则。
- 如果想访问外部类的成员,使用
外部类名.this.成员名
去访问
- 成员内部类
- 定义在外部类的成员位置上
- 可以添加任意访问修饰符(public、protected、默认、private),因为地位就是一个成员
- 外部其他类使用成员内部类的两种方式
第一种方式:
- 先实例化外部类:Outer outer = new Outer()
- Outer.Inner inner = outer.new Inner()
第二种方式: - 外部类中编写一个方法,返回内部类的实例对象
- 成员重名时,遵循就近原则,需要访问外部类成员时,使用外部类.this.成员名;
- 静态内部类
- 写在外部类的成员位置上,使用static修饰
- 只能访问静态成员
- 外部类访问静态内部类
第一种方式:
- Outer.Inner inner = new Outer.inner();
第二种方式: - 编写一个方法,访问静态内部类的对象实例