抽象类:
抽象方法: abstract 类型 方法签名;
抽象类: abstract class 类名
1. 抽象方法必在抽象类中,抽象类中可以不定义抽象方法
2. 抽象类和接口不能直接实例化,但是可以通过子类继承抽象类然后向上转型从而实例化
3. 虽然抽象类不能直接实例化,但是如果在抽象类中定义静态方法,可以通过类名.方法名进行直接调用
抽象类的子类:
1. 抽象类:可以不实现父类的抽象方法,仅继承;
2. 实现类:必须实现父类中的全部抽象方法,且继承全部非抽象方法;
接口:
接口: interface 接口名
实现方式:class 类名 implement 接口名1,接口名2
继承方式:子接口 extends 接口1,接口2
接口不可以直接实例化,但是可以通过多态方式间接实例化。
1. 接口中的成员方法默认修饰词为 public abstract(即可以不写),且不能为其他,除3的例外;
2. 接口中的成员变量默认修饰词且只能修饰为public staticfinal并必须显式初始化;
3. jdk1.8之后,接口中的成员方法可以用default和static修饰:
3.1 static方法: 通过接口名.方法名直接调用 或 直接用方法名在接口中调用;
3.2 default方法:非抽象,需要方法体且被子类继承(被子类或实现类调用时采用类名.super.方法签名的形式调用),此外,子类如果要覆盖default 方法,权限必须是public
4. 接口中无法存在构造方法、构造代码块、静态代码块
接口的子类:
1. 子接口(关键词extends):无需实现,全部继承(同普通类,即可以调用super),可以覆盖,(就算是public 权限的抽象方法,可以用default权限的默认方法进行覆盖产生方法体);
2. 子抽象类(关键词implements):无需实现,全部继承,可以覆盖,(覆盖(本质上为实现)时成员方法权限必须是public);
3. 实现类(关键词implements): 必须实现,可以覆盖,权限必须是public
4. 接口的子类将隐藏父类的同名域,类同普通类的继承隐藏。访问父类同名域需要父类.变量名
内部类:
内部类:class/interface A { class/interface B{…(可以继续下去)}}
1. 内部类可以继承/实现外部类;
2. 内部类在不继承/实现时实际上与外部类是两个独立的类,但是由相互的地址关联;
3. 内部类可以访问外部类的所有成员(包括私有),外部类(外部类访问内部类时采用创建内部类对象的方式进行访问)同样如此
4. 非静态内部类中不能有静态成员(因为静态需要在加载的过程中直接装入jvm,而外部类装载的过程中内部类实际可以被视为封装的,无法加载静态)
5. 内部类中对成员变量以及外部类中的同名成员变量的调用:内部类/外部类.this.变量
this指的时对象名。内部类之所以可以直接访问外部类中的成员,因为内部类持有了外部类的引用 —— 外部类.this
6. 静态内部类、成员内部类、局部内部类(外部类的成员方法中)、匿名内部类
6.1 静态内部类:static修饰,相当于外部类,可以直接用new A.B()创建内部类对象(外部类一加载,内部类即存在)
6.2 成员内部类:
6.3 局部内部类:局部内部类中访问局部变量,该变量(包括方法签名的形参)需要被声明成final,因为当该方法调用结束弹出之后,方法的局部变量被销毁,而局部类仍然在使用这个变量,会产生错误
6.4 匿名内部类:class A{ new A/接口/父类(){ } }(可以直接 .成员方法名 进行调用)
匿名内部类即类名被省略的内部类;
内部类必须继承或实现一个外部类/接口,则可以匿名内部类(简写格式)
匿名内部类可以将地址赋值给父类/接口类型的引用;
通常使用场景之一:函数函数为接口类型;接口中方法不超过3个;匿名内部类作为实际参数传递;(本质上为了提高阅读性)