接口
一、定义
接口就是一种规则,是对行为的抽象
二、接口的定义和使用
-
接口用关键字interface来定义
public interface 接口名{}
接口不能实例化
-
接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名{}
-
接口的子类(实现类)
要么重写接口中的所有抽象方法
要么是抽象类
**注意1:**接口和类的实现关系,可以单实现,也可以多实现。
public class 类名 implements 接口名1,接口名2{}
**注意2:**实现类还可以在继承一个类的同时实现多个接口。
public class 类名 extends 父类 implements 接口名1,接口名2{}
例如:
编写带有接口和抽象类的标准javabean类:
青蛙 属性:名字,年龄 行为:吃虫子,蛙泳
狗 属性:名字,年龄 行为:吃骨头,狗刨
兔子 属性:名字,年龄 行文:吃胡萝卜
首先先定义一个接口
public interface Inter {
public abstract void eat();
public abstract void swim();
}
创建一个父类对象
public class Animal {
String name;
int 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;
}
}
创建一个Frog类对象
public class Frog extends Animal implements Inter{
public Frog(String name, int age) {
System.out.println("动物:" + name + "," + "年龄:" + age);
}
@Override
public void eat() {
System.out.println("吃虫子");
}
@Override
public void swim() {
System.out.println("蛙泳");
}
}
创建一个Dog类对象
public class Dog extends Animal implements Inter {
public Dog(String name,int age) {
System.out.println("动物:" + name + "," + "年龄:" + age);
}
@Override
public void eat() {
System.out.println("吃骨头");
}
@Override
public void swim() {
System.out.println("狗刨");
}
}
创建一个Rabbit类对象
public class Rabbit extends Animal implements Inter{
public Rabbit(String name,int age){
System.out.println("动物:" + name + "," + "年龄:" + age);
}
@Override
public void eat() {
System.out.println("吃胡萝卜");
}
@Override
public void swim() {
}
}
创建一个实现类
public class Test {
public static void main(String[] args) {
Frog f = new Frog("青蛙",1);
f.eat();
f.swim();
Dog d = new Dog("小狗",1);
d.eat();
d.swim();
Rabbit r = new Rabbit("小兔子",1);
r.eat();
r.swim();
}
}
运行结果如下:
动物:青蛙,年龄:1
吃虫子
蛙泳
动物:小狗,年龄:1
吃骨头
狗刨
动物:小兔子,年龄:1
吃胡萝卜
三、接口中成员的特点
- 成员变量
- 只能是常量
- 默认修饰符:public static final
- 构造方法
- 没有
- 成员方法
- 只能是抽象方法
- 默认修饰符:public abstract
- **JDK7以前:**接口中只能定义抽象方法
- **JDK8新特性:**接口中可以定义有方法体的方法(默认,静态)
- **JDK9新特性:**接口中可以定义私有方法
四、接口和类之间的关系
1.类和类的关系
继承关系,只能单继承,不能多继承,但是可以多层继承
2.类和接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
3.接口与接口的关系
继承关系,可以单继承,也可以多继承
四、接口的新增方法
1.JDK8以后接口中新增的方法
默认方法
-
允许在接口中定义默认方法,需要使用关键字default修饰
作用:解决接口升级的问题
接口中默认方法的定义格式:
- 格式:public default 返回值类型 方法名(参数列表){}
- 范例:public default void show(){}
例如:
先定义一个接口,其中含一个默认方法
public interface Inter{
public abstract void method();
public default void specialMethod()
{
System.out.println("这是接口的一个默认方法,对象不需要重写,实现类可以直接调用");
}
}
再创建一个对象
public class Example implements Inter{
@Override
public void method()
{
System.out.println("这是一个抽象方法,对象需要重写才能使用");
}
}
当实现类想使用默认方法时,可以通过对象直接调用
public class Test{
public static void main(String[] args)
{
Example e = new Example();
e.method();
e.specialMethod();
}
}
以上代码的运行结果如下:
这是一个抽象方法,对象需要重写才能使用
这是接口的一个默认方法
接口中默认方法的注意事项:
-
默认方法不是抽象对象,所以不强制被重写。
但如果被重写,重写的时候去掉default关键字
-
public可以省略,default不能省略
-
如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
静态方法
- 允许在接口中定义静态方法,需要用static修饰
接口中静态方法的定义格式:
- 格式:public static 返回值类型 方法名(参数列表){}
- 范例:public static void show(){}
接口中静态方法的注意事项:
- 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
- public可以省略,static不能省略
例如:
先创建一个接口
public interface Inter2 {
public abstract void method();
public static void specialMethod()
{
System.out.println("这是接口的一个静态方法,实现类可以直接调用,不需创建对象");
}
}
再创建一个对象
public class Example implements Inter2{
@Override
public void method()
{
System.out.println("这是一个抽象方法,对象需要重写才能使用");
}
}
再创建一个实现类,用接口名直接调用静态方法
public class Test2 {
public static void main(String[] args)
{
Example e = new Example();
e.method();
Inter2.specialMethod();
}
}
上述代码运行结果如下:
这是一个抽象方法,对象需要重写才能使用
这是接口的一个静态方法,实现类可以直接调用,不需创建对象
2.JDK9新增的方法
私有方法
注:此方法只为Inter接口提供服务,不需要外类访问
接口中私有方法的定义格式:
-
格式1:private 返回值类型 方法名(参数列表){}
-
范例1:private void show(){}
-
格式1:private 返回值类型 方法名(参数列表){}
-
范例1:private static void method(){}
私有方法分两种:
①普通的私有方法
②静态的私有方法
例如:
public Interface Inter3{
public abstract void method1()
{
System.out.println("我是方法1");
method3();
//或者method4();
}
public abstract void method2()
{
System.out.println("我是方法2");
method3();
//或者method4();
}
private void method3()
{
System.out.println("我是重复使用的方法");
}
private static void method4()
{
System.out.println("我是重复使用的方法");
}
}
私有方法不可以被别的类使用,只提供给本接口使用!!!
私有方法不可以被别的类使用,只提供给本接口使用!!!
私有方法不可以被别的类使用,只提供给本接口使用!!!
五、接口的应用
1.接口代表规则,是行为的抽象。想要哪个类拥有一个行为,就让这个类实现对应的接口就可以了
2.当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态
六、适配器设计模式
-
设计模式是一套被反复使用、为多数人知晓、经过分类编目的、代码设计经验的总结
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
-
简单理解:设计模式就是各种套路
-
适配器设计模式:解决接口与接口实现类之间的矛盾问题
例如:
public interface Inter{ public abstract void method1(); public abstract void method2(); public abstract void method3(); public abstract void method4(); public abstract void method5(); public abstract void method6(); public abstract void method7(); public abstract void method8(); public abstract void method9(); public abstract void method10(); }
当只想使用其中一种方法时
可以创建另一个类来接收这些方法(中介)
public class InterAdapter implements Inter{ @Override public void method1(){} @Override public void method2(){} @Override public void method3(){} @Override public void method4(){} @Override public void method5(){} @Override public void method6(){} @Override public void method7(){} @Override public void method8(){} @Override public void method9(){} @Override public void method10(){} }
在用实现类去继承这个中介
其中,需要用哪种方法,就去重写哪种方法
public class InterImpl extends InterAdapter{ @Override public void method5(){ System.out.println("只用第五个方法"); } }
-
当一个接口中抽象方法过多,但是我只要使用其中一部分的时候,就可以适配器设计模式
-
书写步骤:
编写中间类XXXAdapter,实现对应接口
对接口中的抽象方法进行空实现
让真正的实现类继承中间类,并重写需要用的方法
为了避免其他类创建适配器类对象,中间的适配器类用abstract修饰。