【 接口、多态 】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Sugar_i/article/details/81148131

迪米特法则:主要解决重复代码问题。(了解即可)
这里写图片描述
解决的问题:
接口升级,解决实现类需要覆盖重写。

接口的格式

public interface 接口名称{
   //接口内容
}

虽然使用了interface关键字,但是编译后产生的的字节码文件仍然是.class文件
接口当中的组成部分。

定义接口的基本格式(外层框架)

public interface 接口名称{
    1、常量  
    2、抽象方法
    3、默认方法  // java8
    4、静态方法  // java8
    5、私有方法  // java9
}

抽象方法的定义格式:

public abstract 返回值类型 方法名称(参数列表);

备注
1、public abstract两个关键字在接口当中可以省略,就算不写,也照样是public abstract
2、对于方法的三要素,没有要求。

使用接口当中的抽象方法

  • 1、不能直接new接口
  • 2、必须有一个实现类,去实现接口
public class 实现类名称 implements 接口名称{
    // .....
}
  • 3、实现类当中必须覆盖重写所有的抽象方法。
  • 4、创建实现类对象进行使用。

从java8开始,接口里面可以定义默认方法

public defalut 返回值类型 方法名称(参数列表){
    // 方法体
}

备注:

  • 1、public关键字可以省略,就算不写,也照样是public的。但是default关键字不能省略
  • 2、这是Java 8特性之一。
  • 3、接口当中的默认方法一般不强制要求覆盖重写。
  • 4、然而实现类也是可以对默认方法进行覆盖重写的。

java 8还允许接口当中定义静态方法
如果一个方法和对象无关,那么就可以定义成静态方法。
格式:

public static 返回值类型 方法名称(参数列表){
    方法体
}

备注:
public可以省略,static不能省略。

使用格式

接口名称.静态方法名(参数);

注意:
接口当中的静态方法使用,不能通过实现类对象调用。

从java9开始,接口当中允许定义私有方法

public interface 接口名称{
    // 普通的私有方法:
    private 返回值类型 方法名称(参数列表){
    方法体
    }
    // 静态私有方法
    private static 返回值类型 方法名称(参数列表){
    方法体
    }
}

接口当中可以包含常量。
接口中常量的格式

public static final 数据类型 常量名称 = 数据值;

注意事项:

  • 1、public static final三个关键字都可以省略,也可以省略其中的任意多个。
  • 2、final关键字代表“最终”,不可改变的意思。
  • 3、接口当中的常量,必须进行赋值,不能不赋值。
  • 4、接口当中的常量,命名规则为:所有的字母一律大写,中间使用下划线分割。
  • 5、使用接口中常量的格式:接口名称.常量名

格式总结:

常量:
public static final 数据类型 常量名称 =  数据值;

抽象方法:
public abstract 返回值类型 方法名称(参数列表);

默认方法:
public default 返回值类型 方法名称(参数列表){
    //方法体
}

静态方法:
public static 返回值类型 方法名称(参数列表){
    //方法体
}

私有方法;
private static 返回值类型 方法名称(参数列表){
    //方法体
}

一个类在继承父类的同事,实现多个接口的格式:

public class 类名称 extends 父类名称 implements 接口A,接口B{
    //...
}
  • 1、这个类必须覆盖重写所有的抽象方法。
  • 2、如果父类/或多个接口之前存在重复的方法抽象方法,只需要重写覆盖一个即可。
  • 3、如果这个类没有做到覆盖重写所有的重写方法,那么这个类自己也必须是一个抽象类。
  • 4、对于多个接口存在冲突的默认方法,实现类必须进行覆盖重写。
  • 5、父类的方法,优先于接口中的默认方法。
public interface 接口名 extends 父接口A, 父接口B {
    // ...
}
  • 1、类与类之间是单继承关系。
  • 2、类与接口之间是实现关系。
  • 3、接口与接口之间是多继承关系。

子接口的实现类,必须覆盖重写来自于所有接口的所有抽象方法
如果多个父接口当中存在重复的抽象方法,无所谓实现哪一个。
如果多个父接口当中存在冲突的默认方法,那么子接口必须覆盖重写默认方法,而且带着default关键字。

继承性是多态的前提:
1、要么存在父子类的继承
2、要么存在接口,实现类之间的实现关系。
这里写图片描述
对象多态性的特性:

  • 一个对象拥有多种类的形态,就叫做多态性。
    这里写图片描述
    多态性在代码当中的体现就是:左父右子,或者左接口右实现。

在继承关系当中使用多态:

父亲 对象名 = new 子类();

在实现关系当中使用多态:

接口 对象名 = new 实现类();

使用多态的时候,【重要】特点是

  • 编译看左边,运行看右边。
  • “由左边决定能不能调用,由右边决定运行的是谁。”
多态当中成员变量的`访问特点`:看new的是谁,优先用谁;如果没有,向上找父类。

直接通过对象名称`访问成员变量`: 看等号左边是谁,优先用谁;如果没有,向上找父类。

间接通过成员方法访问成员变量: 该方法属于谁,优先用谁,如果没有,向上找父类。

多态当中成员方法的访问特点:   看new 的是谁,优先用谁,如果没有,向上找父类。

向上转型:将本来一个子类对象,向上转换成为父类;
向下转型:将一个父类对象,向下转型成为子类。
这里写图片描述
对象的向上转型:格式:

父类 对象名 = new 子类();
接口 对象名 = new 实现类();

备注:
1、对象的向上转型一定是安全的。
2、有点类似于基本类型的强转。由小到大

注意:对象向上转型之后,就不能调用子类特有的方法了。

对象向下转型:还原格式:

子类 对象 = (子类)父类对象;
实现类 对象名 = (实现类)接口类型的对象;
Cat cat = (Cat)animal;

备注:
- 1、有点类似于基本类型的强制转换。
- 2、对象的向下转型不一定安全,很可能出现问题。
- 3、本来是什么类型,就向下转型成什么类型。

Animal animal = new Cat();
Cat cat = (Cat)animal;
Dog dog = (Dog) animal;// 错误,ClassCastException报错类转换异常。

通过关键字【intanceof】可以判断一个对象是不是指定类型的实例

对象 instanceof 类名称;

这将会得到一个boolean值,如果是true代表可以转换成后者类型。

注意:
一定要保证向下转型之前,首先通过instanceof判断。绝对不能直接向下转型。

// 如果animal对象确实可以转换成为Cat类的话
if (animal instanceof Cat) {
    System.out.println("喵喵喵");
    Cat cat = (Cat) animal;
    cat.eat();
    cat.catchMouse();
}
// 如果animal对象确实可以转换成为Dog类的话
if (animal instanceof Dog) {
    System.out.println("汪汪汪");
    Dog dog = (Dog) animal;
    dog.eat();
    dog.watchHouse();
}

笔记本案例分析:

这里写图片描述
此处笔记本的向上转型,第二种是隐式向上转型:
这里写图片描述
定义一个compter类和一个Usb接口,鼠标和键盘实现类,在compter类中调用usb接口。

public class Computer {

    public void powerOn() {
        System.out.println("开机");
    }

    public void powerOff() {
        System.out.println("关机");
    }

    // 使用设备
    public void useDevice(USB usb) {
        usb.open();

        if (usb instanceof Mouse) {
            Mouse mouse = (Mouse) usb;
            mouse.click();
        }
        if (usb instanceof Keyboard) {
            Keyboard key = (Keyboard) usb;
            key.type();
        }

        usb.close();
    }

}

测试类:

public static void main(String[] args) {
       Computer computer = new Computer();
       computer.powerOn();

       USB mouse = new Mouse(); // 向上转型
       computer.useDevice(mouse);

       Keyboard key = new Keyboard(); // 没有多态,这一行没有向上转型
       computer.useDevice(key); // 照样正确!照样也是向上转型

       computer.powerOff();
}

猜你喜欢

转载自blog.csdn.net/Sugar_i/article/details/81148131
今日推荐