Java四十: 接口

接口

一、普通类、抽象类、接口之间的联系与区别
  1. 结构上的异同:

    普通类:只有具体实现

    抽象类:具体实现和规范(抽象方法)都有

    接口 :只有规范!自己无法写方法~专业的约束!约束和实现分离:面向接口编程。

  2. 实例化

    普通类可以被实例化

    抽象类只能被继承不能被实例化

    接口只能有实现类,不能被继承或实例化,但是有一种接口在匿名内部类(假象的所谓内部类)实例化现象 参考博文 Java 接口实例化

二、接口
  1. 接口关键字:interface
  2. 接口就是规范:

    定义的是一组规则,体现了现实世界中”如果你是···则必须能···“的思想。

    如果你是天使,就必须能飞;如果你似乎汽车,就必须能跑;如果你是好人,就必须干掉坏人···

  3. 接口的本质是契约:

    就像我们社会的法律一样,制定好之后大家必须要遵守。

  4. OO的精髓:

    OO精髓是对对象的抽象,最能体现这一点的就是接口。

    为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如C++/Java/C#等),因为设计模式所研究的,实际上就是如何合理的去抽象。

三、接口的作用:
  1. 约束

  2. 接口中的所有方法的默认类型 public abstract (公开的、抽象的)

  3. 接口中的所有属性的默认类型 public static final(公开的、静态的、常量)

    ① 数据类型
    ② 引用类型:其地址值也不能被更改

  4. 接口不能被实例化,接口中没有构造器,通过类去实现(implements)的方式来使用。

    实现类覆盖接口中的所有抽象方法,则此实现类可以实例化
    实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类

  5. 一个类可以实现多个接口,相当于伪多继承,弥补了Java单继承的局限性

    class A extnds B inmlements C,D,E{
    
    }
    
  6. 接口和接口之间可以多继承
    interface AA{
        void method1();
    }
    interface BB{
        void method2();
    }
    //CC继承了AA,BB,那么CC的实现类必须重写AA和BB中的所有方法
    interface CC extends AA,BB{
        
    }
    
  7. 与继承关系类似,接口与实现类之间存在多态性
    public class CarTest {
        public static void main(String[] args) {
            Made m = new Made();
    		// 非匿名实现类的非匿名对象
            Audi audi = new Audi();
            m.show(audi);
    		// 非匿名实现类的匿名对象
            m.show(new Byd());
    		// 匿名实现类的非匿名对象
            Car dazhong = new Car() {
                @Override
                public void method() {
                    System.out.println("生产五菱神车");
                }
            };
            m.show(dazhong);
    		// 匿名实现类的匿名对象
            m.show(new Car() {
                @Override
                public void method() {
                    System.out.println("生产小鹏新能源");
                }
            });
        }
    }
    // 接口实现类多态性的体现
    class Made{
        public void show(Car c){
            c.method();
        }
    }
    // 接口
    interface Car{
        public void method();
    }
    // 实现类一
    class Audi implements Car{
        @Override
        public void method() {
            System.out.println("生产奥迪");
        }
    }
    // 实现类二
    class Byd implements Car{
        @Override
        public void method() {
            System.out.println("生产比亚迪");
        }
    }
    
四、重点:

是要锻炼自己的抽象思维,Java 架构师:把一个系统的结构全部抽象成一个接口

五、面向接口编程
  1. 接口的主要用途就是被实现类实现
  2. 项目的具体要求是多变的,我们必须以不变应万变才能从容开发,此处的不变就是“规范” 。因此,我们开发项目往往都是面向接口编程。
  3. 接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义(JDK7.0之前),而没有变量和方法的实现。
六、关于实现类对 ” 接口与父类 “ 内属性和方法的调用问题
  1. 调用接口与父类中有同名属性
    interface A{
        int a = 1;
        int b = 4;
    }
    class B{
        int a = 2;
        int c = 5;
    }
    public class C extends B implements A{
        public static void main(String[] args) {
            int a = 3;
            new C().show();
        }
        public void show(){
    		// 调用接口中的同名属性(该属性为全局静态常量)
            System.out.println(A.a);
            // 调用直接父类中的同名属性
            System.out.println(super.a);
            // 调用子类自身的同名属性
            System.out.println(a);
            // 调用父类中的属性
            System.out.println(b);
            // 调用接口中的属性
            System.out.println(c);
        }
    }
    
  2. 两个接口中可以有同名方法,不影响实现类对它的重写。
    interface X{
        void play();
    }
    interface Y{
        void play();
    }
    interface Z extends X,Y{
        // 接口中的成员变量都是默认public static final
        Ball ball = new Ball("接口Z的引用类型成员变量");
    }
    class Ball implements Z{
        String name;
        public String getName(){
            return name;
        }
        public Ball(){
    
        }
        public Ball(String name){
            this.name = name;
        }
        @Override
        public void play(){
            // ball是接口Z中的引用类型成员变量,可直接使用去调用方法或属性
            System.out.println(ball.getName());
        }
    }
    
    class PlayTest {
        public static void main(String[] args) {
            Ball b = new Ball("自身实例化");
            // 输出为: 接口Z的引用类型成员变量,b 是带参实例化对象,但对play方法内的ball造成影响
            b.play();
        }
    }
    
七、接口在java8后新特性(静态/默认方法)
  1. 接口中定义的静态方法,只能通过接口来调用(static)

  2. 通过实现类的对象,可以调用接口中的默认方法(default)

    如果实现类重写了接口中的默认方法,调用时用的是重写后的方法

  3. 如果子类(实现类)继承的父类和接口中声明了同名同参数的方法,那么在没有重写该方法的情况下,默认调用父类的同名同参方法。——>类似优先原则

  4. 接口冲突:

    ① 如果实现类实现了多个接口,而这些多个接口中定义了同名同参的默认方法,并且有方法体,那么在实现类没有重写该方法的情况下,就会报错,这种情况被称为接口冲突

    ② 解决接口冲突的方法,必须在实现类中重写此方法。

  5. 子类调用父类、接口中的各种方法示例
    public class PriorityPrinciple {
        public static void main(String[] args) {
            SubClass sub = new SubClass();
            // 实现类调用重写父类的方法
            sub.method1();
            // 接口调用其自身静态方法,不可通过实现类调用
            CompareA.method2();
            // 实现类调用重写的接口默认方法,执行重写方法
            sub.method3();
            // 实现类调用接口的未被重写默认方法,执行接口中的默认方法
            sub.method4();
            // 实现类调用父类与接口同名同参的方法,执行父类的同名同参方法
            sub.method5();
            // 实现类调用重写的父类与接口同名同参的方法,执行子类重写方法
            sub.method6();
            // 实现类调用重写的接口冲突方法,执行子类重写方法
            sub.method7();
        }
    }
    
    class SubClass extends SuperClass implements CompareA,CompareB{
        @Override
        public void method1(){
            System.out.println("子类重写的父类方法");
        }
        @Override
        public void method3() {        
            System.out.println("子类重写的接口默认方法");
        }
        @Override
        public void method5() {
            System.out.println("子类重写父类/接口共有的同名同参方法");
        }
        @Override
        public void method7() {
            System.out.println("解决接口冲突问题,子类重写的接口方法");
        }
    }
    class SuperClass{
        public void method1(){
            System.out.println("父类自身独有方法");
        }
        public void method5(){
            System.out.println("父类中与接口的同名同参方法,被重写");
        }
        public void method6(){
            System.out.println("父类中与接口的同名同参方法,未被重写");
        }
    }
    interface CompareA{
        static void method2(){
            System.out.println("接口中的静态方法");
        }
        default void method3(){
            System.out.println("接口中的默认方法");
        }
        default void method4(){
            System.out.println("接口未被重写的默认方法");
        }
        default void method5(){
            System.out.println("接口中与父类的同名同参方法,被重写");
        }
        default void method6(){
            System.out.println("接口中与父类的同名同参方法,未被重写");
        }
        
        default void method7(){
            System.out.println("A/B接口中的同名同参方法,被重写");
        }
    }
    interface CompareB{
        default void method7(){
            System.out.println("A/B接口中的同名同参方法,被重写");
        }
    }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

e_nanxu

感恩每一份鼓励-相逢何必曾相识

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值