多态:意味着允许不同类的对象对同一消息做出不同的响应
编译时多态(设计时多态):通过方法重载实现
运行时多态(Java中的多态):程序运行时动态决定调用哪个方法
必要条件:
满足继承关系
父类引用指向子类对象
向上转型、隐式转型、自动转型:
父类引用指向子类实例,可以调用子类重写父类的方法以及父类派生的方法,无法调用子类独有方法
父类中的静态方法无法被子类重写,所以向上转型之后,只能调用到父类原有的静态方法
向下转型、强制类型转换:
子类引用指向父类对象,此处必须进行强转,可以调用子类特有的方法
必须满足类型条件才能强转
instanceof:左边对象是否是右边类实例,是返回true,否返回false
抽象类:不允许实例化,可以通过向上转型,指向子类实例
应用场景:某个父类只知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。
作用:限制了子类设计的随意性,也避免了无意义父类的实例化
抽象方法:不允许包含方法体,子类中需要重写父类的抽象方法,否则,子类也是抽象类。
static final private不允许被子类重写的方法不能与abstract一起使用
抽象类和抽象方法的使用规则:
- abstract定义抽象类
- 抽象类不能直接实例化,只能被继承,可以通过向上转型完成对象实例
- abstract定义抽象方法,不需要具体实现
- 包含抽象方法的类是抽象类
- 抽象类中可以没有抽象方法
接口:
接口定义了某一批类所需要遵守的规范
接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类里必须提供某些方法。
接口访问修饰符:默认使用public
接口中抽象方法可以不写abstract关键字,无论是接口定义的时候还是接口成员定义的时候,访问修饰符会默认加上public
当类实现接口时,需要去实现接口中的所有抽象方法,否则需要将该类设置为抽象类
接口中可以包含常量,默认会加上public static final
default:接口中的默认方法(jdk1.8后新增) 可以带方法体,其实现类可以不重写该方法(重写的时候static关键字会去掉),可以通过实现类调用。通过接口的引用调用:调用的时候要使用接口.super.默认方法。
static:接口中的静态方法(jdk1.8后新增) 可以带方法体, 因为是静态方法,不可以在实现类中重写,而已用接口名调用
接口的继承:
接口也可以实现继承,并且可以继承多个父类,如果多个父类间有同名的方法,子接口要创建属于自己的同名方法。
内部类:
在java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类
与之对应,包含内部类的类被称为外部类
内部类隐藏在外部类之内,更好的实现了信息隐藏
成员内部类:
内部类中最常见的就是成员内部类,也称为普通内部类
获取内部类对象实例
方法1:外部类.内部类 对象名=new 外部类().new 内部类();
方法2:外部类.内部类 对象名=外部类对象.new.内部类();
方法3:外部类.内部类 对象名=外部类对象.获取内部类方法;
内部类在外部使用时,无法直接实例化,需要借由外部类信息才能完成实例化
内部类的访问修饰符,可以任意,但是访问范围会受到影响
内部类可以直接访问外部的成员,如果出现同名属性,优先访问内部类中定义的
可以使用外部类.this.成员的方式,访问外部类中同名的信息
外部类访问内部类信息,需要通过内部类实例,无法直接访问
内部类编译后.class文件命名:外部类$内部类.class
静态内部类:
属于类共享,静态内部类对象可以不依赖于外部类对象,直接创建
1、静态内部类中,只能直接访问外部类的静态成员,如果需要调用非静态成员,可以通过对象实例。
2、静态内部类对象实例时,可以不依赖于外部类对象
3、可以通过外部类,内部类,静态成员的方式,访问内部类中的静态成员
4、当内部类属性与外部类属性同名时,默认直接调用内部类中的成员
如果需要访问外部类中的静态属性,则可以通过 外部类.属性 的方式
如果需要访问外部类中的非静态属性,则可以通过 new 外部类().属性 的方式
方法内部类:
定义在外部类方法中的内部类,也称局部内部类
- 定义在方法内部,作用范围也在方法内
- 和方法内部成员使用规则一样,class前面不能添加public private protected static
- 类中不能包含静态成员
- 类中可以包含final、abstract修饰的成员
匿名内部类:将类的定义与类的创建,放到一起完成
适用场景:
只用到类的一个实例
类在定义后马上用到
给类命名并不会导致代码更容易被理解
- 匿名内部类没有类型名称、实例对象名称
- 编译后的文件命名:外部类$数字.class
- 无法使用public private protected static abstract修饰
- 无法编写构造方法,可以添加构造代码块
- 不能出现静态成员
- 匿名内部类可以实现接口也可以继承父类,但是不可兼得