Java面向对象——接口详解

一、概念引入

接口其实就是一种规则,是对行为的抽象。

二、接口的定义和使用

  • 接口用关键字interface来定义:
    • public interface 接口名 { }
  • 接口不能实例化(接口不能创建对象)
  • 接口和类之间是实现关系,通过implements关键字表示:
    • public class 类名 implements 接口名 { }
  • 接口的子类(实现类):要么重写接口中的所有抽象方法 ; 要么是抽象类

注意1: 接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名1,接口名2 {}

注意2:实现类还可以在继承一个类的同时实现多个接口。
public class 类名 extends 父名 implements 接口名1,接口名2 {}

练习: 编写带有接口和抽象类的标准Javabean类
在这里插入图片描述

// 动物类 Animal.java
 
public abstract class Animal {
	private String name;
	private int age;
 
	public Animal() {}
 
	public Animal(String name, int age) {
		this.name = name;
		this.age = age;
}
 
	public String getName() {return name;}
 
	public void setName(String name) {this.name = name;}
 
	public int getAge() {return age;}
 
	public void setAge(int age) {this.age = age;}
 
	public abstract void eat();
	// 游泳不能写在父类当中
	// 写在父类当中就说明子类都会游泳
	// public abstract void swim();
}
 
//Swim接口
public interface Swim {
	//游泳接口
	public abstract void swim();
}
 
 
//Frog.java
public class Frog extends Animal implements Swim{
	
	public Frog() {}
	public Frog(String name, int age) {super(name, age);
}
	@Override
	public void eat() {
	System.out.println("青蛙在吃虫子");
	}
	
	@Override
	public void swim() {
	System.out.println("青蛙在蛙泳");
	}
}
 
//Rabbit.java
 
public class Rabbit extends Animal {
 
	public Rabbit() {}
	public Rabbit(String name, int age) {super(name, age);}
 
	@Override
	public void eat() {
		System.out.println("兔子在吃胡萝卜");
	}
}
 
//Dog.java
 
public class Dog extends Animal implements Swim{
	public Dog() {}
	public Dog(String name, int age) {super(name, age);}
 
 
	@Override
	public void eat() {
		System.out.println("狗吃骨头");
	}
 
	@Override
	public void swim() {
		System.out.println("狗在狗刨");
	}
}
 
//测试类
public class Test {
public static void main(String[] args) {
//创建对象
	Frog f = new Frog("小青蛙",1);
	System.out.println(f.getName() +"," + f.getAge());
	f.eat();
	f.swim();
	
	Rabbit r = new Rabbit("小兔子",1);
	System.out.println(r.getName() + "," + r.getAge());
	r.eat();
	//r.swim();
}
}

三、 接口中成员的特点

成员变量

只能是常量
默认修饰符:public static final

构造方法

没有

成员方法

只能是抽象方法
默认修饰符:public abstract

  • JDK7以前:接口类只能定义抽象方法。
  • JDK8的新特性:接口中可以定义有方法体的方法。
  • JDK9的新特性:接口中可以定义私有方法。

四、 接口和类之间的关系

1. 类与类之间

继承关系,只能单继承,不能多继承,但是可以多层继承。

2. 类与接口之间

  • 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口。
  • 两个接口中有同名方法只需要重写一次。
//接口1 Inter1
public interface Inter1{
     publc abstract void method1();
     publc abstract void method2();
     publc abstract void method3();
}
//接口2 Inter2
public interface Inter2{
     publc abstract void method1();
     publc abstract void method2();
     publc abstract void method3();
     publc abstract void method4();
}
//实现类  InerImpl.java
 
pubic class InerImpl implements Inter1,Inter2{
   @Override
      public void method1(){
      System.out.println(" method1 ");
  }
   @Override
      public void method2(){
      System.out.println(" method2 ");
  }
   @Override
      public void method3(){
      System.out.println(" method3 ");
  }
   @Override
      public void method4(){
      System.out.println(" method4 ");
  }
  
}

3. 接口与接口之间

  • 继承关系,可以单继承,也可以多继承。
  • 实现类实现的是最下面子接口,需要重写所有的抽象方法。
//接口1 Inter1
 
public interface Inter1{
   public abstract void method1();
}
//接口2 Inter2
 
public interface Inter2{
   public abstract void method2();
}
//接口3 Inter3
 
public interface Inter3 extends Inter1,Inter2{
    public abstract void method3();
}
//实现类 InerImpl.java
 
pubic class InerImpl implements Inter3{
   @Override
      public void method1(){
      System.out.println(" method1 ");
  }
   @Override
      public void method2(){
      System.out.println(" method2 ");
  }
   @Override
      public void method3(){
      System.out.println(" method3 ");
  }
   
}

五、接口中新增方法

JDK7以前设计好的接口后续再添加新的方法规则,那之前写好的实现类就会报错。因此之前接口发生变化,所有的实现类也就不得不随之发生变化。

所以如果在接口里面的方法可以有方法体就可以解决问题了。

1. JDK8以后接口中新增的默认方法

  • 允许在接口中定义默认方法,需要使用关键字default修饰
    作用: 解决接口升级的问题

接口中默认方法的定义格式:

  • 格式: public default 返回值类型 方法名 (参数列表) { }
  • 范例:public default void show (){ }

接口中默认方法的注意事项:

  • 默认方法不是抽象方法,所以不强制被重写。但如果被重写,重写的时候去掉default关键字。
  • public可以省略,但default不能省略
  • 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写。
//InterA  接口A
public interface InterA {
	//默认方法不是抽象方法,所以不强制被重写。
	//但如果被重写,重写的时候去掉default关键字。
	
	//抽象方法
	public abstract void method ();
	
	//默认方法
	//public 可省略 ,但是default 不能
	public default void show() {
		System.out.println("InterA接口默认方法 --- show");
	}
}
 
 
//InterB 接口B
public interface InterB {
	
	//默认方法
	public default void show() {
		System.out.println("InterB接口默认方法 --- show");
	}
}
 
 
//方法类
public class InterImpl implements InterA, InterB {
 
	@Override
	public void method() {
		System.out.println("实现类重写的抽象方法");
	}
 
	// 省略 会报错
	// 不知道调用interA中还是interB中show方法
	// 所以会自动强制重写
	@Override
	// 不能强行书写default 否则会报错
	public void show() {
		System.out.println("重写接口中的默认方法");
	}
}
//实现类
public class Test {
	public static void main(String[] args) {
 
		//创建实现类的对象
		InterImpl ii = new InterImpl();
		ii.method();  //实现类重写的抽象方法
		ii.show();   //接口默认方法 --- show
	}
}

2. JDK8以后接口中新增的静态方法

  • 允许在接口中定义定义静态方法,需要用static修饰
    接口中静态方法的定义格式:

  • 格式: public static 返回值类型 方法名 (参数列表) { }

  • 范例: public static void show() { }
    接口中静态方法的注意事项:

  • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

  • public可以省略,static不能省略

3. JDK9新增的私有方法

接口中私有方法的定义格式:

  • 格式1: private 返回值类型 方法名 (参数列表) { }
  • 范例|: private void show(){ }
  • 格式2: private static 返回值类型 方法名 (参数列表) { }
  • 范例2: private static void method () { }

六、 适配器设计模式

1.当一个接口中抽象方法过多,但是我们只要使用其中一部分的

时候,就可以适配器设计模式

2.书写步骤:

编写中间类XXXAdapter ,实现对应的接口

对接口中的抽象方法进行空实现

让真正的实现类继承中间类,并重写需要用的方法

为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林玖1024

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

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

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

打赏作者

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

抵扣说明:

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

余额充值