一、简介

描述:

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

存在条件:

  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 {
}

Java基本概念:多态的更多相关文章

  1. 转!!java泛型概念(泛型类,接口,方法)

    一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(Stri ...

  2. java中实现多态的机制是什么?

    多态性是面向对象程序设计代码重用的一个重要机制,我们曾不只一次的提到Java多态性.在Java运行时多态性:继承和接口的实现一文中,我们曾详细介绍了Java实现运行时多态性的动态方法调度:今天我们再次 ...

  3. java面向对象之 多态 Polymorphism

    多态(Polymorphism):用我们通俗易懂的话来说就是子类就是父类(猫是动物,学生也是人),因此多态的意思就是:父类型的引用可以指向子类的对象. 1.多态的含义:一种类型,呈现出多种状态 主要讨 ...

  4. Java开发知识之Java的继承多态跟接口*

    Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...

  5. Java 继承和多态

                                                        Java  继承和多态 Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因 ...

  6. Java基础之多态和泛型浅析

    Java基础之多态和泛型浅析 一.前言: 楼主看了许多资料后,算是对多态和泛型有了一些浅显的理解,这里做一简单总结 二.什么是多态? 多态(Polymorphism)按字面的意思就是“多种状态”.在面 ...

  7. Java对象和多态

    Java对象和多态 (面向对象) 面向对象基础 面向对象程序设计(Object Oriented Programming) 对象基于类创建,类相当于一个模板,对象就是根据模板创建出来的实体(就像做月饼 ...

  8. 13、java中的多态

    1,多态的体现 父类的引用指向了自己的子类对象. 父类的引用也可以接收自己的子类对象.2,多态的前提 必须是类与类之间有关系.要么继承,要么实现. 通常还有一个前提:存在覆盖. 3,多态的好处 多态的 ...

  9. java异常处理、多态

    第一:GC是什么? 为什么要有GC?  第二:垃圾回收的优点和原理.并考虑2种回收机制.  第三:垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?  第 ...

  10. Java多线程概念简介 多线程中篇(一)

    Java的线程与操作系统的线程   在线程的相关介绍中,有讲到“线程的实现”分为三种:内核支持,用户级以及两者混合.(这只是一种简要的分类) Java线程在JDK1.2之前,是用户线程实现的 而在JD ...

随机推荐

  1. 自己动手实现java断点/单步调试(二)

    自从上一篇<自己动手实现java断点/单步调试(一)> 是时候应该总结一下JDI的事件了 事件类型 描述 ClassPrepareEvent 装载某个指定的类所引发的事件 ClassUnl ...

  2. 烧录失败导致boot无法加载的解决措施,再也不怕烧成砖了

    目录: 1.usb烧录时出现的问题截图 2.重新擦除boot发现失败的情况 3.解决措施 烧录失败导致boot无法加载的解决措施在烧录系统的时候经常会遇到烧录失败的情况,如果能通过再次执行烧录能烧上肯 ...

  3. Codeforces Round #589 (Div. 2) Another Filling the Grid (dp)

    题意:问有多少种组合方法让每一行每一列最小值都是1 思路:我们可以以行为转移的状态 附加一维限制还有多少列最小值大于1 这样我们就可以不重不漏的按照状态转移 但是复杂度确实不大行(减了两个常数卡过去的 ...

  4. poj2411 Mondriaan's Dream (用1*2的矩形铺)

    Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, af ...

  5. 设计模式(十八)——观察者模式(JDK Observable源码分析)

    1 天气预报项目需求,具体要求如下: 1) 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方). 2) 需要设计开放型 API,便于其他第三方也能接入气象 ...

  6. Python_小程序(云开发)

    一.云开发API初始化 wx.cloud.init({ env:'test-x1dzi', //环境ID traceUser:true //是否在控制台查看用户信息 }) 二.云开发API初始化-服务 ...

  7. python之字符串split和rsplit的方法

    1.描述 split()方法通过指定分隔符对字符串进行切片,如果参数num有指定值,则分隔num+1个子字符串,默认分隔符为所有空字符,包括空格.换行(\n).制表符(\t)等 rstrip()方法通 ...

  8. Linux命令:sysctl

    sysctl命令用于运行时配置或查看内核参数,这些参数位于/proc/sys目录下.可以使用sysctl命令来设置或重新设置网络联网功能,如:IP转发.IP碎片去除以及源路由检查等.用户可以编辑/et ...

  9. 使用SignTool对软件安装包进行数字签名(二)--进行数字签名

    四.使用signcode.exe为安装程序.库或cab包签名 1.运行signcode.exe. 2.点击"下一步",选择需要签名的文件(安装程序.库或cab包). 3.点击&qu ...

  10. 缓冲区溢出实验 2 sizeof/strlen

    实验环境.代码.及准备 https://www.cnblogs.com/lqerio/p/12870834.html vul2 下面只给出有漏洞部分的代码.Vul2问题为sizeof函数在计算时会考虑 ...