Loading

Java抽象类和接口

抽象类

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,使用abstract关键字来定义抽象类。

  • abstract除了可以修饰类之外还可以修饰方法。

  • abstract不能用来修饰属性和构造器。

  • abstract不能用来修饰私有方法和静态方法。

  • 抽象类中一定有构造器,便于子类实例化时调用。

  • 抽象方法只有方法的声明,没有方法体。

  • 包含抽象方法的类,一定是抽象类。

  • 子类重写了父类所有的抽象方法后,子类才能实例化,如果子类不重写父类所有的抽象方法,则子类也必须是抽象类。

public class AbstractTest1 {
    public static void main(String[] args) {
        //Person类使用abstract修饰,不可被实例化
//        Person person = new Person();
    }
}

//使用abstract修饰,此类不能被实例化
abstract class Person {
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //抽象方法
    public abstract void eat();

    public void walk() {
        System.out.println("人走路");
    }
}

class Student extends Person {
    public Student(String name, int age) {
        super(name, age);

    }

    @Override
    public void eat() {
        System.out.println("学生要吃点好的");
    }
}

抽象类的匿名子类对象:

public class AbstractTest1 {
    public static void main(String[] args) {
        //创建了匿名子类的对象
        Person p = new Person() {
            @Override
            public void eat() {
                System.out.println("吃东西");
            }

            @Override
            public void walk() {
                System.out.println("走路");
            }
        };
    }

}

//使用abstract修饰,此类不能被实例化
abstract class Person {
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //抽象方法
    public abstract void eat();
    public abstract void walk();
}

接口

有些情况下,必须从几个类中派生出一个子类,继承他们所有的属性和方法,但是Java不支持多继承,有了接口就可以实现多重继承的效果。使用 Interface关键字用来声明一个接口。

如何定义接口:定义接口中的成员

  • JDK7及之前:只能定义全局常量和抽象方法
    • 全局常量:public static final,书写时可以不写
    • 抽象方法:public abstract
  • JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法和默认方法

接口的特点

  • 接口中不能定义构造器,意味着接口不能实例化。
  • 接口通过让类去实现(implements)的方式来使用。
    • 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
    • 如果实现类没有覆盖接口中所有的抽象方法,则此实现类必须仍是一个抽象类

示例:

public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyable.MAX_SPEED); //7900
        System.out.println(Flyable.MIN_SPEED); //1
        Plane plane = new Plane();
        plane.fly();
    }
}

interface Flyable {
    //全局常量
    public static final int MAX_SPEED = 7900;
    //省略 public static final
    int MIN_SPEED = 1;

    //抽象方法
    public abstract void fly();

    //省略public abstract
    void stop();

}

class Plane implements Flyable {

    @Override
    public void fly() {
        System.out.println("起飞");
    }

    @Override
    public void stop() {
        System.out.println("减速停止");
    }
}

//没有覆盖接口中所有的抽象方法,则必须声明为抽象类
abstract class Kite implements Flyable {
    @Override
    public void fly() {
    }
}

实现多个接口来弥补单继承的局限性

class AA extends BB implements CC,DD,EE

示例:

public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyable.MAX_SPEED); //7900
        System.out.println(Flyable.MIN_SPEED); //1
    }
}

interface Flyable {
    //全局常量
    public static final int MAX_SPEED = 7900;
    //省略 public static final
    int MIN_SPEED = 1;

    //抽象方法
    public abstract void fly();

    //省略public abstract
    void stop();
}

interface Attackable{
    void attack();
}
class Bullet extends Object implements Flyable,Attackable{
    @Override
    public void fly() {

    }
    @Override
    public void stop() {

    }
    @Override
    public void attack() {

    }
}

接口和接口之间可以多继承

interface AA {
    void method1();
}

interface BB {
    void method1();
}

interface CC extends AA, BB {

}

接口可以看做是一种规范

public class USBTest {
    public static void main(String[] args) {
        Computer computer = new Computer();
        //1.创建了接口的非匿名实现类的非匿名对象
        Flash flash = new Flash();
        computer.transferData(flash);

        //2.创建了接口的非匿名实现类的匿名对象
        computer.transferData(new Printer());

        //3.创建了接口的匿名实现类的非匿名对象
        USB phone = new USB() {

            @Override
            public void start() {
                System.out.println("手机开始工作");
            }

            @Override
            public void stop() {
                System.out.println("手机结束工作");
            }
        };
        computer.transferData(phone);

        //4.创建了接口的匿名实现类的匿名对象
        computer.transferData(new USB() {
            @Override
            public void start() {
                System.out.println("mp3开始工作");
            }

            @Override
            public void stop() {
                System.out.println("mp3结束工作");
            }
        });
    }
}

class Computer {
    public void transferData(USB usb) {
        usb.start();
        System.out.println("具体传输数据的细节!");
        usb.stop();

    }
}

interface USB {
    void start();

    void stop();
}

class Flash implements USB {

    @Override
    public void start() {
        System.out.println("U盘开启工作");
    }

    @Override
    public void stop() {
        System.out.println("U盘结束工作");
    }
}

class Printer implements USB {

    @Override
    public void start() {
        System.out.println("打印机开启工作");
    }

    @Override
    public void stop() {
        System.out.println("打印机结束工作");
    }
}

Java8接口的新特性

Java8中可以为接口添加静态方法和默认方法。

  • 静态方法:使用static修饰,可以通过接口直接调用静态方法。
  • 默认方法:默认方法使用default关键字修饰,可以通过实现类对象来调用。

定义接口:

/**
 * JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
 */
public interface CompareA {
    //静态方法
    public static void method1() {
        System.out.println("CompareA:北京");
    }

    //默认方法
    public default void method2() {
        System.out.println("compareA:上海");
    }

    default void method3() {
        System.out.println("compareA:上海");
    }
}

定义接口的实现类:

public class SubClassTest {
    public static void main(String[] args) {
        SubClass s = new SubClass();

        //接口中定义的静态方法,只能通过接口来调用
        CompareA.method1(); //CompareA:北京

        //通过实现类的对象,可以调用接口中的默认方法
        //如果实现类重写了接口的默认方法,调用的则是重写后的方法。
        s.method2(); //SubClass:上海

        //如果子类继承的父类和实现的接口中声明了同名同参数的方法
        //那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。类优先原则。
        s.method3(); //SuperClass:北京

    }
}

class SubClass extends SuperClass implements CompareA {
    public void method2() {
        System.out.println("SubClass:上海");
    }
}

class SuperClass {
    public void method3() {
        System.out.println("SuperClass:北京");
    }
}
posted @ 2021-10-21 16:31  charlatte  阅读(72)  评论(0编辑  收藏  举报