Java学习笔记 --- 面向对象之多态

news/2024/5/19 12:42:37/文章来源:https://blog.csdn.net/a1404359447/article/details/127226313

一、基本介绍

方法或对象具有多种形态,是面向对象的三大特征,多态是建立在封装和继承之上的

二、多态的具体体现

1、方法的多态:

重写和重载就体现多态

案例演示:

package com.javase.poly_;public class PloyMethod {public static void main(String[] args) {//方法重载体现多态A a = new A();//我们传入不同的参数,调用不同的方法System.out.println(a.sum(10, 20));System.out.println(a.sum(10, 20, 30));//方法重写体现多态B b = new B();a.say();b.say();//虽然是同一方法,但根据对象不一样调用结果是不一样的。}
}class B {//父类public void say() {System.out.println("B say 方法被调用...");}
}class A extends B {//子类public int sum(int n1, int n2) {return n1 + n2;}public int sum(int n1, int n2, int n3) {return n1 + n2 + n3;}public void say() {System.out.println("A say 方法被调用...");}
}

2、对象的多态

1.一个对象的编译类型和运行类型可以不一致。

2.编译类型在定义对象时,就确定了,不能改变

3.运行类型是可以变化的。

4.编译类型看定义时 = 号的左边,运行类型看 = 号的右边。

案例演示:

Animal类

package com.javase.poly_.objectpoly_;public class Animal {public void cry() {System.out.println("动物叫...");}
}

Dog类:

package com.javase.poly_.objectpoly_;public class Dog extends Animal{public void cry() {System.out.println("小狗汪汪叫...");}
}

Cat类:

package com.javase.poly_.objectpoly_;import com.javase.super_.A;public class Cat extends Animal {public void cry() {System.out.println("小猫喵喵叫...");}
}

输出:

package com.javase.poly_.objectpoly_;public class PolyObject {public static void main(String[] args) {//animal编译类型是 Animal ,运行类型是DogAnimal animal = new Dog();animal.cry();//因为animal运行类型是Dog,所以会调用Dog里面的cry方法animal = new Cat();animal.cry();//因为animal运行类型变成了Cat,所以会调用Cat里面的cry方法}
}

三、多态的注意事项和细节讨论

多态的前提是:两个对象(类)存在继承关系

1、多态的向上转型

本质上,父类的引用指向了子类对象。

在语法上:父类类型  引用名 = new 子类类型();

编译类型看左边,运行类型看右边,可以调用父类中的所有成员,但必须遵守访问权限,不能调用子类中特有成员,最终运行效果看子类的具体实现。

案例演示:

package com.javase.poly_.detail_;public class Animal {public void eat() {System.out.println("吃");}public void run() {System.out.println("跑");}
}
package com.javase.poly_.detail_;public class Cat extends Animal {public void eat() {//方法重写System.out.println("猫吃鱼");}public void catchMouse() {//特有方法System.out.println("猫抓老鼠");}
}

输出:

package com.javase.poly_.detail_;public class PolyDetail {public static void main(String[] args) {Animal animal = new Cat();Object obj = new Cat();//Object也是Cat父类//最终运行效果看子类的具体实现,即调用方法时,从子类开始查找方法animal.eat();//猫吃鱼animal.run();//跑}
}

2、 多态的向下转型

在语法上:子类类型 引用名 = (子类类型)父类引用

只能强转父类引用,不能强转父类对象

要求父类的引用必须指向的是当前目标类型的对象

当向下转型后,可以调用子类类型中所有的成员

案例演示:

package com.javase.poly_.detail_;public class Animal {public void eat() {System.out.println("吃");}public void run() {System.out.println("跑");}
}
package com.javase.poly_.detail_;public class Cat extends Animal {public void eat() {//方法重写System.out.println("猫吃鱼");}public void catchMouse() {//特有方法System.out.println("猫抓老鼠");}
}

输出

package com.javase.poly_.detail_;public class PolyDetail {public static void main(String[] args) {Animal animal = new Cat();//多态的向下转型Cat cat = (Cat) animal;//编译类型是Cat 运行类型也是Catcat.catchMouse();//可以调用子类里面的特有方法}
}

 3、属性没有重写,属性的值看编译类型

package com.javase.poly_.detail_;public class PolyDetail01 {public static void main(String[] args) {//编译类型是Base 运行类型是 SunBase b = new Sun();System.out.println(b.n1);//属性的值看编译类型,结果为10Sun sun = new Sun();System.out.println(sun.n1);//20}
}class Base {int n1 = 10;
}class Sun extends Base {int n1 = 20;
}

4、instanceOf比较操作符,用于判断对象的运行类型是否为某个类型或某个类型的子类型。

package com.javase.poly_.detail_;public class PolyDetail02 {public static void main(String[] args) {BB bb = new BB();System.out.println(bb instanceof BB);//trueSystem.out.println(bb instanceof AA);//true//用于判断对象的运行类型是否为某个类型或某个类型的子类型//编译类型AA 运行类型BBAA aa = new BB();System.out.println(aa instanceof AA);//trueSystem.out.println(aa instanceof BB);//trueObject o = new Object();System.out.println(o instanceof AA);//false}
}class AA{}class BB extends AA {
}

四、入门练习

1.请说出下面的每条语音,哪些是正确的,哪些是错误的,为什么?

package com.javase.poly_.exercise_;public class PolyExercise01 {public static void main(String[] args) {double d = 13.4;//正确long l = (long) d;//正确System.out.println(l);//13.4int in = 5;//正确boolean b = (boolean) in;//错误,boolean不能转换成int类型Object obj = "hello";//正确 向上转型String objStr = (String) obj;//正确 向下转型System.out.println(objStr);//helloObject objPri = new Integer(5);//正确 向上转型String str = (String) objPri;//错误 指向Integer的父类引用,转成StringInteger str1 = (Integer) objPri;//正确 向下转型}
}

2.输出结果是什么:

输出:

20

20

true

10

20

五、动态绑定机制

1、当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定

2、当调用对象属性时,没有动态绑定机制,哪里声明,那里使用。

package com.javase.poly_.dynamic_;public class DynamicBinding {public static void main(String[] args) {A a = new B();System.out.println(a.sum());//40 -> 30System.out.println(a.sum1());//30 -> 20}
}class A {public int i = 10;//动态绑定机制public int sum() {//调用的子类B的getl()return getl() + 10;}public int sum1() {//当调用对象属性时,没有动态绑定机制,哪里声明,那里使用。return i + 10;}public int getl() {return i;}
}class B extends A {public int i = 20;//    public int sum() {
//        return i + 20;
//    }
//    public int sum1() {
//        return i + 10;
//    }public int getl() {return i;}
}

六、多态的应用

1、多态数组

数组的定义类型为父类类型,里面保存的实际元素类型为子类型。

案例演示:

Person类

package com.javase.poly_.polyarr_;public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.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;}public String say() {return "name=" + name + " age=" + age;}
}

Student 类 

package com.javase.poly_.polyarr_;public class Student extends Person {private double score;public Student(String name, int age, double score) {super(name, age);this.score = score;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}public String say() {return super.say() + " 成绩=" + score;}
}

Teacher类 

package com.javase.poly_.polyarr_;public class Teacher extends Person {private double salary;public Teacher(String name, int age, double salary) {super(name, age);this.salary = salary;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public String say() {return super.say() + " 薪水=" + salary;}
}

输出:

package com.javase.poly_.polyarr_;public class PolyArray {public static void main(String[] args) {Person[] persons = new Person[5];persons[0] = new Person("张三", 20);persons[1] = new Student("李四", 15, 79.5);persons[2] = new Student("王五", 16, 60.0);persons[3] = new Teacher("铁蛋", 25, 30000);persons[4] = new Teacher("二丫", 30, 60000);for (int i = 0; i < persons.length; i++) {//编译类型是Person 运行类型是根据实际情况由JVM来判断System.out.println(persons[i].say());//多态绑定机制}}
}

如何在多态数组中调用子类特有的方法:

在Teacher类 新增特有的方法

public void teach() {System.out.println("老师 " + getName() + " 正在讲课...");
}

在Student类 新增特有的方法

public void study() {System.out.println("学生 " + getName() + "正在听课...");
}

输出:

package com.javase.poly_.polyarr_;public class PolyArray {public static void main(String[] args) {Person[] persons = new Person[5];persons[0] = new Person("张三", 20);persons[1] = new Student("李四", 15, 79.5);persons[2] = new Student("王五", 16, 60.0);persons[3] = new Teacher("铁蛋", 25, 30000);persons[4] = new Teacher("二丫", 30, 60000);for (int i = 0; i < persons.length; i++) {//编译类型是Person 运行类型是根据实际情况由JVM来判断System.out.println(persons[i].say());//多态绑定机制//使用instanceof 判断 persons[i] 是不是Student类型if(persons[i] instanceof Student) {
//                Student student = ;//向下转型
//                student.study();//调用子类特有方法((Student) persons[i]).study();}else if(persons[i] instanceof Teacher) {((Teacher) persons[i]).teach();}}}
}

2、多态参数

方法定义的形参类型为父类类型,实参类型允许为子类型

案例演示:

Employee类

package com.javase.poly_.polyparameter;public class Employee {private String name;private double sal;public Employee(String name, double sal) {this.name = name;this.sal = sal;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}//计算年工资public double getAnnual() {return sal * 12;}
}

Worker类 

package com.javase.poly_.polyparameter;public class Worker extends Employee{public Worker(String name, double sal) {super(name, sal);}//子类特有方法public void work() {System.out.println("普通员工 " + getName() + " 正在工作...");}//共有方法public double getAnnual() {return super.getAnnual();}
}

 Manager类

package com.javase.poly_.polyparameter;public class Manager extends Employee{private double bonus;public Manager(String name, double sal, double bonus) {super(name, sal);this.bonus = bonus;}public double getBonus() {return bonus;}public void setBonus(double bonus) {this.bonus = bonus;}//子类特有方法public void manage() {System.out.println("经理 " + getName() + " 正在管理员工...");}//共有方法public double getAnnual() {return super.getAnnual() + bonus;}
}

输出:

package com.javase.poly_.polyparameter;public class PolyParameter {public static void main(String[] args) {Worker zs = new Worker("张三", 2000);Manager ls = new Manager("李四", 5000, 1000);PolyParameter polyParameter = new PolyParameter();polyParameter.showEmpAnnual(zs);polyParameter.showEmpAnnual(ls);polyParameter.test(zs);polyParameter.test(ls);}//获取员工的年薪public void showEmpAnnual(Employee e) {System.out.println(e.getAnnual());}public void test(Employee e) {if(e instanceof Worker) {//判断对象类型((Worker) e).work();//向下转型}else if(e instanceof Manager) {((Manager) e).manage();}}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_20707.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最新案例 | 昇思MindSpore携手信大网御推出中原AI反诈骗创新解决方案,为全民反诈筑牢防火墙

近日&#xff0c;河南信大网御科技有限公司的中原人工智能反诈骗创新解决方案与华为Atlas 800训练服务器和全场景AI框架昇思MindSpore完成兼容性测试。该方案基于昇腾AI基础软硬件平台&#xff0c;能够在短时间内对涉诈网址/APP进行识别&#xff0c;识别准确率高达99%。 据2021…

嵌入式开发为什么用C语言

有了解过嵌入式开发的人都会想要多去了解一些嵌入式方面的信息&#xff0c;那么既然是嵌入式开发肯定是要你会代码的&#xff0c;至于这些可能你还不是很了解&#xff0c;下面可以一起来了解下嵌入式开发为什么用C语言吧。 点击获取1V1嵌入式学习规划&#xff0c;现在还送100G精…

牛客网刷题-两个队列实现栈

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;《牛客网刷题》 &#x1f4ac;推…

字节跳动测试岗面试挂在2面,我复盘总结了失败原因,决定再战一次

先说下我基本情况&#xff0c;本科不是计算机专业&#xff0c;现在是学通信&#xff0c;然后做图像处理&#xff0c;可能面试官看我不是科班出身没有问太多计算机相关的问题&#xff0c;因为第一次找工作&#xff0c;字节的游戏专场又是最早开始的&#xff0c;就投递了&#xf…

Chain of Responsibility(责任链模式)

责任链模式一、概述二、结构三、适用场景四、优缺点五、实例一、概述 描述&#xff1a;如组长不能处理的金额&#xff0c;需要向经理请求&#xff0c;经理不能请求的需要向老板请求&#xff0c;这样就现成了一条链&#xff0c;每个级别都能处理这金额。而不是直接组长向老板请…

LeetCode括号的分数(三种解法)

LeetCode括号的分数题目描述方法一&#xff1a;栈方法稍微优化方法二&#xff1a;递归方法三&#xff1a;计算每一部分的贡献率分析原因结语题目描述 这道题的题意还是比较好理解的&#xff0c;一个 &#xff08;&#xff09; 就是一分&#xff0c;外层再套有括号则分数翻倍。 …

【genius_platform软件平台开发】第七十四讲:IAP在线升级OTA原理

1. BootLoader知识 1.1 概述及其作用 BootLoader可以理解成是引导程序, 它的作用是启动正式的App应用程序.。换言之,BootLoader是一个程序, App也是一个程序, BootLoader程序是用于启动App程序的. 2. IAP知识 2.1 概述 IAP&#xff08;In-Application Programming&#xf…

python与Electron联合编程记录之六(Electron调试)

Pycharm调试Electron 程序的编写过程离不开调试&#xff0c;在刚开始编写Electron程序的时候我不懂怎么调试主进程&#xff0c;只会通过Chrome的Devtools调试渲染进程&#xff0c;所以程序编写过程非常苦恼。后来决定研究下怎么调试主进程&#xff0c;我使用的是Pycharm&#x…

WebDAV之葫芦儿·派盘 + Evermusic

Evermusic-iPhone或iPad的音乐播放器和下载器。音频均衡器,低音增强器,ID3标签编辑器,播放列表管理器。 支持最流行的音频格式:MP3,AAC,M4A,WAV,AIFF,M4R。有了这个程序,您可以创建自己的音乐流媒体服务。只需将您的音乐库移至云服务,然后直接从那里收听音乐。您现…

(附源码)计算机毕业设计SSM在线考试系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

正则量词 属性方法 使用技巧

n {1,正无穷} \w 0-9A-z_ var reg /\w/g;var str abcdefg;正则匹配的两个原则 1.不会回头 匹配成功的就不会在匹配 2.贪婪模式 能匹配多就不会匹配少 n* {0,正无穷} \w 0-9A-z_ var reg /\w*/g;var str abcdefg;\d 0-9 var reg /\d*/g;var str abcdefg;## n&#xff1…

gorm中的关联操作详解

一对一 belong to 属于:可以理解为舔狗认为自己属于女神,而女神都不知道舔狗的存在 type Girl struct { Id int Name string } type Dog struct { Id int Name string GirlId int Girl Girl } 迁移 schema db.AutoMigrate(&Dog{}) //此时会将…

Linux从入门到入土②(系统管理)

文章目录系统管理Linux 中的进程和服务Service服务管理&#xff08;CentOS 6 版本-了解&#xff09;基本语法使用systemctl服务管理&#xff08;CentOS 7 版本-重点掌握&#xff09;基本语法使用chkconfig 设置后台服务的自启配置&#xff08;CentOS 6 版本&#xff09;基本语法…

mysql 关联查询连接条件

一、内连接 关键字&#xff1a;inner join on 语句&#xff1a;select * from a_table a inner join b_table b on a.a_id b.b_id; 说明&#xff1a;组合两个表中的记录&#xff0c;返回关联字段相符的记录&#xff0c;也就是返回两个表的交集&#xff08;阴影&#xff09;…

【数据结构】交换排序—冒泡排序、快速排序

目录 一、什么是交换排序&#xff1f; 二、冒泡排序 三、快速排序 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f499;一下 一、什么是交换排序&#xff1f; 1.交换排序的基本思想是两两比较待排序记录的关键字&#xff0c;若两个记录的次…

python文件操作

今日内容概要文件操作 利用python代码的编写来读写文件1.文件的概念 2.文件的操作方式 3.文件读写模式 4.文件操作模式 5.文件诸多方法 6.文件内容修改 7.文件光标移动 文件操作 1.文件的概念就是操作系统暴露给用户操作硬盘的快捷方式eg:双击一个文件,其实是从硬盘将数据加载…

Argestes 和序列问题

一 问题描述 Argestes 有很多爱好,特别喜欢解决查询问题。有一天&#xff0c;Argestes 想出了这样的问题。给出一个由 N 个非负整数组成的序列&#xff0c;a [1]&#xff0c;a [2]&#xff0c;a[3] ... a [n]。然后对序列进行 M 个操作。操作可以是以下之一。 S X Y&#xff…

Vue 2.6.13 源码解析(三)

文章目录前言一、initState二、支线2.1.initProps2.1.1.initProps---defineReactive2.1.2.initProps---proxy2.1.3.initProps---dependArray2.2. initMethods2.2.1.initMethods----bind2.3.initData2.3.1.initData---observe2.3.2.1.initData---observe---Observer类2.4.initCo…

灵遁者哲理散文:尘归尘

尘归尘 ——灵遁者 最近想到了很多过去的事情&#xff0c;往往就是一瞬间的情景&#xff0c;然而只有我自己清楚&#xff0c;这些瞬间&#xff0c;我从未忘记&#xff0c;我甚至觉得&#xff0c;它们构成了我生命中的“沉默”和“深刻”。 比如这样一个瞬间&#xff0c;我和…

猿创征文 | 国产数据库之OpenGauss数据库详解安装和使用

文章目录1、OpenGauss简介2、OpenGauss系统架构3、OpenGauss特点4、OpenGauss基本概念5、OpenGauss应用场景6、OpenGauss的安装6.1、获取安装包6.2、软硬件安装环境6.3、单节点安装6.4、一主一备节点安装1、OpenGauss简介 openGauss是一款开源关系型数据库管理系统&#xff0c…