Com.Java.Basis 第十二课 《Java的接口》

简介: Com.Java.Basis 第十二课 《Java的接口》

第十二课 《Java的接口》

第一部分:不知道的内容百度百科:

@1接口的定义:

Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。


两种含义:一,Java接口,Java语言中存在的结构,有特定的语法和结构;二,一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫做“Java接口”,后者叫做“接口”。

@2接口的功能:

在Java语言规范中,一个方法的特征仅包括方法的名字、参数的数目和类型,而不包括方法的返回类型、参数名以及所抛出来的异常。在Java编译器检查方法的重载时,会根据这些条件判断两个方法是否是重载方法。但在Java编译器检查方法的置换时,则会进一步检查两个方法(分处超类型和子类型)的返还类型和抛出的异常是否相同。


接口实现和类继承的规则不同,为了数据的安全,继承时一个类只有一个直接父类,也就是单继承,但是一个类可以实现多个接口,接口弥补了类的不能多继承缺点,继承和接口的双重设计既保持了类的数据安全也变相实现了多继承。


Java接口本身没有任何实现,因为Java接口不涉及表象,而只描述public行为,所以Java接口比Java抽象类更抽象化。但是接口不是类,不能使用new 运算符实例化一个接口。如 x=new comparable(......);//这个是错误来的。但是可以声明接口变量Comparable x; //这是允许的。


Java接口的方法只能是抽象的和公开的,Java接口不能有构造器,Java接口可以有public、static和final属性。即接口中的属性可以定义为 public static final int value=5; [1]


接口把方法的特征和方法的实现分割开来。这种分割体现在接口常常代表一个角色,它包装与该角色相关的操作和属性,而实现这个接口的类便是扮演这个角色的演员。一个角色由不同的演员来演,而不同的演员之间除了扮演一个共同的角色之外,并不要求其它的共同之处。

@3接口的使用:

两个类中的两个类似的功能,调用他们的类动态的决定一种实现,那他们提供一个抽象父类,子类分别实现父类所定义的方法。


问题的出现:Java是一种单继承的语言,一般情况下,哪个具体类可能已经有了一个超类,解决是给它的父类加父类,或者给它父类的父类加父类,直到移动到类等级结构的最顶端。这样一来,对一个具体类的可插入性的设计,就变成了对整个等级结构中所有类的修改。

可插入性

在一个等级结构中的任何一个类都可以实现一个接口,这个接口会影响到此类的所有子类,但不会影响到此类的任何超类。此类将不得不实现这个接口所规定的方法,而其子类可以从此类自动继承这些方法,当然也可以选择置换掉所有的这些方法,或者其中的某一些方法,这时候,这些子类具有了可插入性(并且可以用这个接口类型装载,传递实现了他的所有子类)。


我们关心的不是那一个具体的类,而是这个类是否实现了我们需要的接口。


接口提供了关联以及方法调用上的可插入性,软件系统的规模越大,生命周期越长,接口使得软件系统的灵活性和可扩展性,可插入性方面得到保证。

类型

使用Java接口将软件单位与内部和外部耦合起来。使用Java接口不是具体的类进行变量的类型声明,方法的返还类型声明,参量的类型声明,以及数据类型的转换。

在理想的情况下,一个具体的Java类应当只实现Java接口和抽象Java类中声明的方法,而不应当给多余方法。

等级结构

Java接口(以及抽象类)一般用来作为一个类型的等级结构的起点。

如果一个类已经有了一个主要的超类型,那么通过实现一个接口,这个类可以拥有另一个次要的超类型,这种次要的超类型叫做混合类型。


六个测试Demo来讲讲什么是接口,接口如何定义的:

案例一

一、基本概念


接口(Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合。接口通常以interface来声明。

一个类通过继承接口的方式,从而来继承接口的抽象方法。


如果一个类只由抽象方法和全局常量组成,那么这种情况下不会将其定义为一个抽象类。只会定义为一个接口,

所以接口严格的来讲属于一个特殊的类,而这个类里面只有抽象方法和全局常量,就连构造方法也没有。

由于接口里面存在抽象方法,所以接口对象不能直接使用关键字new进行实例化。接口的使用原则如下:

(1)接口必须要有子类,但此时一个子类可以使用implements关键字实现多个接口;

(2)接口的子类(如果不是抽象类),那么必须要覆写接口中的全部抽象方法;

(3)接口的对象可以利用子类对象的向上转型进行实例化。

package com.JavaBasicsDemo7.Interface1;
/**
 * 由于接口里面存在抽象方法,所以接口对象不能直接使用关键字new进行实例化。接口的使用原则如下:
 * (1)接口必须要有子类,但此时一个子类可以使用implements关键字实现多个接口;
 * (2)接口的子类(如果不是抽象类),那么必须要覆写接口中的全部抽象方法;
 * (3)接口的对象可以利用子类对象的向上转型进行实例化。
 */
public interface A {
    public static final String MSG = "hello";//全局常量
    public abstract void print();//抽象方法
}
package com.JavaBasicsDemo7.Interface1;
public interface B {
    public abstract void get();
}
package com.JavaBasicsDemo7.Interface1;
public interface C {
    public abstract void set();
}
package com.JavaBasicsDemo7.Interface1;
public interface D {
    public abstract void getString();
}
package com.JavaBasicsDemo7.Interface1;
public class TestDemo {
    public static void main(String[] args) {
       Test test = new Test();//实例化子类对象
        A a = test;//向上转型
        B b = test;//向上转型
        C c=test;
        D d=test;
        a.print();
        b.get();
        c.set();
        d.getString();
    }
}
package com.JavaBasicsDemo7.Interface1;
/**
 * 我们发现,从定义结构来讲,A和B两个接口没有任何直接联系,但这两个接口却拥有同一个子类。我们不要被类型和名称所迷惑,
 * 因为实例化的是X子类,而这个类对象属于B类的对象,所以以上代码可行,只不过从代码的编写规范来讲,并不是很好。
 */
//class 子类 [extends 父类] [implemetns 接口1,接口2,...] {}
public class TestDemo1 {
    public static void main(String[] args) {
        A a = new Test();
        B b = (B) a;
        b.get();
        System.out.println(a instanceof A);
        System.out.println(a instanceof B);
    }
}

我们发现,从定义结构来讲,A和B两个接口没有任何直接联系,但这两个接口却拥有同一个子类。我们不要被类型和名称所迷惑,
* 因为实例化的是X子类,而这个类对象属于B类的对象,所以以上代码可行,只不过从代码的编写规范来讲,并不是很好。


案例二:

对于接口,里面的组成只有抽象方法和全局常量,所以很多时候为了书写简单,

* 可以不用写public abstract 或者public static final。并且,接口中的访问权限只有一种:public

* ,即:定义接口方法和全局常量的时候就算没有写上public,那么最终的访问权限也是public,注意不是default。以下两种写法是完全等价的:

package com.JavaBasicsDemo7.Interface2;
public interface A {
    public static final String MSG = "hello";//全局常量
    public abstract void print();//抽象方法
}
package com.JavaBasicsDemo7.Interface2;
public interface B {
    public abstract void get();
}
package com.JavaBasicsDemo7.Interface2;
abstract class C{//定义一个抽象类C
    public abstract void change();
}
package com.JavaBasicsDemo7.Interface2;
/**
 * 对于接口,里面的组成只有抽象方法和全局常量,所以很多时候为了书写简单,
 * 可以不用写public abstract 或者public static final。并且,接口中的访问权限只有一种:public
 * ,即:定义接口方法和全局常量的时候就算没有写上public,那么最终的访问权限也是public,注意不是default。以下两种写法是完全等价的:
 *
 * interface A{
 *     public static final String MSG = "hello";
 *     public abstract void print();
 * }
 * 等价
 * interface A{
 *     String MSG = "hello";
 *     void print();
 * }
 * 是,这样会不会带来什么问题呢?如果子类子类中的覆写方法也不是public,我们来看:
 */
class X extends C implements A,B{//X类继承C类,并实现了A和B两个接口
    @Override
    public void print() {
        System.out.println("接口A的抽象方法print()");
    }
    @Override
    public void get() {
        System.out.println("接口B的抽象方法get()");
    }
    @Override
    public void change() {
        System.out.println("抽象类C的抽象方法change()");
    }
}

案例三:

/这是因为接口中默认是public修饰,若子类中没用public修饰,则访问权限变严格了,给子类分配的是更低的访问权限。所以,在定义接口的时候强烈建议在抽象方法前加上public ,子类也加上:

package com.JavaBasicsDemo7.a;
interface A{
    String MSG = "hello";
    void print();
}
class X implements A{
//这是因为接口中默认是public修饰,若子类中没用public修饰,则访问权限变严格了,给子类分配的是更低的访问权限。所以,在定义接口的时候强烈建议在抽象方法前加上public ,子类也加上:
    void print() {
        System.out.println("接口A的抽象方法print()");
    }
}
class TestDemo {
    public static void main(String[] args){
        A a = new X();
        a.print();
    }
}

package com.JavaBasicsDemo7.a;
interface A{
    String MSG = "hello";
    void print();
}
class X implements A{
//这是因为接口中默认是public修饰,若子类中没用public修饰,则访问权限变严格了,给子类分配的是更低的访问权限。所以,在定义接口的时候强烈建议在抽象方法前加上public ,子类也加上:
  public   void print() {
        System.out.println("接口A的抽象方法print()");
    }
}
class TestDemo {
    public static void main(String[] args){
        A a = new X();
        a.print();
    }
}

案例四:

由此可见,从继承关系来说接口的限制比抽象类少:

(1)一个抽象类只能继承一个抽象父类,而接口可以继承多个接口;

(2)一个子类只能继承一个抽象类,却可以实现多个接口(在Java中,接口的主要功能是解决单继承局限问题)

package com.JavaBasicsDemo7.b;
/**
 * 由此可见,从继承关系来说接口的限制比抽象类少:
 * (1)一个抽象类只能继承一个抽象父类,而接口可以继承多个接口;
 * (2)一个子类只能继承一个抽象类,却可以实现多个接口(在Java中,接口的主要功能是解决单继承局限问题)
 */
interface A{
    public void funA();
}
interface B{
    public void funB();
}
//C接口同时继承了A和B两个接口
interface C extends A,B{//使用的是extends
    public void funC();
}
class X implements C{
    @Override
    public void funA() {
    }
    @Override
    public void funB() {
    }
    @Override
    public void funC() {
    }
}

案例五:

从接口的概念上来讲,接口只能由抽象方法和全局常量组成,但是内部结构是不受概念限制的,

正如抽象类中可以定义抽象内部类一样,在接口中也可以定义普通内部类、抽象内部类和内部接口(但从实际的开发来讲,

用户自己去定义内部抽象类或内部接口的时候是比较少见的),范例如下,在接口中定义一个抽象内部类:

package com.JavaBasicsDemo7.c;
/**
 * interface A{
 *     public void funA();
 *
 *     static interface B{//使用了static,是一个外部接口
 *         public void funB();
 *     }
 * }
 * class X implements A.B{
 *
 *     @Override
 *     public void funB() {
 *
 *     }
 *
 * }
 */
/**
 * 从接口的概念上来讲,接口只能由抽象方法和全局常量组成,但是内部结构是不受概念限制的,
 * 正如抽象类中可以定义抽象内部类一样,在接口中也可以定义普通内部类、抽象内部类和内部接口(但从实际的开发来讲,
 * 用户自己去定义内部抽象类或内部接口的时候是比较少见的),范例如下,在接口中定义一个抽象内部类:
 */
interface A {
    public void funA();
    abstract class B {//定义一个抽象内部类
        public abstract void funB();
    }
}

案例六:经典案例:仔细去想象:去理解接口的作用:

package com.JavaBasicsDemo7.Interface;
public interface USBA {
    public void turnOn(); //设备启动'
    public void turnruning();  //设备运行
    public void turnOff();  //设备关闭
    public void name(); //设备名称
    public void color(); //设备颜色
    public void height();//设备高度
    public void weight();//设备宽度
    public void length(); //设备长度
}
package com.JavaBasicsDemo7.Interface;
public class ElectronicWhiteboard  implements USBA{
    @Override
    public void turnOn() {
        // TODO Auto-generated method stub
        System.out.println("电子白板真在运行,打开你要的软件,并开始运行");
    }
    @Override
    public void turnruning() {
        // TODO Auto-generated method stub
        System.out.println("电子白板真在运行,正在运行这个程序,并开始运行");
    }
    @Override
    public void turnOff() {
        // TODO Auto-generated method stub
        System.out.println("电子白板结束自己运行的程序系统");
    }
    @Override
    public void name() {
        // TODO Auto-generated method stub
        System.out.println("电子白板名称为huaweiwww");
    }
    @Override
    public void color() {
        // TODO Auto-generated method stub
        System.out.println("电子白板色彩为back");
    }
    @Override
    public void height() {
        // TODO Auto-generated method stub
        System.out.println("电子白板高度为150cm");
    }
    @Override
    public void weight() {
        // TODO Auto-generated method stub
        System.out.println("电子白板宽度为200cm");
    }
    @Override
    public void length() {
        // TODO Auto-generated method stub
        System.out.println("电子白板长度为300cm");
    }
}
package com.JavaBasicsDemo7.Interface;
public class Keyboarda implements USBA {
    @Override
    public void turnOn() {
        // TODO Auto-generated method stub
        System.out.println("键盘已启动,请开始以下程序");
    }
    @Override
    public void turnruning() {
        // TODO Auto-generated method stub
        System.out.println("键盘开始运行自己设定的程序");
    }
    @Override
    public void turnOff() {
        // TODO Auto-generated method stub
        System.out.println("键盘结束自己运行的程序系统");
    }
    @Override
    public void name() {
        // TODO Auto-generated method stub
        System.out.println("键盘名称为huaweiwww");
    }
    @Override
    public void color() {
        // TODO Auto-generated method stub
        System.out.println("键盘色彩为back");
    }
    @Override
    public void height() {
        // TODO Auto-generated method stub
        System.out.println("键盘高度为10cm");
    }
    @Override
    public void weight() {
        // TODO Auto-generated method stub
        System.out.println("键盘宽度为30cm");
    }
    @Override
    public void length() {
        // TODO Auto-generated method stub
        System.out.println("键盘长度为80cm");
    }
}
package com.JavaBasicsDemo7.Interface;
public class Mousea  implements USBA {
    @Override
    public void turnOn() {
        // TODO Auto-generated method stub
        System.out.println("鼠标已启动,请开始以下程序");
    }
    @Override
    public void turnruning() {
        // TODO Auto-generated method stub
        System.out.println("鼠标开始运行自己设定的程序");
    }
    @Override
    public void turnOff() {
        // TODO Auto-generated method stub
        System.out.println("鼠标结束自己运行的程序系统");
    }
    @Override
    public void name() {
        // TODO Auto-generated method stub
        System.out.println("鼠标名称为huaweiwwwe");
    }
    @Override
    public void color() {
        // TODO Auto-generated method stub
        System.out.println("鼠标色彩为back");
    }
    @Override
    public void height() {
        // TODO Auto-generated method stub
        System.out.println("鼠标高度为50mm");
    }
    @Override
    public void weight() {
        // TODO Auto-generated method stub
        System.out.println("鼠标宽度为500mm");
    }
    @Override
    public void length() {
        // TODO Auto-generated method stub
        System.out.println("鼠标长度为900mm");
    }
}
package com.JavaBasicsDemo7.Interface;
public class Phonea  implements USBA{
    @Override
    public void turnOn() {
        // TODO Auto-generated method stub
        System.out.println("手机已启动,请开始以下程序");
    }
    @Override
    public void turnruning() {
        // TODO Auto-generated method stub
        System.out.println("手机开始运行自己设定的程序");
    }
    @Override
    public void turnOff() {
        // TODO Auto-generated method stub
        System.out.println("手机结束自己运行的程序系统");
    }
    @Override
    public void name() {
        // TODO Auto-generated method stub
        System.out.println("手机名称为huaweiwww");
    }
    @Override
    public void color() {
        // TODO Auto-generated method stub
        System.out.println("手机色彩为back");
    }
    @Override
    public void height() {
        // TODO Auto-generated method stub
        System.out.println("手机高度为8cm");
    }
    @Override
    public void weight() {
        // TODO Auto-generated method stub
        System.out.println("手机宽度为15cm");
    }
    @Override
    public void length() {
        // TODO Auto-generated method stub
        System.out.println("手机长度为20cm");
    }
}
package com.JavaBasicsDemo7.Interface;
public class telephone implements USBA {
    @Override
    public void turnOn() {
        //
        System.out.println("电话已启动,请打电话");
    }
    @Override
    public void turnruning() {
        // TODO Auto-generated method stub
        System.out.println("电话开始进行联系对方");
    }
    @Override
    public void turnOff() {
        // TODO Auto-generated method stub
        System.out.println("电话结束:请把电源turnoff");
    }
    @Override
    public void name() {
        // TODO Auto-generated method stub
        System.out.println("电话名称为大哥大");
    }
    @Override
    public void color() {
        // TODO Auto-generated method stub
        System.out.println("电话色彩为开门红");
    }
    @Override
    public void height() {
        // TODO Auto-generated method stub
        System.out.println("电话高度为6cm");
    }
    @Override
    public void weight() {
        // TODO Auto-generated method stub
        System.out.println("电话宽度为12cm");
    }
    @Override
    public void length() {
        // TODO Auto-generated method stub
        System.out.println("电话长度为18cm");
    }
}
package com.JavaBasicsDemo7.Interface;
import java.util.ArrayList;
public class DwmoTesta  {
    public static void main(String[] args) {
        ArrayList<USBA> usbs =new <USBA> ArrayList ();
        usbs.add(  new Mousea());    //类
        usbs.add(new Keyboarda());
        usbs.add(new Phonea());
        usbs.add(new ElectronicWhiteboard ());
        usbs.add(new telephone ());
        System.out.println("用for循化输出内容");
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).height();
        }
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).weight();
        }
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).length();
        }
        System.out.println("设定设备的长:宽:高");
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).turnOn();   //接口方法
        }
        System.out.println("设定程序启动的系统");
        System.out.println("============================");
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).turnOff();
        }
        System.out.println("设置程序正在运行的程序");
        System.out.println("============================");
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).turnruning();
        }
        System.out.println("设置程序名称");
        System.out.println("**********************");
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).name();
        }
        System.out.println("设置设备色彩为");
        System.out.println("**********************");
        for (int i = 0; i < usbs.size(); i++) {
            usbs.get(i).color();
        }
    }
}

看懂了第六个案例说明自己对接口的定义有礼一点的了解。

相关文章
|
1月前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
124 3
|
2月前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
34 2
|
3天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
28 6
|
20天前
|
Java API
Java中内置的函数式接口
Java中内置的函数式接口
20 2
|
25天前
|
Java
在Java中如何实现接口?
实现接口是 Java 编程中的一个重要环节,它有助于提高代码的规范性、可扩展性和复用性。通过正确地实现接口,可以使代码更加灵活、易于维护和扩展。
46 3
|
24天前
|
Java
在Java中,接口之间可以继承吗?
接口继承是一种重要的机制,它允许一个接口从另一个或多个接口继承方法和常量。
69 1
|
24天前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
46 1
|
24天前
|
Java
在Java中实现接口的具体代码示例
可以根据具体的需求,创建更多的类来实现这个接口,以满足不同形状的计算需求。希望这个示例对你理解在 Java 中如何实现接口有所帮助。
37 1
|
29天前
|
Java Android开发
Eclipse 创建 Java 接口
Eclipse 创建 Java 接口
27 1
|
1月前
|
Java
java线程接口
Thread的构造方法创建对象的时候传入了Runnable接口的对象 ,Runnable接口对象重写run方法相当于指定线程任务,创建线程的时候绑定了该线程对象要干的任务。 Runnable的对象称之为:线程任务对象 不是线程对象 必须要交给Thread线程对象。 通过Thread的构造方法, 就可以把任务对象Runnable,绑定到Thread对象中, 将来执行start方法,就会自动执行Runable实现类对象中的run里面的内容。
39 1