Java基本概念:多态


一、简介

描述:

  • 多态性是面向对象编程中的一个重要特性,主要是用来实现动态联编的。换句话说,就是程序的最终状态只有在执行过程中才被决定,而非在编译期间就决定了。这对于大型系统来说能提高系统的灵活性和扩展性。
  • 多态允许相同类域的不同对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。
  • 多态可以让我们不用关心某个对象到底是什么具体类型,就可以使用该对象的某些方法,从而实现更加灵活的编程,提高系统的可扩展性。
  • 如果对象的编译时类型运行时类型不一致,就会造成多态

存在条件:

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

注意:

  • 多态是方法的多态,属性没有多态性。
  • 一个对象的实际类型是确定的,但是可以指向这个对象的引用的类型,却是可以是这对象实际类型的任意父类型
  • 子类继承父类,调用方法,如果该方法在子类中没有重写,那么就是调用的是子类继承父类的方法,如果重写了,那么调用的就是重写之后的方法
  • 'protected'修饰的父类方法可以被子类见到,也可以被子类重写,但是它是无法被外部所引用的,所以没有多态性
  • 通过一个变量调用其引用的对象的一个方法,编译器是否能让其编译通过,主要是看该变量类型的类中有没有定义该方法,如果有则编译通过,如果没有则编译报错。而不是看这个变量所引用的对象中有没有该方法。
  • Java中的方法调用,是运行时动态和对象绑定的,不到运行的时候,是不知道到底哪个方法被调用的。
  • 编写程序时,如果想调用运行时类型的方法,只能进行类型转换,不然通不过编译器的检查。但是如果两个没有关联的类进行强制转换,会报类型转换异常:ClassCastException

示例:

public class Test {
    public static void main(String[] args) {
        /* 编译看左,运行看右 */
        Student student = new Student();
        /* 变量person是可以指向Person类型或其子类型的对象,所以可以指向Student类型对象 */
        Person person = new Student();
        /* 变量student能调用的方法是Student类中有的方法(包括继承过来的) */
        student.say();//Student
        /* 变量person能调用的方法是Person类中有的方法 */
        person.say();//Student
    }
}

class Person {
    public void say() {
        System.out.println("Person");
    }
}

class Student extends Person {
    public void say() {
        System.out.println("Student");
    }
}

二、重写、重载、多态的关系

  1. 重载是编译时多态

    • 调用重载的方法,在编译期间就要确定调用的方法是谁,如果不能确定则编译报错 。
  2. 重写是运行时多态
    • 调用重写的方法,在运行期间才能确定这个方法到底是哪个对象中的。
    • 重写方法所属取决于调用方法的引用,在运行期间所指向的对象是谁,那么调用的就是该对象中的方法。

三、方法绑定

  • 程序执行调用方法时,系统根据相关信息,能够执行内存地址中代表该方法的代码
  • 根据绑定方法的代码的时机不同,分为静态绑定和动态绑定。

静态绑定:

  • 在编译期完成,可以提高代码执行速度。

动态绑定:

  • 通过对象调用的方法,采用动态绑定机制。
  • 这虽然让我们编程灵活,但是降低了代码的执行速度
  • Java所有方法都是JVM在运行期才进行动态绑定的。

四、'instanceof'关键字

描述:

  • 'instanceof'是Java的一个二元操作符。
  • 'instanceof'是Java的保留关键字。
  • 'instanceof'的作用是测试它左边的对象是否是它右边的类的实例,返回一个布尔值。

注意:

  • 'instanceof'左边的引用的类型与右边的类之间,必须有父子关系或子父关系,否则编译会报错。
  • 'instanceof'的布尔值结果,根据左边的引用的对象类型是否为右边的类的子类型。

示例:

public class Test {
    public static void main(String[] args) {
        Object object = new Student();
        System.out.println(object instanceof Student);//true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object);//true
        System.out.println(object instanceof Teacher);//false
        System.out.println(object instanceof String);//false
        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
    }
}

class Person {
}

class Student extends Person {
}

class Teacher extends Person {
}

五、类型转换

描述:

  • 由于多态的关系,父类引用可以指向子类对象,子类引用不能指向父类对象。当我们想要调用子类中的方法,而对象的引用类型是其父类时,就需要将该引用类型进行强制类型转换。
  • 把子类对象直接赋给父类引用叫向上转型,向上转型不用进行强制类型转换。
  • 把指向子类对象的父类引用赋给子类引用叫向下转型,需要进行强制类型转换。
  • 向上转型会丢失子类特有的方法,但是子类若重写了父类的方法,重写的子类方法仍有效。
  • 向上转型可以减少重复代码,体现了抽象编程的思想。父类引用作为形式参数,调有时用子类引用作为实际参数,就是利用了向上转型。

强制类型转换语法:

(targetType) object

示例:

public class Test {
    public static void main(String[] args) {
        Person person1 = new Student();
        Student student1 = (Student) person1;
        student1.go();//studentGo
        student1.run();//studentRun
        person1.run();//studentRun
        Object object1 = new Student();
        Person person2 = (Person) object1;
        person2.run();//studentRun
        /*
        因为object2引用的对象类型不是Student的子类型,所以以下代码会出现运行时异常:ClassCastException
            Object object2 = new Teacher();
            Student student2 = (Student) object2;
        */
    }
}

class Person {
    public void run() {
        System.out.println("personRun");
    }
}

class Student extends Person {
    public void run() {
        System.out.println("studentRun");
    }

    public void go() {
        System.out.println("studentGo");
    }
}

class Teacher extends Person {
}

(0)

相关推荐

  • 多态

    多态 即同一方法可以根据发送对象的不同而采用多种不同的行为方式 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多 注意: 多态是方法的多态,属性没有多态 有父类和子类的关系,类型转换异常: ...

  • Java基本概念:接口

    一.简介 描述: 普通类只有具体实现,抽象类具体实现和规范都有,接口只有规范! 接口就是比抽象类还抽象的抽象类,可以更加规范的对子类进行约束,全面专业地实现了规范和具体实现的分离. 抽象类还提供某些具 ...

  • Java学习——37、类的多态(二)

    类型的多态主要体现在:子类是一种父类类型. 子类通过继承扩充和发展了它的父类,子类是父类的一种特殊类型. 1.子类对象即是父类对象 子类对象包含了父类的所有成员,包括成员变量和成员方法,所以子类对象也 ...

  • Java基础之三个修饰符

    三个关键字 抽象的(abstract) 静态(static) 最终的(final) 一.抽象 1.1 什么是抽象 似是而非的,像却又不是:具备某种对象的特征,但不完整. 二. 抽象的(abstract ...

  • 继承,重写,多态

    继承 继承的本质是对某一类的抽象,从而实现对现实世界更好的建模. extends的意思是"扩展",子类是父类的扩展 java中类只有单继承,没有多继承 继承是类和类之间的一种关系. ...

  • Java学习——36、类的多态(一)

    多态性是指"一种定义,多种实现".例如,画画.同是画画,但每一个人,会画出来不同的画,这就是多态. 多态主要有方法的多态和类型的多态. 今天介绍方法的多态. 方法的多态包括方法的重 ...

  • java 面向对象编程

    什么是面向对象 回顾方法的定义与调用 方法的定义 import java.io.IOException; //Demo01 类 public class Demo01 { //main方法 publi ...

  • 面向对象编程(中)

    继承性(inheritance) 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类 中, 那么多个类无需再定义这些属性和行为,只要继承那个类即可 多个类称为子类(派生类),单独的这个类称为父类 ...

  • Java中的多态详解

    一.多态的概念 多态分为类的多态和方法的多态,类的多态就是一个类型可以有不同的表现形态,什么样的类型才会具备多态呢?只有被多个子类继承或者实现的父类才具备多态的特征,因为在运行期间可以根据具体的子类表 ...

  • Java基本概念:内部类

    一.简介 描述: 很多时候我们创建类的对象的时候并不需要使用很多次,每次只使用一次,这个时候我们就可以使用内部类了. 内部类不是在一个java源文件中编写两个平行的类,而是在一个类的内部再定义另外一个 ...

  • Java多态性:Java什么是多态?

    多态性是面向对象编程的又一个重要特征,它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义. 对面向对象来说 ...

  • Java异常处理(异常基本概念)

    一:异常的基本概念 当我们的程序在运行中出现了不合理的地方则会出现异常,异 常就是终止程序运行的指令,当一行代码出现异常之后,那么后面的代码就不再继续执行,如果要让后面的代码继续需要将异常处理,异常处 ...

  • Java分布式锁的概念以及使用优点

    普通的锁,即在单机多线程环境下,当多个线程需要访问同一个变量或代码片段时,被访问的变量或代码片段叫做临界区域,我们需要控制线程一个一个的顺序执行,否则会出现并发问题. 设置一个各个线程都能看的见的标志 ...

  • Java封装的概念详解

    一:封装的概念 Java是一门面向对象的语言,面向对象就是一种以组件化模式进行代码开发的思想,面向对象的理解你需要学完整个课程才会有感觉,面向对象有 三个基本特征:封装.继承.多态. 今天学习的是封装 ...