【Java面向对象】java学习之旅17-接口

定义:

表示一种能力或者规范

使用:

  1. 使用interface关键字声明接口
  2. 接口中可以声明常量、抽象方法、静态方法、默认实现的方法
  3. 用implements关键字实现接口
  4. 实现类中需要重写实现所有的抽象方法,也可以重写接口中默认实现的方法

一个简单的接口实例:

//接口的声明用interface,可以继承多个接口
public interface MyInterface extends MyFaterInterface, MyFaterInterface2 {

    //接口中可以定义的有:
	// 常量
	public static final String NAME = "阿文";
	
	// 默认使用public static final修饰
	int AGE = 18;
	
	// 静态方法 jdk1.8+
	public static void fun1() {
		System.out.println("fun1");
	}
	
	// 默认实现的方法 jdk1.8+
	public default void fun2() {
		System.out.println("fun2");
	}
	
	// 抽象方法
	public abstract void fun3();
	
	// 默认使用public abstract修饰
	void fun4();
}

接口中的抽象方法需要子类去实现:

/**
 * 接口实现类
 */
 //类可以实现多个接口
public class MySubClass implements MyInterface, MyInterface2 {

	@Override
	// 接口默认实现的方法,也可以重写
	public void fun2() {
		System.out.println("sub-fun2");
	}

	@Override
	public void fun3() {
		System.out.println("sub-fun3");
	}

	@Override
	public void fun4() {
		System.out.println("sub-fun4");
	}

}

注意事项:

  1. 实现类及其对象都无法调用接口的静态方法,只能通过接口名调用
  2. 实现类可以获得接口中所有静态常量
  3. jdk1.8+接口中的方法不只是抽象方法,还有静态方法和默认实现的方法
  4. 一个类可以实现多个接口,用逗号分隔
  5. 接口只能继承接口,多继承,使用逗号分隔
  6. 实现类需要实现接口中的所有抽象方法,否则该类是一个抽象类

我们在主类中测试一下:

    @Test
	public void test2() {
	    //通过实现类的子类调用自身重写后的方法
		MySubClass msc = new MySubClass();
		msc.fun3();
		msc.fun4();
		msc.fun2();
		
		//接口中的静态方法只能通过自身的接口名去调用
		MyInterface.fun1();
		//msc.fun1(); 实现类的对象无法调用接口的静态方法
		//MySubClass.fun1();
		
		//接口可以自己点出自身的静态常量
		System.out.println(MyInterface.NAME);
		System.out.println(MyInterface.AGE);
		
		//实现类可以获得接口中所有静态常量
		System.out.println(msc.NAME);
		System.out.println(msc.AGE);
		System.out.println(MySubClass.NAME);
		
	}

分类:

  1. 普通接口:可以有静态常量、抽象方法、静态方法、默认实现的方法
  2. 标识接口:接口内没有任何成员,标识一种能力(如Serializable标识该类可序列化)
  3. 函数式接口:接口中只能有一个抽象方法,便于函数式编程使用

上述所示的是一般普通的接口

标识接口

 /**
 * @author  unascribed
 * @see java.io.ObjectOutputStream
 * @see java.io.ObjectInputStream
 * @see java.io.ObjectOutput
 * @see java.io.ObjectInput
 * @see java.io.Externalizable
 * @since   JDK1.1
 */
 //这种所示的是标识性的接口,该接口类强调的是一种能力,具体的实现会在java虚拟机中进行
 public interface Serializable {
 }

函数式接口:

/**
 * 自定义函数式接口
 */
 //函数式接口的注解,规定函数式接口内只定义有一个抽象方法,可以有多个其他
 //的静态方法。
@FunctionalInterface
public interface MyFunInterface {
	
	double apply(double d);
	
}

/**
 * 自定义函数式接口的实现(传统的实现方式)
 */
public class MyFunInterfaceImpl implements MyFunInterface {

	@Override
	public double apply(double d) {
		return Math.round(d * 100) * 0.01;
	}
	
}

传统用法 vs 接口的内部实现 vs 函数式编程

    @Test
	public void test3() {
		//传统用法
		MyFunInterfaceImpl mfii = new MyFunInterfaceImpl();
		double result = mfii.apply(3.1415);
		System.out.println(result);
		
		//使用接口的内部实现优化(这里默认的是创建了一个接口的隐式对象,需要我们实现里面的方法才能创建该对象。)
		MyFunInterface mfi = new MyFunInterface() {
			@Override
			public double apply(double d) {
				return Math.round(d * 1000) * 0.001;
			}
		};
		System.out.println(mfi.apply(3.1415));
		
		//使用函数式编程优化
		MyFunInterface mfi1 = d -> {return Math.round(d * 1000) * 0.001;};
		System.out.println(mfi1.apply(3.1415));
	}
接口和抽象类的异同:

相同点:

1. 都不能实例化,但是可以内部实现(匿名内部类)。
2. 都可以包含抽象方法。
3. 子类或者实现类在继承或者实现抽象类或者方法的时候,必须重写实现所有的抽象方法,否则这个类还是抽象类。
4. 抽象类和接口都是引用数据类型,都可以作为父类引用指向子类对象,实现了多态。

不同点:

1. 子类只能继承一个抽象类,可以实现多个接口。
2. 抽象类只能继承一个抽象类,接口可以继承多个接口。
3. 抽象类可以声明变量、常量,接口中只能声明常量。
4. 抽象类的成员可以使用所有权限修饰符,接口中只能使用public。
5. 抽象类有构造方法,接口没有构造方法。
6. 抽象类可以有抽象方法和普通方法,接口只有抽象方法、静态方法、默认实现的方法。
7. 抽象类可以实现接口,接口无法继承抽象类。

总结:

接口类似于抽象类但是不同于抽象类,接口最主要是提供自己的抽象方法,让子类去实现,接口不允许被创建一个新的对象,这样就可以去通过子类创建对象去调用自己的方法了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JeffHan^_^

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

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

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

打赏作者

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

抵扣说明:

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

余额充值