Java SE 多态
1、多态
方法的多态
//方法重载体现多态
A a = new A();
//这里我们传入不同的参数,就会调用不同sum方法
System.out.println(a.sum(10,20));
System.out.println(a.sum(10,20,30));
//方法重写体现多态
对象的多态
- 一个对象的编译类型和运行类型可以不一致
- 编译类型在定义对象时,就确定了,不能改变
- 运行类型是可以变化的
- 编译类型看定义时 = 号 的左边,运行类型看 = 号的右边
Animal animal = new Dog();//animal编译类型是Animal,运行类型是Dog
animal = new Cat(); //animal 的运行类型变成了 Cat,编译类型仍然是 Animal
多态的向上转型
本质:父类的引用指向了子类的对象
语法:父类类型 引用名 = new 子类类型();
特点:编译类型看左边,运行类型看右边。
可以调用父类中的所有成员(须遵循访问权限)
不能调用子类中特有的成员
最终运行效果看子类(运行类型)的具体实现,
即调用方法时,按照从子类开始查找方法,然后调用,规则按方法的调用规则一致
(从子类找,子类有,则调用,子类无,则在父类找,父类有,并可以调用,则调用,父类无,从祖父类找,祖父类 有,并可以调用,则调用,祖父类无,从Object类找) 如果查找方法的过程中,找到了,但是不能访问,则报错
多态的向下转型
- 语法:子类类型 引用名 = (子类类型)父类引用;
- 只能强转父类的引用,不能强转父类的对象
- 要求父类的引用必须指向的是当前目标类型的对象
- 当向下转型后,可以调用子类类型中所有的成员
Animal animal = new Cat();
Cat cat = (Cat) animal;
属性没有重写之说!属性的值看编译类型
instanceOf 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型
System.out.println(aa instanceof AA); // true
属性看编译类型,方法看运行类型
Java的动态绑定机制
当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
(子类中没有get方法,调用了父类的get方法,但是父类的get方法中又有一个say方法,这个say方法子类也有,则这个时候调用 子类的say方法)
当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
多态数组:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
public class PloyArray {
public static void main(String[] args){ Person[] person = new Person[5];
person[0] = new Person("jack",20);
person[1] = new Student("mary",18,100);
person[2] = new Student("smith",19,30.1);
person[3] = new Teacher("scott",30,20000);
person[4] = new Teacher("king",50,25000); //循环遍历多态数组,调用say
for (int i = 0; i < person.length; i++) {
//person[i] 编译类型是 Person ,运行类型是根据实际情况由JVM来判断
System.out.println(person[i].say()); //动态绑定机制
//类型判断 + 向下转型
if (person[i] instanceof Student){//判断person[i] 的运行类型是不是Student
Student student = (Student)person[i];//向下转型
student.study();
}else if(person[i] instanceof Teacher){
((Teacher)person[i]).teach();
}else if(person[i] instanceof Person){ }else{
System.out.println("你的类型有误,请自己检查...");
}
} }
} 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 + "\t" + age;
}
} 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;
} //重写父类的say方法
@Override
public String say() {
return "学生 " + super.say() + " score =" + score;
} //特有方法
public void study(){
System.out.println("学生 " + getName() + "正在学习...");
}
} 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;
} //重写父类的say方法
@Override
public String say() {
return "老师 " + super.say() + " salary =" + salary;
} //特有方法
public void teach(){
System.out.println("老师 " + getName() + "正在授课...");
}
} /*
运行结果
jack 20
学生 mary 18 score =100.0
学生 mary正在学习...
学生 smith 19 score =30.1
学生 smith正在学习...
老师 scott 30 salary =20000.0
老师 scott正在授课...
老师 king 50 salary =25000.0
老师 king正在授课...
*/
多态参数:方法定义的形参类型为父类类型,实参类型允许为子类类型
public class PloyParameter {
public static void main(String[] args) {
Worker tom = new Worker("tom", 2500);
Manager milan = new Manager("milan", 5000, 200000);
PloyParameter ployParameter = new PloyParameter(); ployParameter.showEmpAnnual(tom);
ployParameter.showEmpAnnual(milan); ployParameter.testWork(tom);
ployParameter.testWork(milan); } public void showEmpAnnual(Employee e) { //形式参数为父类类型
System.out.println(e.getAnnual());
} public void testWork(Employee e) {
if (e instanceof Worker) {
((Worker) e).work(); //有向下转型
}else if(e instanceof Manager) {
((Manager) e).manager(); //有向下转型
}else {
System.out.println("不做处理");
}
}
} public class Employee { //父类
private String name;
private double salary; //月工资 public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
} //得到年工资的方法
public double getAnnual() {
return 12 * salary;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getSalary() {
return salary;
} public void setSalary(double salary) {
this.salary = salary;
} } public class Worker extends Employee{
public Worker(String name, double salary) {
super(name, salary);
}
public void work() {
System.out.println("普通员工" + getName() + "is working");
} @Override
public double getAnnual() { //普通员工没有其他收入,则直接调用父类方法
return super.getAnnual();
}
} public class Manager extends Employee{ private double bonus; public Manager(String name, double salary, double bonus) {
super(name, salary);
this.bonus = bonus;
} public double getBonus() {
return bonus;
} public void setBonus(double bonus) {
this.bonus = bonus;
} public void manager() {
System.out.println("经理" + getName() + "is managing");
} //重写获取年薪的方法
@Override
public double getAnnual() {
return super.getAnnual() + bonus;
}
} /*
运行结果
30000.0
260000.0
普通员工tomis working
经理milanis managing
*/
Java SE 多态的更多相关文章
- Java SE 简介 & 环境变量的配置
Java SE 简介 & 环境变量的配置 一.Java 技术的三个方向 Java 技术分为三个方向 javaSE( Java Platform Standard Edition 标准版)用来开 ...
- Java Se 基础系列(笔记) -- OO
记录所学到的关于Java Se的一些基础知识 1.对象是通过“属性(成员变量)”和“方法”来分别对应事物所具有的静态属性和动态属性 2.类(Class)是对某一类事物的抽象,对象(Object)为某个 ...
- 黑马程序员 ——Java SE(1)
----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训 ...
- Java SE 基础知识(一)
一.基础知识 1. Java SE : Java Standard Edition Java ME : Java Micro Edition Java EE : Java Enterprise Edi ...
- Java SE教程
第0讲 开山篇 读前介绍:本文中如下文本格式是超链接,可以点击跳转 >>超链接<< 我的学习目标:基础要坚如磐石 代码要十份规范 笔记要认真详实 一.java内容介绍 ...
- Java SE 开篇
一. Java SE 开篇 1. Java 基本数据类型及其对应的包装类 基本数据类型 对应的包装类 * byte Byte * boolean Boolean * char Character ...
- JAVA SE回顾及思考(1)——面向对象的特点
学习Java已经三年了,现在开始做Android开发,虽说还在用Java语言但本人现在才真真的意识到无论学什么基础才是最重要的,可能一些刚接触Java或者Android的朋友现在还体会不到基础的重要性 ...
- Java SE(1)
Java SE基础回顾 1.循环语句中的break是终止全部循环,跳出循环体:而continue是终止本次循环,跳执行下一循环 2.return语句有两个作用:返回值:结束方法的运行 3.对于java ...
- Java SE —— 专栏总集篇
前言: Java 语言,是相对于其他语言而言,门槛低,而且功能还强大的一门编程语言,本人十分看好这一门语言,但是,它也是有深度的,看过本人的<数据结构与算法>专栏的同学们有福了,因为本人在 ...
随机推荐
- java--方法/debug
一.方法的定义 1.什么是方法 方法是将具体独立功能的代码块组织称为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建后使用,该过程为方法定义: 方法创建后并不是直接运行的,需要手动十一后执行 ...
- Graphics2D类
Graphics2D类 Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管 ...
- 如何验收安卓PCBA主板的质量和性能
. 版本:v0.1 作者:河东西望 日期:2022-7-15 . 目录 1 有哪些情况需要验收? 2 有哪些验收测试? 2.1 主板测试 2.2 工程测试 2.3 性能测试 2.4 压力测试 2.5 ...
- Java + Selenium + OpenCV解决自动化测试中的滑块验证
最近工作过程中,一个常用的被测网站突然增加了滑块验证环节,导致整个自动化项目失效了. 为了解决这个滑块验证问题,在网上查阅了一些资料后,总结并实现了解决方案,现记录如下. 1.滑块验证思路 被测对象的 ...
- 「一本通 1.4 例 2」[USACO3.2]魔板 Magic Squares
[USACO3.2]魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题 ...
- 算法竞赛进阶指南0x41并查集
并查集简介 并查集的两类操作: Get 查询任意一个元素是属于哪一个集合. Merge 把两个集合合并在一起. 基本思想:找到代表元. 注意有两种方法: 使用一个固定的值(查询方便,但是在合并的时候需 ...
- SpringBoot中Tomcat和SpringMVC整合源码分析
概述 SpringBoot中集成官方的第三方组件是通过在POM文件中添加组件的starter的Maven依赖来完成的.添加相关的Maven依赖之后,会引入具体的jar包,在SpringBoot启动 ...
- 分享一些小tips
谷歌浏览器破解 google拓展商店中hackbar地址 https://chrome.google.com/webstore/detail/djmoeoifnlhjolebkehmpaocfnipk ...
- PLC中增益和偏移
y=kx+b这个直线方程,那么增益就是指k这个斜率,而偏移就是指b. 模拟量转换时一般是不需要设置这两个参数的,只有当外部信号与模块接收的信号在值上有偏差的情况下才会去调整这个参数. 如果的模块信号是 ...
- 黑马2022最新redis课程笔记知识点(面试用)持续更新
redis入门 redis的常见五种数据类型 String类型 String类型,类似于java中的String类型,常见使用get,set方法. String类型还可以存储json字符串格式. Ha ...