还在说Java中接口内容很难理解?看完这篇6000字总结你就彻底明白了!

接口

1. 概念

  • 是一种标准、规范,是接口的使用者和接口的实现者都必须遵循的约定和规范。

2. 接口相当于一个特殊的抽象类

  • 语法(基于JDK7.0版本)

    • 关键字 interface
interface 接口名{}
  • 接口在编译之后会生成独立的 .class 文件
  • 接口不能创建对象,但是可以声明引用
接口名 变量名;
  • 接口中属性都是公开、静态、常量(默认被public static final修饰)
  • 接口中的方法都是公开、抽象方法(默认被public abstract修饰)
  • 接口中没有构造方法

    注意
    接口从语法角度是一个抽象类,是对抽象类进一步的抽象;
    接口从Java分类来看,不是类

//抽象类
/*
抽象类不能单独new对象,但可以声明引用
抽象类:编译后生成独立的 .class文件
*/
abstract class MyClass{
    int a=1;//实例变量
    static int b=2;//静态变量
}
mian(){
    //接口类型的引用-->实现类的对象
    MyInter mi=new MyClass();//多态
    mi.m1();
    mi.m2();
}
//接口:共语法角度,相当于特殊的抽象类
interface MyInter{ //定义MyInter接口
    int m=1; //实例变量,默认被static修饰,同时被final修饰
    static int n=2; //静态变量,默认被final修饰
    
    public void m1(); //默认被abstract修饰
    void m2(); //默认被public abstract修饰
}

3. 实现类

  • 实现类语法
class 类名 implements 接口名{
    public void m1(){//方法
        syso();
    }
}
  • 注意
    • 如果实现类不想成为抽象类,则必须覆盖接口中所有的抽象方法,同时给予实现,否则实现类也必须定义为抽象类
    • 对接口中方法默认的访问权限为public,所以实现类覆盖接口中的方法时访问修饰符也是public。
    • 因为类中方法如果不写访问修饰符。默认的访问权限是default
  • 使用
    接口类型的引用中可以存储实现类的对象,多态的应用
  • 接口的使用语法
接口名 引用 = new 实现类类名(实参);

注意
如果以接口类型的引用调用方法,只能调用接口中有的方法

  • 案例
public class TestInter{    
	public static void main(String[] args){        
		// 接口类型的引用 --》 实现类的对象        
		MyInter mi = new MyClass();  // 多态                
		mi.m1();        
		mi.m2();        
		//mi.m3();    
	}
} 
// 接口 
interface MyInter{    
	public void m1();// 默认被abstract修饰   
	void m2(); //默认被public abstract修饰 
} 
// 接口的实现类(从语法角度:类继承一个特殊的抽象类) 
class MyClass implements MyInter{    
	public void m1(){
		System.out.println("m1方法的实现....");    
	}    
	public void m2(){        
		System.out.println("m2方法的实现....");    
	}   
	public void m3(){} 
}

4. java中接口的继承性

4.1 接口之间的继承性
  • 接口与接口之间是多继承
  • 语法
interface 接口名 extends 父接口1,父接口2{}
4.2 类和接口之间的关系
  • 类和接口是实现关系,即一个类可以实现多个接口
  • 语法
class 类名 implements 接口名1,接口名2{}
  • 注意
    如果实现类不想成为抽象类,必须覆盖所有接口中的所有方法
4.3 父类、子类和接口的关系
  • 一个类继承一个父类的同时可以实现多个接口
  • 语法
class 类名 extends 父类 implements 接口名1,接口名2{}
  • 注意
    必须先定义继承,再定义实现类

5. 接口多继承的影响

  • 让多态的应用更加的复杂和多样性。

  • 如果强制类型转换的双方有一方是接口类型,编译一定通过,运行有以下两种情况

    • 如果实际存储对象类型和要转换的类型相兼容,则运行通过;
    • 如果实际存储对象类型和要转换的类型不兼容,则运行报错,错误信息为:
      java.lang.ClassCastException (类型转换异常)

      注意
      评判是否兼容:实际存储的对象类型是否为要转换类型一种

  • 案例

public class Test6{
	public static void main(String[] args){
		MyClass mc = new MyClass();
		/*System.out.println(mc instanceof ClassA);
		System.out.println(mc instanceof IA);
		System.out.println(mc instanceof IB);
		System.out.println(mc instanceof IC);
		System.out.println(mc instanceof ID);*/
		/*IA ia = mc;
		ia.m1();
		ia.m2();
		//ia.m3();*/
		/*IB ib = mc;
		ib.m3();*/
		/*IC ic = mc;
		ic.m1();
		ic.m2();
		ic.m3();
		ic.m4();*/
		/*ID id = mc;
		id.m5();*/
		ClassA ca = mc;
		ca.m6();
	}
}
interface IA{
    void m1();
    void m2();
}
interface IB{
	void m3();
}
interface IC extends IA,IB{
	void m4();
}
interface ID{
	void m5();
}
// 类和接口的多实现
class MyClass extends ClassA implements IC,ID {
	public void m1(){
		System.out.println("m1()...");
	}
	public void m2(){
		System.out.println("m2()...");
	}
	public void m3(){
		System.out.println("m3()...");
	}
	public void m4(){
		System.out.println("m4()...");
	}
	public void m5(){
		System.out.println("m5()...");
	}
}
class ClassA{
	public void m6(){
		System.out.println("m6()...");
	}
}

6. 接口的应用场景

6.1 利用接口扩充子类的能力
  • 子类之间是单继承,当子类通过继承关系,从父类继承的功能不满足子类的功能需求时,可以利用接口扩充子类的功能需求。
  • 通常将主要功能定义在父类中,相对次要功能定义接口中
6.2 依赖倒转原则
  • 当一个类和其他类建立联系时,尽可能和父类是接口建立联系,避开直接与其子类或是实现类建立联系
    • 降低代码之间的耦合度,从而实现弱耦合
    • 提高程序的可维护性
  • 案例
public class TestComputer{
    public static void main(String[] args){
        // 创建电脑对象
        Computer c = new Computer();
        // 创建鼠标对象
        //Mouse m = new Mouse();
        //Keyboard k = new Keyboard(); // 实现类 对象对象
        //Mouse m = new Mouse();
        Fan f = new Fan();
        c.useDevice(f);
    }
}
// A类   --》使用者
class Computer{
    // 鼠标
    public void useDevice(USB usb){ //USB usb = f;  --->体现的多态
        usb.service();
    }
}
// 对电子设备 和 电脑做一个标准和规范(接口)
interface USB{
    void service();
}
// 实现类
// B类
class Mouse implements USB{
    public void service(){
        System.out.println("咔嚓...");
    }
}
// C类
class Keyboard implements USB{
    public void service(){
        System.out.println("噼里啪啦...");
    }
}
// D类
class Fan implements USB{
    public void service(){
        System.out.println("呼呼的...");
    }
}

7. 接口回调

  • 理解
    将接口对应的实现类对象作为实际参数赋值给接口类型的引用,当接口类型的引用地哦啊用方法时,实际运行的是对应实现类中的方法(覆盖),实现类作为实际参数传递给引用类型,目的是让借口的使用者完成对应的功能,这种现象称为接口回调。
  • 使用场景
    通常接口制定好之后,接口的使用者先被定义,根据需求的不同,再定义接口的实现者(先有接口的使用者,再有接口的实现者),开发时一旦出现接口回调的现象,作为开发人员,通常关注的根据需求定义接口的实现类,无需关注接口的使用者。
  • 案例
import java.util.Scanner;
public class Test_13{
	public static void main(String[] args){
		// 项目的整合
		MathTool mt = new MathToolImpl();
		MyClass mc = new MyClass(mt);
		
		mc.chaiFen();
	}
}

// 模块一:将一个 大于 6偶数进行拆分,列举出所有拆分结果,验证是否为质数(接口的使用者)
class MyClass{
	private MathTool mt;
	public MyClass(MathTool mt ){  // MathTool mt = new MathToolImpl();-->多态
		this.mt=mt;
	}
	public void chaiFen(){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个大于6的偶数:");
		int n = sc.nextInt();
		
		if(n>6 && n%2==0){
			// 用循环变量控制 拆分前一项
			for(int i=2;i<=n/2;i++){
				// 拆分前一项为 i ;后一项为 n-i
				// 验证 i 和 n-i是否为 质数
				if(mt.isPrime(i) && mt.isPrime(n-i)){
					System.out.println(n+"="+i+"+"+(n-i));
				}
			}
		}else{
			System.out.println("输入不合理....");
		}
	}
}

// 接口:制定模块一和模块二之间的标准
interface MathTool{
	boolean isPrime(int n);
}

// 模块二: 判断一个数据是否为质数  -->接口的实现者
class MathToolImpl implements MathTool{
	public boolean isPrime(int n){
		System.out.println("~~~~~~~1~~~~~~~");
		for(int i=2;i<n;i++){
			if(n%i==0){
				return false;
			}
		}
		return true;
	}
}


// 实现类:判断一个数据是否为 偶数
//如需使用此类,则必须将main()方法中的内容进行修改
class MathToolImpl2 implements MathTool{
	public boolean isPrime(int n){
		System.out.println("~~~~~~~~~~2~~~~~~~~~~~~~");
		if(n%2==0){
			return true;
		}else{
			return false;
		}
	}
}
  • 案例:利用接口回调对学生按年龄进行排序
public class TestStudent{
	public static void main(String[] args){
		// 定义 一个 Student类型数组
		Student[] ss = {
			new Student("张三",18,99.0),
			new Student("李四",38,89.0),
			new Student("王五",35,78.0),
			new Student("陆六",17,97.0)
		};
		// 对学生数组进行排序(按照什么进行排序)
		java.util.Arrays.sort(ss);
		
		for(int i=0;i<ss.length;i++){
			System.out.println(ss[i].name+"\t"+ss[i].age+"\t"+ss[i].score);
		}
	}
}

class Student implements Comparable<Student>{
	String name;
	int age;
	double score;
	public Student(){}
	public Student(String name,int age,double score){
		this.name = name;
		this.age = age;
		this.score = score;
	}
	// 制定排序规则(按照 age)
	public int compareTo(Student s){
		/*
			将 当前对象 和 指定的对象进行比较 
			    this            s
                this.age  小于 	s.age   负数,通常为 -1
                this.age  等于  s.age    0
                this.age  大于  s.age    正数 通常为 1				
		*/
		if(this.age < s.age ){
			return -1;
		}else if(this.age > s.age){
			return 1;
		}else {
			return 0;
		}
	}
}

8. 接口和抽象类的区别小结

抽象类 接口
关键字不同 abstract class interface
extends(类继承抽象类) implements(类实现接口)
属性 实例变量
静态变量
4个访问修饰符可以用于修饰属性
公开静态常量
方法 抽象方法
普通成员方法
抽象方法
静态方法(JDK8.0)
默认方法,带方法实现
私有方法(JDK9.0)
构造方法
继承关系 单继承 多继承

9. 接口的分类【了解】

9.1 常量接口
  • 接口中只有公开静态常量,没有定义任何方法

应用不广泛

9.2 标记接口
  • 空接口,接口中没有定义任何的常量,也没有 定义任何的 方法,例如IO中对象序列化
9.3 普通接口
  • 具有至少定义一个抽象方法。–》开发广泛应用
9.4 函数式接口
  • 是一种特殊的普通接口,接口中只有一个抽 象方法,对静态方法和默认方法没有要求

10. JDK高版本对接口语法升级 【了解】

10.1 JDK8.0版本接口的升级内容
  • 可以定义默认方法:
    • 语法:
default 返回值类型 方法名(形参列表){} 

注意
接口中默认方法中的default不再是访问修饰符,代表此方法可以写方法的实现部分
接口中默认方法访问权限为 public

  • 可以定义静态方法:
    • 语法
public static 返回值类型 方法名(形参列表){} 

注意
接口中静态方法默认访问权限也是 public,可以省略

  • 使用
接口名.静态方法名(实参);
10.2 JDK 9.0版本接口中升级
  • 可以定义 私有方法
    • ​ 语法:
private 返回值类型 方法名 (形参列表){} 

整理不易,喜欢请点个赞!
编者微信:1014961803,添加时请备注"CSDN"

发布了16 篇原创文章 · 获赞 15 · 访问量 1630

猜你喜欢

转载自blog.csdn.net/qq_44664231/article/details/105182842
今日推荐