接口的使用

目录

接口的基本介绍

接口的注意事项和使用细节

接口vs继承

接口体现多态

接口体现多态数组

接口体现多态传递现象

接口的习题

第一题

第二题


接口的基本介绍

接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。

语法:

interface 接口名{

         //属性

        //方法(1.抽象方法2默认实现方法3.静态方法)

}

class 类名 implements 接口 { 自己属性; 自己方法; 必须实现的接口的抽象方法

}

小结 1.在Jdk7.0前 接口里的所有方法都没有方法体,即都是抽象方法。 2.Jdk8.0后接口可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现

代码演示:

注意:在jdk8后,可以有默认实现方法,需要使用default关键字修饰,接口中的方法默认都是抽象方法也就是说,方法不能有具体的实现,如果想要实现方法,那么需要使用default修饰,且jdk版本要在8后

package idea.chapter10.Interface;

/**
 * 演示接口的基本使用
 */
public class interface01 {
    public static void main(String[] args) {
        /*
        接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。
        语法:
        interface 接口名{
        //属性
        //方法(1.抽象方法2默认实现方法3.静态方法)
        }
        class 类名 implements 接口 { 自己属性; 自己方法; 必须实现的接口的抽象方法
        }
        小结 1.在Jdk7.0前 接口里的所有方法都没有方法体,即都是抽象方法。 2.Jdk8.0后接口可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现
         */
    }
}

interface AA {
    //可以有属性还有方法
    //属性
    public int n1 = 10;

    //方法
    //在接口中,抽象方法,可以省略abstract关键字
    public void hi();

//小结
//1.在Jdk7.0前 接口里的所有方法都没有方法体,即都是抽象方法。
//2.Jdk8.0后接口可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现

    //在jdk8后,可以有默认实现方法,需要使用default关键字修饰
    default public void ok() {
        System.out.println("ok ...");
    }

    //在jdk8后, 可以有静态方法
    public static void cry() {
        System.out.println("cry ....");
    }
}


接口的注意事项和使用细节

1)接口不能被实例化

2)接口中所有的方法是 public方法,接口中抽象方法,可以不用abstract修饰 图示: void aaa(); 实际上是 abstract void aa0; void aaa()

3)一个普通类实现接口,就必须将该接口的所有方法都实现

4)抽象类实现接口,可以不用实现接口的方法。

代码演示:

package idea.chapter10.Interface;

/**
 * 演示接口的注意实现和使用细节
 */
public class InterfaceDetail01 {
    public static void main(String[] args) {
        /*
        结论
        1)接口不能被实例化
        2)接口中所有的方法是 public方法,接口中抽象方法,可以不用abstract修饰 图示: void aaa(); 实际上是 abstract void aa0; void aaa()
        3)一个普通类实现接口,就必须将该接口的所有方法都实现。
        4)抽象类实现接口,可以不用实现接口的方法。
         */

        //1)接口不能被实例化
        //这是错误的,接口不能实例化
        //B b = new B();

    }
}

//定义了一个接口
interface B {
    //2)接口中所有的方法是 public方法,接口中抽象方法,可以不用abstract修饰 图示: void aaa(); 实际上是 abstract void aa0; void aaa()
    //这是错误的,接口中的方法都是public方法,
    //protected void hi(){};

    //因为接口的方法都是public和abstract的,因此这样写等价于 abstract public void aaa();
    void aaa();//等价于 abstract public void aaa();
}

//一个普通类实现接口,就必须将该接口的所有方法都实现。
class C implements B {
    //因为我们C类实现了B接口,所以就需要将接口中的方法全部实现
    @Override
    public void aaa() {

    }
}

//抽象类实现接口,可以不用实现接口的方法。
abstract class A implements B {
//因为A类是抽象类,所以去实现B接口,就不用实现接口中的方法    
}

5)一个类同时可以实现多个接口

6)接口中的属性,只能是final的,而且是public static final修饰符。比如:int a=1;实际上是 public static final int a=1;(必须初始化)

7)接口中属性的访问形式:接口名.属性名

8)接口不能继承其它的类,但是可以继承多个别的接口[举例]

interface A extends B,Co

9)接口的修饰符 只能是public和默认,这点和类的修饰符是一样的。

代码演示:

注意:因为接口中的属性只能是是final ,并且是public static final 修饰的,因此我们看到的是 int n1 = 1;实际上是 public static final int n1 = 1; 注意接口中的属性必须初始化,因为final修饰的属性,必须初始化,这也是为什么在接口中的属性,一定要初始化的原因

package idea.chapter10.Interface;

/**
 * 演示接口的注意实现和使用细节2
 */
public class InterfaceDetail02 {
    public static void main(String[] args) {
        /*
        结论
        5)一个类同时可以实现多个接口
        6)接口中的属性,只能是final的,而且是public static final修饰符。比如:int a=1;实际上是 public static final int a=1;(必须初始化)
        7)接口中属性的访问形式:接口名.属性名
        8)接口不能继承其它的类,但是可以继承多个别的接口[举例]
        interface A extends B,Co
        9)接口的修饰符 只能是public和默认,这点和类的修饰符是一样的。
         */

        //接口中属性的访问形式:接口名.属性名
        System.out.println(AAA.n1);
    }
}

//接口不能继承其它的类,但是可以继承多个别的接口[举例]
//此时我们的AAA接口就继承了BBB接口,和CCC接口
interface AAA extends BBB, CCC {
    //接口中的属性,只能是final的,而且是public static final修饰符。比如:int a=1;实际上是 public static final int a=1;(必须初始化)
    //因为接口中的属性只能是是final ,并且是public static final 修饰的,因此我们看到的是 int n1 = 1;实际上是 public static final int n1 = 1;
    //注意必须初始化,因为final修饰的属性,必须初始化,这也是为什么在接口中的属性,一定要初始化的原因
    int n1 = 1;//实际上是 public static final int n1 = 1;


}

interface BBB {
    int a = 10;
}


interface CCC {

}

//接口的修饰符 只能是public和默认,这点和类的修饰符是一样的。
//这样是错误的,接口不能使用private修饰 ,只能是public和默认的
//private interface DDD{
//    
//}

//一个类同时可以实现多个接口,此时我们的Dog类就实现了AAA和BBB两个接口
class Dog implements AAA, BBB {

}

接口vs继承

实现接口vs继承类

接口和继承解决的问题不同

继承的价值主要在于:解决代码的复用性和可维护性。

接口的价值主要在于:设计,设计好各种规范(方法),让其它类去实现这些方法。即更加的灵活..

接口比继承更加灵活

接口比继承更加灵活,继承是满足is- a的关系,而接口只需满足like- a的关系

思路分析:

1.我们发现,当我们继承完Monkey类中,想要继续实现其他方法,就很难了,因为Java是单继承机制,因此我们可以通过实现接口的方法来完成 。我们的猴子本来只会爬树,但是在我们继承接口后,或者可以游泳,也可以飞翔

小结:

 当子类继承了父类,就自动的拥有父类的功能

 如果子类需要扩展功能,可以通过实现接口的方式扩展.

 可以理解 实现接口 是 对java 单继承机制的一种补充.

package idea.chapter10.Interface;

/**
 * 演示继承和接口的区别
 */
public class ExtendsVsInterface {
    public static void main(String[] args) {
        LittleMonkey wuKong = new LittleMonkey("猴子");
        wuKong.climbing();
        wuKong.swimming();
        wuKong.flying();
    }
}

//定义了一个猴子类
class Monkey {
    private String name;

    public Monkey(String name) {
        this.name = name;
    }

    public void climbing() {
        System.out.println(name + " 会爬树");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

//定一个鱼的接口
interface Fish {
    void swimming();
}

//定一个鸟的接口
interface Bird {
    void flying();
}

//继承
//小结:  当子类继承了父类,就自动的拥有父类的功能
//      如果子类需要扩展功能,可以通过实现接口的方式扩展.
//      可以理解 实现接口 是 对java 单继承机制的一种补充.

//我们发现,当我们继承完Monkey类中,想要继续实现其他方法,就很难了,因为Java是单继承机制,因此我们可以通过实现接口的方法来完成
//我们的猴子本来只会爬树,但是在我们继承接口后,或者可以游泳,也可以飞翔
class LittleMonkey extends Monkey implements Fish, Bird {

    public LittleMonkey(String name) {
        super(name);
    }

    @Override
    public void swimming() {
        System.out.println(getName() + " 可以游泳");
    }

    @Override
    public void flying() {
        System.out.println(getName() + " 可以飞翔");
    }
}

接口体现多态

代码演示:

package idea.chapter10.Interface;

/**
 * 演示接口体现多态
 */
public class InterfacePolyParameter {
    public static void main(String[] args) {
        //接口体现多态
        //接口可以指向,实现了该接口类的对象实例
        IF if01 = new Monster();
        if01 = new Car();
        IF if02 = new Car();

        //继承体现多态
        Animal animal = new Cat();//向上转型
        animal = new Cat();
        Animal animal1 = new pig();
    }
}

//定义了一个接口
interface IF {
}

//定义了两个类,实现了IF接口
class Monster implements IF {
}

class Car implements IF {
}

//继承体现多态
class Animal {
}

class pig extends Animal {
}

class Cat extends Animal {
}

接口体现多态数组

思路分析:
1.因为接口也可以体现多态,所以我们的Animal接口可以指向,实现了Animal接口的对象实例,所以我们的Animal类型的数组可以存放Cat类和pig类

2.因为在Animal类中有抽象方法,所以我们的类在实现接口后就必须实现该方法

3.我们在遍历数组的过程中,判断当前数组的运行类型是什么,使用 instanceof 关键字,判断的是运行类型,和我们之前的多态数组一样,如果是当前类型的子类型
  或者就是当前类型,那么我们就向下转型,即使Cat类中和pig类中的方法名都一样都是eat方法但是,有动态绑定机制,会找到对应类中的eat方法
package idea.chapter10.Interface;

/**
 * 接口体现多态数组
 */
public class InterfacePolyArray {
    public static void main(String[] args) {
        //创建一个Animal数组
        Animal[] animal = new Animal[2];
        animal[0] = new Cat();
        animal[1] = new pig();

        /*
        思路分析:
        1.因为接口也可以体现多态,所以我们的Animal接口可以指向,实现了Animal接口的对象实例,所以我们的Animal类型的数组可以存放Cat类和pig类
        2.因为在Animal类中有抽象方法,所以我们的类在实现接口后就必须实现该方法
        3.我们在遍历数组的过程中,判断当前数组的运行类型是什么,使用 instanceof 关键字,判断的是运行类型,和我们之前的多态数组一样,如果是当前类型的子类型
          或者就是当前类型,那么我们就向下转型,即使Cat类中和pig类中的方法名都一样都是eat方法但是,有动态绑定机制,会找到对应类中的eat方法
         */
        for (int i = 0; i < animal.length; i++) {
            if (animal[i] instanceof Cat) {
                ((Cat) animal[i]).eat();
            } else if (animal[i] instanceof pig) {
                ((pig) animal[i]).eat();
            } else {
                System.out.println("不做处理");
            }
        }
    }
}

interface Animal {
    void say();

}


class Cat implements Animal {

    public void eat() {
        System.out.println("猫在吃鱼");
    }

    @Override
    public void say() {

    }
}

class pig implements Animal {

    public void eat() {
        System.out.println("猪在睡觉");
    }

    @Override
    public void say() {

    }
}

接口体现多态传递现象

思路分析:

因为IG 继承了 IH 接口,而Teacher 类实现了 IG接口
那么,实际上就相当于 Teacher 类也实现了 IH接口.
这就是 接口多态传递现象.

package idea.chapter10.Interface;

/**
 * 演示接口体现多态传递
 */
public class InterfacePolyPass {
    public static void main(String[] args) {
        //接口类型的变量可以指向,实现了该接口的类的对象实例
        IG ig = new Teacher();
        //因为IG 继承了 IH 接口,而Teacher 类实现了 IG接口
        //那么,实际上就相当于 Teacher 类也实现了 IH接口.
        //这就是 接口多态传递现象.
        IH ih = new Teacher();
    }
}

interface IH {
    void hi();
}

interface IG extends IH {
}

class Teacher implements IG {
    @Override
    public void hi() {
    }
}

接口的习题

第一题

思路分析:
1.我们要注意到接口中的属性都是 public static final修饰的
2.因为B1类实现了A1接口,所以b可以访问a
3.A1.a因为a是static的并且A1是接口所以可以直接访问
4.B1.a因为B1实现了A1接口,所以可以使用A1中的属性
package idea.chapter10.Interface;

public class InterfaceExercise01 {
    public static void main(String[] args) {
        B1 b = new B1();//ok
        System.out.println(b.a);  //23
        System.out.println(A1.a);  //23
        System.out.println(B1.a);  //23
    }
}

/*
思路分析:
1.我们要注意到接口中的属性都是 public static final修饰的
2.因为B1类实现了A1接口,所以b可以访问a
3.A1.a因为a是static的并且A1是接口所以可以直接访问
4.B1.a因为B1实现了A1接口,所以可以使用A1中的属性
 */
interface A1 {
    int a = 23; //等价 public static final int a = 23;
}

class B1 implements A1 {//正确
}

第二题

思路分析:
1.因为C类继承了B 并且实现了A 所以在直接使用x属性时候,会发现在B类中有x属性,在接口A中也有x属性,因此会报错,
  可以明确的指定x
  访问接口的 x 就使用 A.x
  访问父类的 x 就使用 super.x
2.使用接口名.属性名 访问的就是接口中的属性   使用super.属性名 访问的就是父类中的属性
package idea.chapter10.Interface;

public class InterfaceExercise02 {
    public static void main(String[] args) {
        new C().pX();
    }
}

interface A {  // 1min 看看
    int x = 0;
}  //想到 等价 public static final int x = 0;

class B {
    int x = 1;
} //普通属性

class C extends B implements A {
    public void pX() {
        /*
        思路分析:
        1.因为C类继承了B 并且实现了A 所以在直接使用x属性时候,会发现在B类中有x属性,在接口A中也有x属性,因此会报错,
          可以明确的指定x
          访问接口的 x 就使用 A.x
          访问父类的 x 就使用 super.x
        2.使用接口名.属性名 访问的就是接口中的属性   使用super.属性名 访问的就是父类中的属性         
         */
        //System.out.println(x); //错误,原因不明确x

        System.out.println(A.x + " " + super.x);
    }


}

你可能感兴趣的:(Java,java,开发语言)