2019.3.14 多态和接口

多态

  • 什么是多态?
    多态就是事物存在的多种形态——当全部符合以下三种情况时 就是多态

1.有继承
2.有方法重写
3.有父类引用指向子类对象

  • 样例
    定义一个Person类作为父类


    public class Person {

    private String name; //姓名

    private int age; //年龄

    public void eat(){

      System.out.println("吃吃吃");

    }

    @Override
    public String toString() {
    return "Person{" +
    "name='" + name + ''' +
    ", 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;
    }
    }

定义一个Student类继承Person


public class Student extends Person {
private double score;    //Student特有的属性

public void exam(){    //Student特有的方法

    System.out.println("考试");
}


//重写eat方法

@Override
public void eat() {

    System.out.println("学生吃食堂");
}




@Override
public String toString() {
    return "Student{" +
            "score=" + score +
            '}';
}

public double getScore() {
    return score;
}

public void setScore(double score) {
    this.score = score;
}

}

定义主函数MainClass


public class MainClass {

    public static void main(String[] args) {

        Student student = new Student();    //子类正常创建对象

        student.setName("张三");
        student.setAge(14);
        student.setScore(100);

        student.eat();
        
             //p:父类引用  Student:子类对象
        Person p = new Student();    //父类引用指向子类对象
        p.eat();

    }
}

上述MainClass中,p是Person类的一个引用,指向的是子类Student的对象,这个就是父类引用指向子类对象
student.eat();的输出与p.eat();的输出是一样的
925370-20190314142412634-1869385896.png

  • 总结:
    1.父类的变量可以引用子类的对象。
    2.当一个方法的参数类型是某个类(Person)的时候,那么不仅仅可以把这个类创建的对象传入方法,
    也可以把这个类和它的子类创建的对象传入方法。注:传的都是对象
    3.使用多态之后,只可以使用父类的方法,如果非要使用子类方法,必须强制类型转换。

对象与引用

使用上述Person类和Student类,在MainClass中新建引用


public class MainClass {

    public static void main(String[] args) {

        Student student = new Student();    //子类正常创建对象

        student.setName("张三");
        student.setAge(14);
        student.setScore(100);

        Student s1 = student;
        s1.setScore(200);
        System.out.println(student.getScore());
    }
}

那么此时的输出score为多少?
答案为200。

Student s1 = student;这句代码的意思是:新建一个变量s1也可以访问student对象——这个就叫做增加一个对“对象的”引用;
这个s1复制的是对象student的内存地址,即s1也可以操作地址中的数据。
举个例子,我有一个大名叫刘子博 这个就相当于student,我还有一个外号,那么这个外号就相当于是s1。
student和s1中存放的 都是对象Student的地址,s1和student做的修改,都是对这个地址中的东西进行修改,所以上述例子中score的输出为200。
具体图解如图所示:
925370-20190314143257390-1306612330.png

注意:一个对象可以有多个引用,可以有多个变量操作同一个对象;当一个对象没有任何变量引用时,就会销毁。

当在MainClass中定义一个方法:


public class MainClass {
public static void main(String[] args) {

    Student student = new Student();

    student.setName("张三");
    student.setAge(14);
    student.setScore(100);
        
    Person person = new Student();
    test(student);        //主函数调用的test方法
}

public static void test(Person person){

    person.eat();
    System.out.println(person.getName());
}

}

此时,主函数中调用的test方法的参数可以写什么?
答:因为父类可以引用子类,所以test里可以放student,因为studnet是Person的父类
test函数括号中的参数是person 因为student包括于person 所以test也可以加student。

接口

  • 啥是接口?
    java语言里面使用interface来声明一个接口,接口其实是一个特殊的抽象类,在接口里面的方法全部都是抽象的。
    接口代表的是一种能力;
    接口代表的是一种约定;
    能力:
    引用许超飞的Java接口这篇博客中的蜘蛛侠例子:
    需求:现在要创造一个蜘蛛侠。人有“唱歌”和“考试”的功能,蜘蛛有“爬行”和“吐丝”的功能。
    分析:首先蜘蛛侠是一个人,他有蜘蛛的能力。按照面向对象思想,可以将人和蜘蛛分别定义成抽象类。但是,不能让蜘蛛侠在继承人的同时又继承蜘蛛。
    两个原因:一、蜘蛛侠不是蜘蛛,不符合继承中 【is a】的关系;
    二、Java只支持单继承。如何解决这个问题呢?这时就要用到接口,接口是【has a】的关系。可以将蜘蛛的行为能力定义为接口,让蜘蛛侠继承人,实现蜘蛛的行为能力的接口。

    样例:
    新建一个接口“USB“


    public interface USB {
      void charge();    //充电
      void transfer();    //传输

    }

    新建一个Computer类:


    import java.io.Serializable; //有这个Serializable接口才能数据写到本地

public class Computer implements USB, Serializable {

private String name;
private int size;

@Override
public String toString() {
    return "Computer{" +
            "name='" + name + '\'' +
            ", size=" + size +
            '}';
}

public String getName() {
    return name;
}

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

public int getSize() {
    return size;
}

public void setSize(int size) {
    this.size = size;
}


//接口的实现
@Override
public void charge() {                  //所有的抽象方法都要实现

    System.out.println("充电");           //这个地方才是所谓的"实现"
}

@Override
public void transfer() {

    System.out.println("传输数据");
}

}

注意:在类中将接口中的抽象方法重写才是接口的"实现"。

  • 继承于接口的比较
    • 1.继承的不足:
      • (1)继承会导致继承树太深从而降低方法调用的效率(继承树太深是所有面向对象语言的缺点);
      • (2)不够灵活,父类的方法一定会被子类继承;
    • 2.接口的优势:
      • (1)一个类可以实现多个接口
      • (2)可以隐藏实现
  • 接口和多态
    • (1)接口不能创建对象,只能被类来实现;
    • (2)接口作为类型的变量,可以引用实现了该接口的对象;
  • 关于接口的多态

    新建一个接口“HDMI”


    public interface HDMI {

    void transferVideo();

    void transferAudio();

}

新建一个显示器类Monitor,并实现HDMI接口


public class Monitor {
//显示器的显示需要有HDMI提供图像
public void display(HDMI hdmi){

    hdmi.transferVideo();
    hdmi.transferAudio();
    System.out.println("开始显示图像和声音");
}

}

在上述的Computer类中实现HDMI接口


@Override
public void transferVideo() {
    System.out.println("传输视频");
}

@Override
public void transferAudio() {

    System.out.println("传输音频");
}

当在MainClass中新建对象
HDMI hdmi = new Computer;
那么hdmi.可以直接调用HDMI中接口的方法

hdmi.transferAudio();
hdmi.transferVideo();
当想使用hdmi.调用USB中接口的方法时,需要强制转换类型

((Computer) hdmi).charge();

当在MainClass中新建对象
Computer com = new Computer();
Monitor monitor = new Monitor();
那么
monitor.display()的小括号中可以填实现了/Monitor类用的接口HDMI/的任何一个东西
比如
monitor.display(com); 意思是电脑输出的东西显示到显示器上 可以理解为接口就是连接设备的线?

代码及工程

链接:https://pan.baidu.com/s/1hCzEeCRpidSycEx1cr3Qcg
提取码:onnr

转载于:https://www.cnblogs.com/lzb1234/p/10531105.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值