Java基础之:OOP——接口

Java基础之:OOP——接口

usb插槽就是现实中的接口,可以把手机,相机,u盘都插在usb插槽上,而不用担心那个插槽是专门插哪个的,原因是做usb插槽的厂家和做各种设备的厂家都遵守了统一的规定包括尺寸,排线等等。

而在java中我们也可以实现类似这样的功能。

简单案例

package class_interface;
​
public class Class_Test {
​
    public static void main(String[] args) {

        Computer computer = new Computer();

        //使用USB接口,多态传入
        //1. 在java中, 允许 将一个实现了某个接口的 类的对象,传递给该接口的一个引用
        //2. 在接口使用过程中,仍然遵守我们的多态和动态绑定机制
        computer.work(new Phone()); //匿名对象做传入参数
        computer.work(new U_disk());
    }
​
}
​
class Computer{
    //Computer类使用了USB接口
    public void work(USB usb) { //输入参数实现接口的多态
        usb.start();
        usb.stop();
    }
​
}
​
//声明一个接口使用 interface 关键字
interface USB{
    //对于接口内写的所有方法而言,都是默认带有abstract关键字修饰的,即抽象方法
    public void start();
    public void stop();

    //在jdk8.0之后,接口中也可以实现方法,但必须是静态方法与默认方法,例如:
    //因为可能会出现一个接口我们会频繁的使用,且对于接口中的某一个方法都实现一样的作用。
    //那么在接口中实现静态/默认方法后,在实现接口的类中,直接调用此方法即可。不需要再重写实现此方法
    default public void hi() {
        System.out.println("say hi....");
    }
    public static void hello() {
        System.out.println("say hello....");
    }
}
​
//实现一个接口使用 implements 关键字,接口与抽象类很类似
//实现了接口的类,也需要实现接口中的所有抽象方法
class Phone implements USB{
​
    @Override
    public void start() {
        System.out.println("手机开始工作....");
    }
​
    @Override
    public void stop() {
        System.out.println("手机停止工作....");
        hi();
    }   

}
​
class U_disk implements USB{
​
    @Override
    public void start() {
        System.out.println("U盘开始工作....");
    }
​
    @Override
    public void stop() {
        System.out.println("U盘停止工作....");
    }

}

程序输出

手机开始工作....

手机停止工作....

say hi....

U盘开始工作....

U盘停止工作....

接口介绍

接口就是将没有实现的抽象方法放在一起,当有类需要使用这些方法时,则根据实际情况将这个方法实现出来。

声明语法:

  1. 创建接口

    interface 接口名{

      //属性

      //抽象方法

    }

  2. 使用接口

    class 类名 implements 接口名{

      //类自己的属性

    //类自己的方法

    //必须实现接口中的抽象方法

    }

小结:接口是更加抽象的抽象的类,抽象类里的方法可以有方法体,接口里的所有方法都没有

方法体。

接口使用细节

1) 接口不能被实例化

2) 接口中所有的方法是 public方法, 接口中抽象方法,可以不用abstract 修饰

3) 一个普通类实现接口,就必须将该接口的所有方法都实现。

4) 抽象类实现接口,可以不用实现接口的方法。

5) 一个类同时可以实现多个接口

6) 接口中的属性,只能是final的,而且是 public static final 修饰符。比如: int a=1; 实际上是 public static final int a=1; (必须初始化)

7) 接口中属性的访问形式: 接口名.常量名

8) 一个接口不能继承其它的类,但是可以继承多个别的接口

9) 接口的修饰符 只能是 public 和默认,这点和类的修饰符是一样的。

细节案例

package class_interface;
public class InterfaceDetail {
    public static void main(String[] args) {

    }
}
​
//接口命名习惯: 大写I + 接口名 , 例如:IUser
interface IA{
    public void m1();
    public void m2();
}
​
interface IB{
    public void m1();
    public void m3();
}
​
​
//细节1.一个普通类实现接口,就必须将该接口的所有方法都实现。
class CA implements IA{
​
    @Override
    public void m1() {
​
    }
​
    @Override
    public void m2() {

    }
}
​
//细节2.抽象类实现接口,可以不用实现接口的方法。
abstract class CB implements IA{
    //这点很容易理解,因为抽象类中允许继承下来的抽象方法不进行重写实现。
}
​
//细节3:一个类同时可以实现多个接口 ,且必须实现多个接口中的所有抽象方法
//这里我们会发现,IA与IB接口中,m1()方法重名了,但在CC类中实现并没有报错。
//理解:因为m1()方法,仅是接口定义的一个规范,需要类来实现这个规范,而我们只要实现了m1()方法,则IA与IB接口可以使用
class CC implements IA,IB{
​
    @Override
    public void m3() {

    }
​
    @Override
    public void m1() {

    }
​
    @Override
    public void m2() {

    }
}
​
//细节4:接口中的属性,只能是final的,而且是 public static final 修饰符。
//比如: int a=1; 实际上是 public static final int a=1; (必须初始化)
interface IC{
    int a = 1;
//  private int b = 2;
    /*
     * 这里使用private声明之后,报错:
     * Illegal modifier for the interface field IC.b; only public, static & final are permitted
     */
}
​
//细节5:接口中属性的访问形式: 接口名.常量名
class CD implements IC{
    //这点也很好理解,因为属性a是默认被static修饰的,所以只能使用接口名访问
    public void say() {
        System.out.println(IC.a);
    }
}
​
//细节6:一个接口不能继承其它的类,但是可以继承多个别的接口
interface ID extends /*CD*/ IA,IB,IC{
    //如果继承CD类的话,报错:
    //The type CD cannot be a superinterface of ID; a superinterface must be an interface

    /*
     * 这点容易出现混淆,因为我们之前说Java是单继承的,但接口这里好像又出现了多继承的情况
     * 我们可以这样理解,电脑通过USB接口连接上了USB转换器,通过USB转换器,我们连接上了读卡器
     * 那么就说,USB接口通过继承USB连接器扩展了可以连接读卡器的功能。
     * 所以对于接口的继承而言,并不像是父类与子类的关系,而是使用继承机制,扩展单个接口的功能。
     */
}
​
//细节7:接口的修饰符 只能是 public 和默认,这点和类的修饰符是一样的。
/*private*/  interface IE {
    /*
     * 使用private 报错:Illegal modifier for the interface IE; only public & abstract are permitted
     * 这里可以看到只能使用public与abstract修饰,当然也可以不修饰(即默认)。
     * 而使用abstract修饰又显得有一些多余,因为接口本来就是抽象的概念。
     */
}

实现接口与继承父类之间的区别

  1. 继承的价值主要在于:解决代码的复用性和可维护性。

  2. 接口的价值主要在于:设计,设计好各种规范(方法),让其它类去实现这些方法。

  3. 接口比继承更加灵活,继承是满足 is - a的关系,而接口只需满足 like - a的关系。

  4. 接口在一定程度上实现代码解耦。

简单案例

package class_interface;
​
public class ImplementsVSExtends {
    /*
     * 讨论实现接口 与 继承类,到底有什么样的区别
     * 虽然两者都具有实现功能扩展的能力
     */
    public static void main(String[] args) {
        /*
         * 可以看到这里 对象a 即能够使用 父类 Person中的eat也能够使用接口IFish中的swimming
         * 但我们可以这样理解,为什么要使用接口来定义swimming方法。
         * 人类与生俱来的能力就一定会吃东西,但游泳并不是与生俱来的能力。即继承Person
         * 那么运动员为了拥有游泳的能力就去向小鱼学习,即实现接口IFish。
         *
         * 总结:
         *      继承:父类是通过子类扩展其已有的方法与功能。
         *      实现:类通过接口扩展类所需要的方法与功能。
         */
        Athletes a = new Athletes("小范");
        a.eat();
        a.swimming();
​
    }
}
​
class Person{
    private String name;

    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }

    public Person(String name) {
        super();
        this.name = name;
    }
​
    public void eat() {
        System.out.println(name + "吃东西....");
    }
}
​
interface IFish{
    public void swimming();
}
​
class Athletes extends Person implements IFish{
​
    public Athletes(String name) {
        super(name);
    }
​
    @Override
    public void swimming() {
        System.out.println(getName() + "游泳.....");
    }

}

程序输出

小范吃东西....

小范游泳.....

接口的多态特性

在前面的Usb接口案例,Usb usb ,既可以接收手机对象,又可以接收U盘对象,就体现了 接口 多态 (接口引用可以指向实现了接口的类的对象)

简单案例

演示一个案例:给Usb数组中,存放 Phone 和 相机对象,Phone类还有一个特有的方法call(),请遍历Usb数组,如果是Phone对象,除了调用Usb 接口定义的方法外,还需要调用Phone 特有方法 call。以及U盘的特有方法read。

package class_interface.InterfacePolyArray;
​
public class InterfacePolyArray {
​
    public static void main(String[] args) {
        USB[] u = new USB[2];
        u[0] = new Phone();
        u[1] = new U_disk();

        for (int i = 0; i < u.length; i++) {
            work(u[i]);
        }
    }

    public static void work(USB usb) {  //输入参数实现接口的多态
        usb.start();
        usb.stop();
        if(usb instanceof Phone) {
            ((Phone) usb).call();
        }else if(usb instanceof U_disk) {
            ((U_disk) usb).read();
        }
    }
​
}
​
interface USB{
    public void start();
    public void stop();
}
​
class Phone implements USB{
​
    @Override
    public void start() {
        System.out.println("手机开始工作....");
    }
​
    @Override
    public void stop() {
        System.out.println("手机停止工作....");
    }   

    public void call() {
        System.out.println("手机开始打电话......");
    }
}
​
class U_disk implements USB{
​
    @Override
    public void start() {
        System.out.println("U盘开始工作....");
    }
​
    @Override
    public void stop() {
        System.out.println("U盘停止工作....");
    }

    public void read() {
        System.out.println("U盘开始读取数据.....");
    }
}

程序输出

手机开始工作....

手机停止工作....

手机开始打电话......

U盘开始工作....

U盘停止工作....

U盘开始读取数据.....

接口的多态传递

接口的多态传递解读:

  1. 当一个类实现了某个接口

  2. 这个类的对象可以赋给该接口的引用

  3. 如果这个类被继承,那么这个类的子类的对象,也可以赋给该接口的引用

  4. 如果这个接口是继承来的,那么这个对象也可以赋给该接口的上层接口的引用

  5. 不限于一级,可以多级传递.

简单案例

package class_interface.InterfacePolymorphicPass;
/**
        下面程序的继承关系:
            IC 继承于 IB ,IB 继承于 IA
            CA 实现了接口 IC,CB 继承于 CA

        show方法的实际传入参数:
            传入参数是IC时,可以识别CA与CB的对象 ,因为CA实现了IC 且 CB继承于CA
            而传入参数是IA时,也可以识别CA与CB的对象,因为CA实现的IC是继承于IA的(子类对象可以赋值给父类引用)。
​
 */
public class InterfacePolymorphicPass {
​
    public static void main(String[] args) {
        CA ca = new CA();
        CB cb = new CB();

        show(ca);
        show2(ca);
        show3(ca);
        System.out.println("=================");
        show(cb);
        show2(cb);
        show3(cb);
    }

    public static void show(IC ic) {
        ic.m4();
    }

    public static void show2(IB ib) {
        ib.m3();
    }

    public static void show3(IA ia) {
        ia.m1();
        ia.m2();
    }
}
​
interface IA{
    void m1();
    void m2();
}
​
interface IB extends IA{
    void m3();
}
​
interface IC extends IB{
    void m4();
}
​
class CA implements IC{
​
    @Override
    public void m1() {
        System.out.println("CA--IA--m1");
    }
​
    @Override
    public void m2() {
        System.out.println("CA--IA--m2");
    }
​
    @Override
    public void m3() {
        System.out.println("CA--IB--m3");
    }
​
    @Override
    public void m4() {
        System.out.println("CA--IC--m4");
    }

}
​
class CB extends CA{
    @Override
    public void m3() {
        System.out.println("CB--IB--m3");
    }
    @Override
    public void m4() {
        System.out.println("CB--IC--m4");
    }
}

程序输出

CA--IC--m4

CA--IB--m3

CA--IA--m1

CA--IA--m2

============

CB--IC--m4

CB--IB--m3

CA--IA--m1

CA--IA--m2

(0)

相关推荐

  • Java并发编程之线程的创建

    简介 线程是基本的调度单位,它被包含在进程之中,是进程中的实际运作单位,它本身是不会独立存在.一个进程至少有一个线程,进程中的多个线程共享进程的资源. Java中创建线程的方式有多种如继承Thread ...

  • java面向对象高级

    目录 1.类变量(静态类变量) 2.静态方法 3.Main()方法 4.代码块 5.单例模式 6.抽象类 6.1.抽象类的介绍 6.2.抽象类的特点 6.3.多态在抽象类的体现 6.4.抽象类体现了模 ...

  • Spring Boot 启动时,让方法自动执行的 4 种方法!

    不装逼的程序员 今天 作者:FOEVERYANG 来源:www.cnblogs.com/lsgspace/p/10508180.html 在springBoot中我们有时候需要让项目在启动时提前加载相 ...

  • Java基础之:OOP——代码块

    代码块又称初始化块,是类中的成员(即类的一部分),类似于方法,将逻辑语句封装在方法体中,通过{}包围起来,也是通过调用执行. 但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象 ...

  • Java基础之:OOP——类变量与类方法

    类变量与类方法,我们习惯也将其称为静态变量与静态方法. 类变量/静态变量 通过一个实际案例来了解,为什么需要使用静态变量. 引入案例 声明一个学生类,每创建一个学生对象,统计学生的人数. public ...

  • Java基础之:OOP——继承

    Java基础之:OOP--继承 面向对象编程OOP(Object Oriented Programming)的三大特征之二:继承 首先看一个案例,分别创建小学生与研究生类,输出他们的信息: 小学生类: ...

  • Java基础之:泛型

    Java基础之:泛型 在不使用泛型的情况下,在ArrayList 中,添加3个Dog. Dog对象含有name 和 age, 并输出name 和 age (要求使用getXxx()). package ...

  • Java 基础知识

    Java 基础知识

  • Java 基础语法

    注释 #单行注释 // 这里是单行注释 #多行注释 /* 这里是 多行注释 */ #JavaDoc /* *@Description: *@Author: */ Java可以使用中文命名 但不建议使用 ...

  • Java基础(第二期)

    数据类型扩展以及面试题讲解 整数拓展:进制 int i=10; int i2=010; //八进制0 int i3=0x10; //十六进制0x 0~9 A~F 16 相关进制转换自行学习,用的不多 ...

  • Java开发工程师最新面试题库系列——Java基础部分(附答案)

    JAVA基础 如果你有更好的想法请在评论区留下您的答案,一起交流讨论 面向对象有哪些特征? 答:继承.封装.多态 JDK与JRE的区别是什么? 答:JDK是java开发时所需环境,它包含了Java开发 ...

  • 全栈必备 Java基础

    那一年,从北邮毕业,同一年,在大洋的彼岸诞生了一门对软件业将产生重大影响的编程语言,它就是--Java.1998年的时候,开始学习Java1.2,并在Java Orbix 上做服务,而如今Java 9 ...