多态
同一个对象不同时刻的不同形态。
父类引用指向子类对象。
- 成员变量:编译看左边,运行看左边。
- 成员方法:编译看左边,运行看右边。
- 原因:成员方法可以重写,成员变量没有。
优:提高了程序的扩展性。定义方法使用父类型为参数,使用时用具体的子类型参与操作。
缺:不能使用子类型特有的功能。
转型:
- 向上转型:
People p = new Student();
,父指向子,子转父。 - 向下转型:
Student s = (Student) p;
,子指向父,强转(p为People p的地址)。
抽象类:
没有方法体的方法是抽象方法。
特点:
- abstract关键字修饰。
- 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类。
- 抽象类的子类要么重写抽象类里的所有抽象方法,要么是抽象类。
- 不能实例化。除非参照多态的方式,通过子类对象实例化,称为抽象类多态。
抽象类的成员变量:
- 成员变量:变量和常量。
- 构造方法:有,但不能实例化,用于子类访问父类数据的初始化。
- 成员方法:可以有抽象方法:限定子类必须完成;可以有非抽象方法,用来提高代码的复用性。
接口:
一种公共的行为规范。
特点:
- interface关键字修饰。
- 类实现接口用implement
- 不能实例化。除非参照多态的方式,通过子类对象实例化,称为接口多态。
- 接口的实现类要么重写接口里的所有抽象方法,要么是抽象类。
抽象类的成员变量:
- 成员变量:都是常量,默认为public static final。
- 构造方法:没有构造方法。
- 成员方法:必须是抽象方法。
抽象类与接口的设计理念区别:抽象类对事物抽象,属性、行为;接口对行为抽象,主要是行为。
抽象类名作为形参和返回值:
- 方法的形参是抽象类名,需要的是该抽象类的子类对象。
- 方法的返回值是抽象类名,其实返回的是该抽象类的子类对象。
接口作为形参和返回值:
- 方法的形参是接口名,需要的是该接口的实现类对象。
- 方法的返回值是接口名,其实返回的是该接口的实现类对象。
内部类
访问特点: 内部类可以直接访问外部类所有成员,外部类创建对象才能访问内部类的成员。
外界使用成员内部类:
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
(这种写法不常用。)
public class Outer {
public class Inner {
public void show() {
System.out.println(i);
}
}
}
public class Test {
public static void main(String[] args) {
//调用内部类的方法,不常用
Outer.Inner oi= new Outer().new Inner();
oi.show();
}
}
(常用写法)
public class Outer {
public int i = 10;
private class Inner {
public void show() {
System.out.println(i);
}
}
public void method(){
Inner in = new Inner();
in.show();
}
}
public class Test {
public static void main(String[] args) {
//常用
Outer o = new Outer();
o.method();
外界使用局部内部类:
public class Test {
public static void main(String[] args) {
//常用
Outer o = new Outer();
o.method();
public class Outer {
public int i = 10;
public void method(){
int i2 = 20;
class Inner{
public void show(){
System.out.println(i);
System.out.println(i2);
}
}
Inner in = new Inner();
in.show();
}
}
匿名内部类(局部内部类的一种)
前提:存在接口或者一个类(具体类抽象类都可)
本质:一个继承了该类或者实现了该接口的子类匿名对象。
两种调用形式:
new Inter(){
@Override
public void show(){//show是已经存在的类名或者接口名
System.out.println(2);
}
}.show();//对象.方法();
Inter i = new Inter(){
@Override
public void show(){//show是已经存在的类名或者接口名
System.out.println(2);
}
}
i.show();
i.show();
i.show();/多次调用