一. 抽象类
是一种模板
包含抽象方法的类叫做抽象类(抽象类可以没有抽象方法 HttpServlet)
抽象方法:仅有声明而没有方法体 abstract void f();
抽象类只能被继承,抽象方法只能被重写
抽象类可以包含 成员变量,方法,构造器(不能用于创建实例,用于被子类调用) 初始化块 内部类
二. 接口
是一种规范
接口是一个完全抽象的类,没有提供任何的具体实现
接口可以包含域,默认增加public final static修饰符
可以向上转型为多个基类型,防止客户端创建该类的对象
Java8 允许接口定义默认方法,默认方法提供方法实现,必须使用default修饰,不能使用static修饰,默认使用public修饰。
以上两者区别:
same:都不能实例化
diff:
1.本质上一个是类一个是接口,接口可以多实现,类只能继承一个
2.接口只能做方法声明,抽象类既可以方法声明也可以方法实现
3.接口定义变量默认是为public static final,抽象类定义变量则为普通变量
4.抽象类有构造器,以便子类实例化调用
三. 内部类
一个类放在另一个类的内部称为内部类,包含它的类称为外部类
内部类一般与包含它的外部类关系密切,而与其他类关系不大,定义在类内部可以实现对外部类的隐藏,有更好的封装性。
[内部类只是java编译器的概念,java虚拟机也会把内部类编译为独立的类,生成独立的字节码文件]
内部类可以方便访问外部类的私有变量,可以声明为private从而实现对外完全隐藏。
内部类分为四种:静态内部类/成员内部类/方法内部类/匿名内部类
1.静态内部类
public class Outer01 {
private static int shared = 100;
private static class StaticInner{
public void innerMethod(){
System.out.printf(" inner = "+shared);
}
}
public static void main(String[] args) {
Outer01.StaticInner staticInner = new Outer01.StaticInner();
staticInner.innerMethod();
}
}
可以访问外部类的静态变量和静态方法,不可访问实例变量和方法
public的静态外部类可以被外部使用,通过外部类.静态内部类的方法使用
--静态内部类与外部类关系密切,且不依赖于外部类实例
2. 成员内部类
public class Outer02 {
private int a = 100;
private static int b = 200;
private void action(){
System.out.println("outer action");
}
private static void sAction(){
System.out.println("outer static action");
}
public class Inner{
public void innerMethod(){
System.out.println("outer a = "+a +", b ="+ b);
Outer02.this.action();
Outer02.sAction();
}
}
public static void main(String[] args) {
Outer02 outer02 = new Outer02();
Outer02.Inner inner = outer02.new Inner();
inner.innerMethod();
}
}
除了静态变量和方法,成员内部类还可以访问外部类的实例变量和方法。[如果方法和外部类有重名,可以外部类.this.func()]
与静态内部类不同,成员内部类中不可以定义静态变量和方法 (final变量例外,它等同于常量),下面介绍的方法内部类和匿名内部类也都不可以[内部类是与外部类关联的,不应独立使用,而静态变量/方法是属于类的一般独立使用]
--内部类与外部类关系密切,且操作或依赖外部类实例变量和方法
3. 方法内部类
public class Outer03 {
private int a = 100;
public void test(int param) {
String str = "hello";
int a = 200;
class Inner {
public void innerMethod() {
System.out.println("Outer a = " + a);
System.out.println("param = " + param);
System.out.println("local var = " + str);
}
}
Inner inner = new Inner();
inner.innerMethod();
}
public static void main(String[] args) {
Outer03 outer03 = new Outer03();
outer03.test(50);
}
}
方法内部类只能在方法内被使用
1)如果方法是实例方法,除了静态变量和方法,还可以方法外部类的实例变量和方法
2)方法内部类还可以方法方法的参数和方法中的局部变量,不过必须声明为final
如果的确需要修改外部的变量,可以将变量改为只含该变量的数组,修改数组中的值
--类只在方法内被使用,方法内部类可以实现更好的封装
4. 匿名内部类
匿名内部类是与new相关联的
public interface Contents {
int value();
}
public class Outer04 {
public Contents contents(){
return new Contents() {
@Override
public int value() {
return 10;
}
};
}
public static void main(String[] args) {
Outer04 outer04 = new Outer04();
Contents c = outer04.contents();
}
}
匿名内部类只能被使用一次,用来创建一个对象,没有名字和构造函数,可以定义实例变量和方法,可以有初始化代码块。
没有构造方法,自己无法接受参数。
与方法内部类一样,匿名内部类也可以访问外部类的所有变量和方法,可以访问方法中的final参数和局部变量
--如果对象只会创建一次,且不需要构造方法来接受参数
四. 回调
思想:类A的a()方法调用类B的b()方法
类B的b()方法执行完毕后主动调用类A的callback()方法
1.public interface TellFinish {
void tell();
}
2.public class Teacher implements TellFinish{
public void doWork(Student student){
System.out.println("老师布置作业");
student.workDone(this);
}
@Override
public void tell() {
System.out.println("报告老师,已完成作业");
}
}
3.public class Student{
public void workDone(Teacher teacher){
System.out.println("学生完成作业");
teacher.tell();
}
}
4.public class CallMain {
public static void main(String[] args) {
Teacher teacher = new Teacher();
Student student = new Student();
teacher.doWork(student);
}
}
老师布置作业
学生完成作业
报告老师,已完成作业
\