接口与interface关键字

接口

Java中,接口使用interface关键字来声明,接口中可以含有变量和方法。如:

public interface Instrument {
	void play();
	String what();
	void adjust();
}

同抽象类一样,接口也不能进行实例化,而只能声明接口变量引用实现了接口的类对象。

// 实例化
Instrument instance = new Instrument();//错误的
// 声明接口变量
Instrument instance;// 可以
instance = new InstrumentImpl();// 引用实现了接口的类对象

默认方法

可以为接口的方法提供一个默认实现,但必须用 default 修饰符对方法进行标记。

public interface Instrument {
    int AIN=1;
	void play();
	String what();
	void adjust();
	default void say(){System.out.println("默认实现");}
}

当一个类实现该接口时,如果不覆盖say方法,那么该类对象就会使用默认实现。

接口中的属性(域)

但是要注意,接口中的任何域都会被自动隐式地指定为public static final变量,也就是静态常量(并且只能是public static final的域)。即使没有写权限访问修饰,编译器也会自动指定为public,而不是包访问权限。

接口

package ch6;
public interface Instrument {
    int aValue=1;
	void play();
	String what();
	void adjust();
}

主函数

package ch7;

import ch6.Instrument;

public class IntrumentTest {
	public static void main(String[] args) {
		System.out.println(Instrument.aValue);
	}
}

在不同包中,使用Instrument.aValue能够访问就说明,Instrument.aValue的访问权限不是包访问权限,而是public的。
前面所说的意思就是,接口中绝不能含有实例域,只能拥有常量,可以把接口看成是没有实例域的抽象类。由此带来的影响就是,接口中的域需要在声明的同时就进行初始化,因为接口没有构造方法,所以final类型的域就不能在构造器初始化了。

接口中的方法

而接口中的方法都会被隐式地指定为public abstract方法,且只能是public abstract方法,这是由编译器保证的。也就是说,接口中的方法必须都是抽象方法,这么说或许有点不准确。因为在JDK1.8中,接口里可以有静态方法,也可以包含嵌套类但是没有构造方法,接口里的静态方法必须要有方法体。该静态方法不需要在子类中被实现(因为在接口中就已经实现了)。值得注意的是,在实现接口中的方法时,就必须把方法声明成public的,否则编译器将认为这个方法的访问属性是包可见性。

实现接口

要让一个类遵循某个特定的接口,需要使用implements关键字。如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法。而对于遵循某个接口的抽象类,可以不实现或部分实现该接口中的抽象方法。另外,接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法。

示例

package ch6;

import java.time.LocalDate;
// 假设根据雇员的薪水进行比较
public class Employee implements Comparable<Employee>{
	private String name;
	private double salary;
	private LocalDate hireDay;
	
	public Employee(){}
	public Employee(String n, double s, int year, int month, int day){
		name = n;
		salary = s;
		hireDay = LocalDate.of(year, month, day);
	}
	// 按byPercent%加薪
	public void raiseSalary(double byPercent){
		double raise = salary * byPercent / 100;
		salary += raise;
	}
	// 按照工资排序
	@Override
	public int compareTo(Employee obj) {
		if(this.salary > obj.salary)
		{
			return 1;// 大于则返回正数
		}
		else if(this.salary < obj.salary)
		{
			return -1;// 小于则返回负数
		}
		else
		{
			return 0;// 相等则返回0
		}
	} 
	@Override
	public String toString() {
		return "name : "+name
				+",salary :"+salary
				+",hireDay :"+hireDay;
	}
}
package ch6;

import java.util.Arrays;

public class InterfaceEmployeeTest {

	public static void main(String[] args) {
		Employee emp1 = new Employee("zhao",5000,2020,5,5);
		Employee emp2 = new Employee("qian",4000,2020,4,4);
		Employee emp3 = new Employee("sun",3000,2020,3,3);
		Employee emp4 = new Employee("li",2000,2020,2,2);
		Employee emp5 = new Employee("zhou",1000,2020,1,1);
		
		Employee[] emps = new Employee[]{emp1,emp2,emp3,emp4,emp5};
		// 排序
		Arrays.sort(emps);
		for(Employee e: emps)
		{
			System.out.println(e.toString());
		}
	}
}

接口间的继承

接口之间的继承,同样使用extends关键字来声明,但是有点区别于具体类或者抽象类的继承,接口可以同时继承好几个接口(多重继承)。所以从这个角度看,接口就是为了弥补Java不能多重继承的缺点,这是Java中唯一可以多重继承的地方,而具体类或抽象类只能继承一个类。这点需要注意一下。

示例

interface Monster{
	void menace();
}
interface Lethal{
	void kill();
}
interface Vampire extends Monster,Lethal{
	void drinkBlood();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值