接口的细节

接口

  • 概念:接口是一种特殊的抽象类,通常用于定义标准或标注额外能力。
    演示的代码如下:
package com.txw.test;
public class TestInterface{
	public static void main(String[]args){
		// USB     标准  对象与对象之间的一种链接方式
		// TYPE-C  标准  
		
		MyClass mc;		// 可以声明引用
		// mc = new MyClass();		// Error 不能创建对象
		mc = new Sub();		// 使用多态
		MyClass.m3();		// 调用静态方法
		
	}
}
// 抽象类
abstract class MyClass{
	int a;			// 属性
	static int b;   // 静态属性
	final static int C = 10;		// 静态常量
	
	public MyClass(){}				// 构造方法
	public void m1(){}				// 普通方法
	public abstract void m2();		// 抽象方法
	public static void m3(){};		// 静态方法
	
}
// 子类继承父类
class Sub extends MyClass{
	// 实现父类中的抽象方法
	public void m2(){
		
	}
}

1 语法

1.1 定义接口
  • 语法如下:
    interface 接口名{
        
    }
    
    演示的代码如下:
    interface MyInterface{
        
    }
    
1.2 接口与抽象类的异同

演示的代码如下:

package com.txw.test;
public class TestInterface2{
	public static void main(String[]args){
		// USB     标准  对象与对象之间的一种链接方式
		// TYPE-C  标准  
		MyInterface mi;
		mi = new Sub();		// 使用多态		
		MyInterface.m1();	// 调用静态方法
		System.out.println( MyInterface.MY_VALUE );
		// MyInterface.MY_VALUE2 = 300;
		System.out.println( MyInterface.MY_VALUE2);
	}
}
// 接口
interface MyInterface{
	// 公开静态常量
	public static final int MY_VALUE = 100;
	int MY_VALUE2 = 200;		// 隐式包含 public static final 
	// 静态方法
	static void m1(){
		
	}
	// 接口中的普通方法,必须使用default
	public default void m2(){
		
	}
	//公开抽象方法
	public abstract void m3();
	void m4();		// 隐式包含 public abstract	
}
// 子类实现接口
// class Sub implements MyInterface{
	
//}
  1. 相同点:

    1. 只能声明引用,不能创建对象。
      演示的代码如下:
    MyInterface mi;
    mi = new MyInterface(); // Error
    

    2)可以使用多态。
    演示的代码如下:

    MyInterface mi;
    mi = new MyClass();
    

    3)都可以定义静态方法(JDK8)。
    演示的代码如下:

    // 接口
    interface MyInterface{
    	// 静态方法
    	public static void m1(){
    		
    	}
    }
    

    4)都可以定义一般方法,接口中要使用default(非访问权限修饰符)进行修饰(JDK8)。
    演示的代码如下:

    // 接口
    interface MyInterface{
    	// 静态方法
    	static void m1(){
    		
    	}
    	// 接口中的普通方法,必须使用default
    	public default void m2(){
    		
    	}
    }
    
    1.3 不同点
  2. 接口中的属性默认为公开静态常量。
    演示的代码如下:

    interface MyInterface{
    	// 公开静态常量
    	public static final int MY_VALUE = 100;
    	int MY_VALUE2 = 200;		// 隐式包含 public static final 
    }
    
  3. 接口中的方法默认为公开抽象方法。
    演示的代码如下:

    // 接口
    interface MyInterface{
    	// 公开抽象方法
    	public abstract void m3();
    	void m4();		// 隐式包含 public abstract
    	
    }
    

    由于接口中的方法默认包含public abstract,所以如果定义一般方法,必须加入default修饰符用于区分。

  4. 接口中不能定义构造方法。

2 接口的使用方式

2.1 实现接口
  • 作用:接口必须依赖类继承(实现)后通过多态才能使用。
  • 实现接口的语法如下:
    class 类名 implements 接口名{
        
    }
    

演示的代码如下:

interface Super{
    
}
// Sub实现Super接口
class Sub implements Super{
    
}

Super也会称为Sub的一种父类型,具有继承的效果,从父类中继承属性或方法。

  • 如果接口中有抽象方法,子类不想成为抽象类则必须实现接口中的所有抽象方法。
    演示的代码如下:

    interface Super{
        void m1();
    }
    // 未实现Super类中的抽象方法,那么子类还是抽象类
    abstract class Sub1 implements Super{}
    
    // 实现Super类中的所有抽象方法,子类可以不是抽象类
    class Sub2 implements Super{
        // 实现接口中的抽象方法
        public void m1(){
            
        }
    }
    
2.2 创建对象,配合多态
  • 演示的代码如下:
    Super sup; // 接口
    sup = new Sub();		// 子类对象
    sup.m1();		// 调用方法
    
    为了更好区分类与接口,类与类之间的关系称为继承,类与接口之间的关系称为实现,接口的子类称为实现类。

3 关系

3.1 接口与接口之间可以多继承
  • 演示的代码如下:
    interface IA{
    	public void m1();
    }
    
    interface IB {
    	public void m2();
    }
    // 接口与接口之间可以继承
    // 接口与接口之间可以多继承
    interface IC extends IA,IB{
    	//I A: m1();
    	//I B: m2();
    }
    
3.2接口与类之间可以多实现

演示的代码如下:

interface IA{
	public void m1();
}

interface IB {
	public void m2();
}
// 接口与类多实现
class MyClass implements IA,IB{
	// IA: m1();
	public void m1(){}
	// IB: m2();
	public void m2(){}
}
3.3 类可以继承另外一个类并实现多个接口

演示的代码如下:

class Super{}

// MyClass继承Super并实现IA,IB接口
// 接口与类多实现
class MyClass extends Super implements IC,ID{
	//I A: m1();
	public void m1(){}
	//I B: m2();
	public void m2(){}
}

4 接口的作用【了解】

4.1 标注一个类所具备的额外能力
  • 作用:可以根据一个类所具备的能力筛选对象,更贴近现实可以更灵活的使用多态。
    演示的代码如下:
    // 动物数组
    Animal[] as = {new Dog(),new Cat(),new Bird(),new Fish(),new Cat(),new Bird(),new Dog(),new Fish()};
    		
    // 请找出所有会跑的动物
    for(int i=0; i<as.length; i++){
    	// 提取数组中的一种动物
    	Animal a = as[i];			
    	if( a instanceof Runnable ){
    		// 将a引用中的对象存储到Runnable引用里,由于可能失败需要强转
    		Runnable r = (Runnable)a;
            // 调用run方法
    		r.run();
    	}					
    }
    
4.2 标记型接口,用于授权
  • 作用:向其他类证明自己所具备的一些特点(特权)。
    演示的代码如下:
    public interface Serializable {}		// 可序列化接口
    public interface Cloneable {}			// 可克隆接口
    
4.3 使用接口更好的降低耦合
  • 耦合度:表示对象与对象的关联性,关联性强(依赖性强) 则耦合度高扩展性差。
    演示的代码如下:
    package classes;
    public class TestInterface{
    	public static void main(String[]args){
    		USB mouse = new Mouse();		// 鼠标
    		USB key = new Keyboard();		// 键盘
    		USB fan = new Fan();			// 风扇
    		USB hum = new Humidifier();		// 加湿器
    		
    		Computer com = new Computer();
    		com.setUSB1( fan );
    		//com.setComputerEquipment1( key );		// 接入鼠标 	  插入第一个接口
    		//com.setComputerEquipment2( mouse );		// 接入键盘   插入第二个接口
    		com.on();
    	}
    }
    // USB协议
    interface USB{
    	public void service();
    }
    
    class Computer{
    	// 插口
    	USB usb1;
    	USB usb2;
    	public void setUSB1(USB usb1){		// 插入鼠标
    		this.usb1  = usb1;
    	}
    	public void setUSB2(USB usb2){		// 插入键盘
    		this.usb2 = usb2;
    	}
    	// 开机
    	public void on(){
    		System.out.println("电脑开机");
    		if(usb1!=null) usb1.service();		// 鼠标提供服务
    		if(usb2!=null) usb2.service();		// 键盘提供服务
    	}
    }
    
    class Fan implements USB{			// 电风扇
    	public void service(){
    		System.out.println("吹~~~~");
    	}
    }  
    class Humidifier implements USB{		// 加湿器
    	public void service(){
    		System.out.println("降低干燥度");
    	}
    }
     class ComputerEquipment{			// 电脑外设
    	public void service(){}
    }
    
    
    class Mouse extends ComputerEquipment implements USB{									// 鼠标
    	public void service(){
    		System.out.println("控制指针移动");
    	}
    }
    
    class Keyboard extends ComputerEquipment implements USB{		// 键盘
    	public void service(){
    		System.out.println("输入信息 ");
    	}
    }
    
4.4 更好的管理常量
  • 因为接口中所有的属性默认为公开静态常量,所以使用接口便于管理常量。
    演示的代码如下:
    interface Color{			// 颜色
        int RED = 1;
        int GREEN = 2;
        int YELLOW = 3;
    }
    
4.5 函数式接口
  • JDK8配合Lambda表达式与 流式编程一起使用的手段。
    演示的代码如下:
    @FunctionalInterface
    public interface Consumer<T> {
        void accept(T t);
       	// 略
    }
    
    函数式接口声明时会使用@FuncationalInterface注解,内部只有一个抽象方法。

5 习题

  1. 关于接口和抽象类,下列说法正确的是(A C D)。
    A. 抽象类可以有构造方法,接口没有构造方法。
    B. 抽象类可以有属性,接口没有属性。
    C. 抽象类可以有非抽象方法,接口中都是抽象方法。
    D. 抽象类和接口都不能单独创建对象。
  2. 下列哪一种叙述是正确的( C)。
    A. 一个 Java 类只能实现一个接口。
    B. 一个 Java 类不能同时继承一个类和实现一个接口。
    C. 一个 Java 类可以实现多个接口。
    D. 一个 Java 类只能直接继承一个类。
  3. 仔细阅读以下代码,有几处错误代码?并修改正确。
    在这里插入图片描述
    答:
interface  IA {
    void m1();
    int a = 100;
}
class MyClass implements IA{
    public void m1() { }  // 接口中方法默认是public的,因此实现类必须也是public的
}

public class TestInterface{
    public static void main(String[] args) {
        IA ia = new MyClass();
        ia.m1();
        System.out.println(ia.a);
    }
}
  1. 仔细阅读以下代码,根据语法将代码补全。
    在这里插入图片描述
    答:
interface IA{
    void m1();
    void m2();
}
abstract class MyClassAimplements IA{
    public void m1(){}
}
class MyClassB extends MyClassA{
    public void m2() {}
}
  1. 仔细阅读以下代码,根据要求完成程序。
    在这里插入图片描述
    (1) 如果有一个类 ClassE 实现 ID 接口,如果不希望 ClassE 是抽象的,则需要实现哪些方法?
    (2) 将以下代码补充完整。
    在这里插入图片描述
    (3) 写出以下程序输出的结果。在这里插入图片描述
    答:
    I. 要实现 ma,mb,mc,md 方法
    II. 调用 mc 方法时不用强转,调用 ma/mb/md 方法时需要强转 I
    II. 输出为 5 个 true。
  2. 仔细阅读以下代码,写出程序输出的结果。
    在这里插入图片描述
    答:输出结果为 4 个 true。
    原因: 如果父类实现了某些接口,则子类自动就实现了这些接口。
  3. 仔细阅读以下代码,写出程序运行输出结果。在这里插入图片描述
    在这里插入图片描述
    答:
    输出结果
    Red Light shine in Red
    Yellow Light shine in Yellow
    Green Light shine in Green
    注:多态中方法有覆盖,执行的是覆盖之后的。
  4. 仔细阅读以下代码,写出程序输出的结果。
    在这里插入图片描述
    答:输出结果
    TeacherAteach Java
    TeacherBteach Java
    解释:本题的重点在于利用接口,把多态用在返回值类型上。getTeacher方法返回的对象是 JavaTeacher 接口类型,在 getTeacher 方法内部创建 JavaTeacher 实现类的对象,并作为返回值返回。
    注意:对于 getTeacher 的调用者而言,不需要关心 JavaTeacher 的实现类,而只要操作 JavaTeacher接口,从而 实现了弱耦合。
  5. 仔细阅读以下代码:
    在这里插入图片描述
    需要一个实现 ServiceInterface 接口的类 MyService。
    (1) 第一种方式可以让 MyService 实现 ServiceInterface 接口,即: class MyService implements ServiceInterface (2) 第二种方式可以让 MyService 继承 AbstractService 类,即: class MyService extends AbstractService
    请问:这两种方式有什么区别?AbstractService 类有什么作用?
    答:
    如果实现 ServiceImpl 接口,则必须实现其所有方法。而如果继承 AbstractService 类,则只需要覆盖其中我们感 兴趣的方法即可。在实际开发中,往往既提供接口,又提供抽象类。既可以提供接口灵活性的基础,也能够使用抽象类来减 少代码量。
  6. 仔细阅读以下代码,完成//1、//2、//3、//4 处程序。
    在这里插入图片描述
    在这里插入图片描述
    答:
    //1 处填入的代码为 Animal[] as = { new Dog(),new Cat(),new Wolf() };
    //2 处填入的代码为 for (int i = 0;i<as.length; i++){ as[i].eat(); }
    //3 4 处填入的代码为 int count = 0; for (int i = 0;i<as.length; i++){ if(as[i] instanceof Pet){ count++; Pet p = (Pet) as[i]; p.play(); }}System.out.println(count);
  7. 编程:定义一个接口 MathTool,接口中有三个抽象方法如下:
    (1) “long fact(int m);”方法的功能为:求参数的阶乘。
    (2) “long intPower(int m , int n)”方法的功能为:求 m 的 n 次方。
    (3) “boolean findFactor(int m,int n)”方法的功能为:判断参数的和是否大于 100 定义类实现接口,编写应用程序,调用接口中的 3 个方法,并将调用方法的结果输出。
    演示的代码如下:
package com.txw.test;

public class Test {
    public static void main(String[] args) {
        MathTool m = new TestMathTool();
        System.out.println(m.fact(5));
        System.out.println(m.intPower(2, 3));
        System.out.println(m.findFactor(1, 1));
    }
}
interface MathTool {
    // 求阶乘 
    public abstract long fact(int m);
    // 求m的n次方、
    public abstract long intPower(int m, int n);
    public abstract long findFactor(int m, int n);
}
class TestMathTool implements MathTool {
    @Override
    public long fact(int m) {
        long result = 1;
        for (int i = 2; i <= m; i ++) {
            result *= i;
        }
        return result;
    }
    @Override
    public long intPower(int m, int n) {
        long result = 1;
        for (int i = n; i > 0; i --) {
            result *= m;
        }
        return result;
    }
    @Override
    public long findFactor(int m, int n) {
        return 0;
    }
}
  1. 编程:验证歌德巴赫猜想:输入一个大于 6 的偶数,请输出这个偶数能被分解为哪两个质数的和。 如 10=3+7 12=5+7 要求:两个人一组合作完成。一个人负责把一个整数 n 拆分成两个整数的和,另一个人负责写一个函 数,判断某一个整数 a 是否是质数 。
    演示的代码如下:
package com.txw.test;

import java.util.Scanner;
interface MathTool{
    boolean isPrime(int n);
}
// 接口实现者 
class MathToolImpl implements MathTool{
    public boolean isPrime(int n) {
        for(int i = 2; i<= Math.sqrt(n); i++){
            if (n % i == 0)
                return false;
        }return true;
    }
}
// 接口的使用者 
public class TestGoldBach {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        MathTool mt = new MathToolImpl();
        for(int i = 2; i<=n/2; i++){
            if (mt.isPrime(i) && mt.isPrime(n - i)){
                System.out.println(n + "=" + i + "+" + (n - i));
            }
        }
    }
}
6 总结:接口与抽象类的区别
抽象类接口
属性无要求无要求默认为公开静态常量
隐式包含:public static final
一般方法静态|非静态静态|非静态静态|非静态需要使用default修饰
构造方法
抽象方法可有可无默认为公开抽象方法
隐式包含:public abstract
继承关系单继承单继承接口与接口多继承,类与接口多实现
关键字classabstract classinterface

如图所示:
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学无止路

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值