Java接口

本文详细介绍了Java接口的概念、特点、定义、继承以及多态性的使用,包括JDK8之后接口的新特性。通过示例展示了如何实现接口、接口的匿名子类以及类优先原则。接口作为契约,规范了类的行为,使得多继承成为可能。
摘要由CSDN通过智能技术生成

目录

 接口

 接口多态性,接口的匿名子类

1.有名对象,匿名子类

2.无名对象,匿名子类

JDK8之后的接口

类优先原则


 

接口的特点

  1. Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)
  2. Java接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化
  3. Java接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法
  4. 接口中没有构造方法,不能被实例化
  5. 一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口
  6. Java接口必须通过类来实现它的抽象方法
  7. 当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类
  8. 不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例
  9. 一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承.

接口

  • Java不支持多继承,因此引入了一个和类并列的结构接口,接口可以达到多继承的效果。继承的判断是“A is a B”则class A extends B,接口则不是is a关系,例如:键盘、鼠标、u盘都支持USB连接,但不能说他们is a USB连接
  • 继承的是“是不是”关系,而接口实现的是“能不能”的关系
  • 接口的本质是契约、标准、规范

 接口定义

JDK7之前只能定义以下两个

public interface 接口名{  

public static final 类型 属性 = XX;public static final可省

public abstract 返回值类型 方法(); abstract可省

}

解释:因为接口只有全局常量和抽象方法,所以可以省略

接口没有构造器,所以不能实例化

子接口可以用extends继承父接口

子类可以通过implements连接父接口

接口的继承

public interface 子接口 extends 父接口{

一些补充方法

}

可实例化的类,接口通过implements实现

public class  子类 implements 父接口名,父接口名,父接口名{

在这里面重写所有的父接口方法

}

只重写部分父接口方法,该类为抽象类

public abstract class 子类 implements 父接口名,父接口名,父接口名{

在这里面重写所有的父接口方法

}

同时继承类也继承接口

public class 子类 extend 父类 implements 父接口名,父接口名,父接口名{

在这里面重写所有的父接口方法and父类方法

缺一个没重写就是abstract类

}

 先定义两个接口,两个接口规范了实现类的必要条件,

interface Flyable {
public static final int MAX_SPEED = 50 ;
int MIN_SPEED = 10;//省略了public static final 
public abstract void fly();
}

interface Eatable {
void eat();//省略了public abstract
}
abstract class Bird implements Flyable{
	public void fly(){
		System.out.println("鸟会飞");
	}
}

class Bird_EatBugs extends Bird implements Flyable{
public void eat(){
	System.out.println("有一些鸟吃虫子");
}
}
class Eagle implements Flyable,Eatable {
public void fly(){
	System.out.println("老鹰是大鸟,也能飞");
}
public void eat(){
	System.out.println("老鹰吃肉");
}
}
public class FlyTest {
public static void main(String[] args) {
	Bird B1 = new Bird_EatBugs();
//	Bird_EatBugs.fly()不能调用,因为编译看左
	B1.fly();//抽象类只是不能实例化,并不是不能编译
	
	Bird_EatBugs B2 = new Bird_EatBugs();
	B2.fly();
	B2.eat();
	
	Eagle E1 = new Eagle();
	E1.fly();
	E1.eat();
}
}

测试

 接口多态性,接口的匿名子类

类可以有匿名子类,通过new 父类 {重写} 实现

接口也有匿名子类,通过 new 接口 {重写} 实现

1.有名对象,匿名子类

Flyable FFF = new Flyable(){//new一个名为FFF的对象
	public void fly(){
		System.out.println("不知名的可飞行生物");
	}//匿名内部需要重写
};//此时本质上new的是重写后的子类,不过没有名字
	
FFF.fly();

2.无名对象,匿名子类

public static void Method(Object obj){
	System.out.println("调用成功,接口的匿名子类也属于Object");
}

	Method(new  Flyable(){
		public void fly(){
		System.out.println("不知名的可飞行生物");
	}
		});

JDK8之后的接口

这个版本之后的接口可以定义4种内容

  • public static 接口静态方法
  • public static fianl 全局常量
  • public default 接口默认方法
  • public abstract 用于规范的抽象方法

这些结构一般能简化,但是开发中建议不要简化,只是应注意在面试中可能会遇到挖坑的情况

下面用一个例子来完整说明4个方法的用法,定义两个接口Bounceable和Rollable来规范一个可以弹也可以滚的东西,定义他们的实现类Ball,定义一个继承于Ball的Basketball类

interface Rollable {
	public static final double PI = 3.1415926535;

	public abstract void roll();// 抽象方法,等待重写

	public static void tell() {//解释这个接口的目的
		System.out.println("这个东西能够滚动");
	}//

	public default void check() {//检查能否滚动
		System.out.println("能调用,这个类能滚动");
	}
}

interface Bounceable {
	int MIN_BOUNCE = 1;//省略public static final,表示最小能弹1下
	
	void bounce();//省略public abstract,等待重写
	
	public static void tell(){//静态方法可以由接口直接调用,所以重名不用重写
		System.out.println("这个东西能弹起来");
	}
	
	public default void check() {//default方法由对象调用,重名需重写
//多接口情况下接口同名同参方法必须在实现类重写,否则接口冲突,报错
		System.out.println("能调用,这个类能弹起来");
	}
	
}


class Ball implements Bounceable,Rollable{

	@Override
	public void roll() {
		System.out.println("ball可以roll");
			}
	public void bounce() {
		System.out.println("ball可以bounce");
	}
	@Override
	public void check() {//default方法只能定义在interface中
		//通过如下重写,让check方法只能检测bounce功能
		//格式就是 接口.super.重名的默认方法();
			Bounceable.super.check();
	}
}

class Basketball extends Ball{//继承了Ball类就继承了Ball的所有接口
	public void roll(){
		System.out.println("篮球滚的很远");
	}
	public void bounce(){
		System.out.println("篮球弹性很好");
	}
	//因为父类已经重写过了check方法,所以子类可以不用重写check
	public void check(){
	//	Rollable.super.check();
	// Basketball没有直接implements两个接口,所以不能用这个方法调用
		System.out.println("篮球是弹的又高,滚的又远");
	}
}

public class InterTest {
	public static void main(String[] args) {
		System.out.println(Basketball.MIN_BOUNCE+"\t"+Basketball.PI);
		//接口静态常量,只要跟他有关的下级都能直接调用
		Rollable.tell();
		Bounceable.tell();
		//接口静态方法,只能用接口调用,与类类似
System.out.println("*******************");
		Basketball bsk = new Basketball();
		bsk.bounce();
		bsk.roll();
		//调用两个在实现类中重写的方法
		bsk.check();
System.out.println("*******************");
		Ball bo = new Ball();
		bo.bounce();
		bo.roll();
		bo.check();
	}
}

类优先原则

如果Ball定义为abstract,则可以删除Ball中重写的roll()和bounce()方法

如果Ball中重写了roll()和bounce()方法,则子类Basketball调用的是Ball中重写的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值