Java-抽象类/接口/内部类

147 阅读5分钟

一. 抽象类

是一种模板

包含抽象方法的类叫做抽象类(抽象类可以没有抽象方法 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);
    }
}
老师布置作业
学生完成作业
报告老师,已完成作业

\