Java 基础(接口)

接口详解一

  • 一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java 不支持多重继承。有了接口,就可以得到多重继承的效果
  • 另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。
  • 接口就是规范,定义的是一组规则,体现了现实世界中 "如果你是/要...则必须能..." 的思想。继承是一个"是不是"的关系,而接口实现则是"能不能"的关系。
  • 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。

接口的使用

  1. 接口使用 interface 来定义
  2. Java 中,接口和类是并列的两个结构
  3. 如何定义接口: 定义接口中的成员
    3.1 JDK7 及以前: 只能定义全局常量和抽象方法
    > 全局常量: public static final 的
    > 抽象方法: public abstract 的
    3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
  4. 接口中不能定义构造器! 意味着接口不可以实例化
  5. Java开发中,接口通过让类去实现(implements)的方式来使用
    如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
    如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
  6. Java 类可以实现多个接口 ---> 弥补了 Java 单继承性的局限性
    格式: class AA extends BB implements CC,DD,EE
  7. 接口与接口之间可以继承,而且可以多继承
  8. 接口的具体使用,体现多态性
  9. 接口,实际上可以看做是一种规范

InterfaceTest.java

package com.klvchen.java1;

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

}


interface Flyable{
    //全局常量
    public static final int MAX_SPEED = 7900; //第一宇宙速度
    int MIN_SPEED = 1;  //省略了 public static final
    
    //抽象方法
    public abstract void fly();
    
    //省略了 public abstract
    void stop();
}

interface Attackable{
    void attack();
}


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() {
        // TODO Auto-generated method stub
        
    }
}

class Bullet extends Object implements Flyable, Attackable{

    @Override
    public void attack() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void fly() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
        
    }
    
}

接口详解二

  • 定义Java类的语法格式: 先写 extends,后写 implements
  • class SubClass extends SuperClass implements InterfaceA{}
  • 一个类可以实现多个接口,接口也可以继承其它接口。
  • 实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
  • 接口的主要用途就是被实现类实现。((面向接口编程)
  • 与继承关系类似,接口与实现类之间存在多态性
  • 接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义(JDK7.0及之前),而没有变量和方法的实现。
 

USBTest.java

package com.klvchen.java1;

public class USBTest {
    public static void main(String[] args) {
        
        Computer com = new Computer();
        //1. 创建了接口的非匿名实现类的非匿名对象
        Flash flash = new Flash();
        com.transferData(flash);
        
        System.out.println("******************************");
        
        //2. 创建了接口的非匿名实现类的匿名对象
        com.transferData(new Printer());
        
        System.out.println("******************************");
        
        //3. 创建了接口的匿名实现类的非匿名对象
        USB phone = new USB() {

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

            @Override
            public void stop() {
                System.out.println("手机结束工作");
            }
            
        };
        com.transferData(phone);
        
        System.out.println("******************************");
        
        //4. 创建了接口的匿名实现类的匿名对象
        
        com.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中关于接口的改进

Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。

静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像 Collection/Collections 或者 Path/Paths 这样成对的接口和类。

默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。比如: java 8 API 中对 Collection、List、Comparator 等接口提供了丰富的默认方法。

CompareA.java

package com.klvchen.java8;
/*
 *  JDK8, 除了定义全局常量和抽象方法之外,还可以定义静态方法,默认方法
 * 
 * 
 */

public interface CompareA {
    
    //静态方法
    public static void method1() {
        System.out.println("CompareA:北京");
    }
    
    //默认方法
    public default void method2() {
        System.out.println("CompareA public default:上海");
    }
    
    default void method3() {
        System.out.println("CompareA default:上海");
    }

}

CompareB.java

package com.klvchen.java8;

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

}

SuperClass.java

package com.klvchen.java8;

public class SuperClass {

    public void method3() {
        System.out.println("SuperClass: 北京");
    }
}

SubClassTest.java

package com.klvchen.java8;

public class SubClassTest {
    public static void main(String[] args) {
        SubClass s = new SubClass();
        
//        s.method1();
//        SubClass.method1();
        //知识点1:接口中定义的静态方法,只能通过接口来调用。
        CompareA.method1();   
        //知识点2:通过实现类的对象,可以调用接口中的默认方法
        //如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
        s.method2();          
        //知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,
        //那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。 --> 类优先原则

        //知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
        //那么在实现类没有重写此方法的情况下,报错。-->接口冲突。
        //这就需要我们必须在实现类中重写此方法
        s.method3();          
        
//        SubClass.method2();
        System.out.println("*******************************");
        s.myMethod();
    }
    

}

class SubClass extends SuperClass implements CompareA, CompareB{
//class SubClass implements CompareA, CompareB{
    
    public void method2() {
        System.out.println("SubClass: 上海");
    }
    
    public void method3() {
        System.out.println("SubClass: 深圳");
    }
    
    public void myMethod() {
        method3();        //调用自己定义的重写的方法
        super.method3();  //调用的是父类中声明的
        //调用接口中的默认方法
        CompareA.super.method3();
        CompareB.super.method3();
    }
}

Man.java

package com.klvchen.java8;

interface Filial {
    default void help() {
        System.out.println("Lily,我来救你了");
    }
}

interface Spoony{
    default void help() {
        System.out.println("Lucy, 我来救你了");
    }
}

class Father{
    public void help() {
        System.out.println("救Lucy");
    }
}

public class Man extends Father implements Filial, Spoony {

    @Override
    public void help() {
        System.out.println("我改救谁呢?");
        Filial.super.help();
        Spoony.super.help();
    }

    public static void main(String[] args) {
        Man m = new Man();
        m.help();
    }
}

 
posted @ 2021-11-29 14:04  民宿  阅读(53)  评论(0)    收藏  举报