接口
电脑上的USB插槽其实就是现实中的接口
实现接口,本质上就是把接口方法实现
基本介绍
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来;
在接口中,抽象方法可以省略abstract关键字
在JDK7之前,接口里的所有方法都没有方法体,即都是抽象方法
在JDK8之后,接口里可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现
//写属性
public int youth = 679;
//写方法
//在接口中,抽象方法,可以省略abstract关键字
public abstract void fun();
public void hi();
//在JDK8之后,可以有默认的实现方法,但需要使用default关键字修饰
default public void ok(){
System.out.println("平平淡淡才是真啊!");
}
//在JDK8之后,可以有静态方法
public static void laugh(){
System.out.println("生活的苦乐取决于你的心态hhh");
}
接口注意事项和细节
接口不能被实例化
-
不能直接new接口,会报错,因为接口本身就是希望别的类来实现它,然后再去创建实现了接口的这个类的一个实例,
所以它本身是不可以被实例化的;
接口中所有的方法是public方法,接口中抽象方法,可以不用abstract修饰
interface A{
//以下两个方法都是抽象方法,只是写法不同罢了
public abstract void fun();
void play();
}
一个普通类实现接口,就必须将该接口的所有抽象方法都实现
如果接口中包含默认方法,普通类可以选择不重写这些默认方法
普通类实现接口时,不需要实现或重写接口中的静态方法
interface A{
//以下两个方法都是抽象方法,只是写法不同罢了
public abstract void fun();
void play();
}
//Life类实现了A接口,就必须把A中的所有方法都实现
class Life implements A{
@Override
public void fun() {
}
@Override
public void play() {
}
}
抽象类实现接口,可以不用实现接口的方法
//抽象类实现接口,不会报异常让你实现接口方法或者自己搞抽象
abstract class Tiger implements A{
}
一个类同时可以实现多个接口
接口中的属性,只能是final的,而且是public static final修饰符
比如: int a =1;实际上是public static final int a = 1;(必须初始化)
接口中属性的访问形式:接口名.属性名
接口不能继承其他的类,但是可以继承多个别的接口
interface A extends IB,IC{
}
接口的修饰符 只能是public 和默认,这点和类的修饰符是一样
public interface A{}//此时是public 修饰接口
interface A{}//此时是默认 什么都不写来修饰接口
练习
答案如下:
b是一个对象实例,a又是由public修饰的,所以输出23
a前面隐藏了static,所以其接口A可以直接访问属性a,输出23
B实现了接口A,B当然也就拥有了A的属性,也可以使用A中的方法
实现接口VS继承类
//main方法
public class Journey {
public static void main(String[] args) {
LittleMonkey wukong = new LittleMonkey("悟空");
wukong.climbing();
//让LittleMonkey实现了Fishable接口,实现swimming方法,就可以让悟空学会游泳了
wukong.swimming();
//写好Birdable接口后,让LittleMonkey实现Birdable接口,就可以让悟空学会飞行了
wukong.flying();
}
}
//猴子类(父类)
class Monkey{
private String name;
public Monkey(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void climbing(){
System.out.println(getName()+"会爬树");
}
}
//继承
//小猴子(子类)
class LittleMonkey extends Monkey implements Fishable,Birdable{
public LittleMonkey(String name) {
super(name);
}
@Override
//让LittleMonkey实现了Fishable接口,实现swimming方法,就可以让悟空学会游泳了
public void swimming() {
System.out.println(getName()+"通过学习,学会了游泳");
}
@Override
//写好Birdable接口后,让LittleMonkey实现Birdable接口,就可以让悟空学会飞行了
public void flying() {
System.out.println(getName()+"通过学习,学会了飞翔");
}
}
//接口(帮助小猴子悟空实现各个特异功能)
interface Fishable{
//等同于public abstract void swimming();
void swimming();
}
interface Birdable{
//等同于 void flying();
public abstract void flying();
}
小结
-
当子类继承了父类,就自动地拥有了父类的功能
-
如果子类需要扩展功能,可以通过实现接口的方式扩展
-
可以理解 实现接口是对java 单继承机制的一种补充
接口和继承解决的问题不同
- 继承的价值主要在于:解决代码的复用性和可维护性
- 接口的价值主要在于:设计好各种规范(方法),让其他类去实现这些方法
接口比继承更加灵活
- 继承满足is - a 的关系;eg. cat is a animal;
- 而接口只需满足like - a 的关系;eg. LittleMonkey can fly like a bird;
接口在一定程度上实现了代码解耦合【接口规范性+动态绑定】
接口的多态特性
接口引用可以指向实现了接口的类的对象
//接口体现的多态
public class Journey {
public static void main(String[] args) {
//接口的多态体现
//接口类型的变量if01 可以指向 实现了IF接口的对象实例
IF if01 = new Monster();
if01 = new Car();
}
}
interface IF{}
class Monster implements IF{}
class Car implements IF{}
//回顾复习下继承体现的多态
public class Journey {
public static void main(String[] args) {
//继承体现的多态
A a = new B();//父类型引用指向子类型对象
a = new C();
}
}
class A{}
class B extends A{}
class C extends A{}
多态数组
/**
* 给usb数组中,存放Phone 和 Camera 对象,Phone类还有一个特定的方法call(),请遍历usb数组,
* 如果是Phone对象,除了调用usb接口定义的方法外,还需要调用phone特有的方法call
*/
public class Journey {
public static void main(String[] args) {
//先看底下的几个类和接口,再回来看main方法
//多态数组 -> 接口类型数组
USB[] usbs = new USB[2];
usbs[0] = new Camera();
usbs[1] = new Phone();
for (int i = 0; i < usbs.length; i++) {
usbs[i].work();//此中仍然是有动态绑定的哟
//如果要满足需求,倘若为phone对象,不仅要调用work(),还要调用其特有的call()
//此时就需要进行类型的向下转型
if(usbs[i] instanceof Phone){//判断它的运行类型是Phone
((Phone) usbs[i]).call();//输入usb[i].call就会自动快捷转换
}
}
}
}
interface USB{
//等同于void work();
public void work();
}
class Phone implements USB{
public void call(){
System.out.println("手机可以打电话......");
}
@Override
public void work() {
System.out.println("手机工作中.....");
}
}
class Camera implements USB{
@Override
public void work() {
System.out.println("照相机工作中.....");
}
}
接口存在多态传递现象
//演示多态传递现象
public class Journey {
public static void main(String[] args) {
//接口类型可以指向实现了该接口的类的对象实例
B b = new Teacher();
//因为Teacher类没有实现A接口,所以下面这条语句报错,此时B没有继承A接口
// A a = new Teacher();
//但让B接口继承A接口后,下面这条语句就不会报错
// 这就是接口的多态传递现象
// 有点类似于Teacher通过这种方式也实现了A接口
// Teacher 实现B接口,B接口继承A接口,就相当于Teacher类也实现了A接口
A a = new Teacher();
}
}
interface A {
}
interface B extends A {
}
class Teacher implements B {
}
练习
public class Journey {
public static void main(String[] args) {
new C().pX();
}
}
interface A{
int x =0;//等价于 public static final int x = 0;
}
class B {int x = 1;}//普通属性
class C extends B implements A{
public void pX(){
//报错,Reference to 'x' is ambiguous, both 'B.x' and 'A.x' match
//x指向不明确
// System.out.println(x);
//访问接口的x就使用A.x,访问父类的x就使用super.x
System.out.println(A.x +" "+super.x);
}
}
//最后输出结果
0 1