当前位置: 首页 > news >正文

Java学习笔记--面向对象高级(多态)

1 多态基础概念

1.1 多态理解

1.2 多态的使用场景

1.3 多态基础

1.4 练习

学生类:
属性:姓名,账号,密码
行为:work:学生的工作是学习
老师类:
属性:姓名,账号,密码
行为:work:老师的工作是教书
管理员:
属性:姓名,账号,密码
行为:work:管理员的工作是管理网站
学生管理系统:
行为:注册register
要求:能注册所有的角色
输出:姓名为张三的同学注册成功,账号zhangsan,密码123456

test1.Person

package com.itstudy.test1; public class Person { private String name;//姓名 private String account;//账号 private String password ;//密码 //无参构造方法 public Person() { } //有参构造方法 public Person(String name, String account, String password) { this.name = name; this.account = account; this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; // Changed from this.account = account; to this.account = account; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public void work(){ System.out.println("工作"); } }

test1.Student

package com.itstudy.test1; public class Student extends Person { //构造方法 public Student() { } public Student(String name, String account, String password) { super(name, account, password); } //方法重写 @Override public void work() { System.out.println("学生的工作是学习"); } }

test1.Teacher

package com.itstudy.test1; public class Teacher extends Person { //构造方法 public Teacher() { } public Teacher(String name, String account, String password) { super(name, account, password); } @Override public void work() { System.out.println("老师的工作是教书"); } }

test1.Manager

package com.itstudy.test1; public class Manager extends Person { public Manager() { } public Manager(String name, String account, String password) { super(name, account, password); } @Override public void work() { System.out.println("管理员的工作是管理网站"); } }

test1.StudentManger

package com.itstudy.test1; public class StudentManger { //定义一个方法表示注册用户 //参数Person:此时可以传递Person本身的对象,同时也可以传递Person所有的子类对象 public void register(Person person) { //输出:姓名为张三的同学注册成功,账号zhangsan,密码123456 System.out.println("姓名为" + person.getName() + "的账号注册成功,账号" + person.getAccount() + ",密码" + person.getPassword()); //传递不同的对象,调用不同类里面的work方法 person.work(); } }

test1.Test

package com.itstudy.test1; public class Test { public static void main(String[] args) { /* 学生类: 属性:姓名,账号,密码 行为:work:学生的工作是学习 老师类: 属性:姓名,账号,密码 行为:work:老师的工作是教书 管理员: 属性:姓名,账号,密码 行为:work:管理员的工作是管理网站 学生管理系统: 行为:注册register 要求:能注册所有的角色 输出:姓名为张三的同学注册成功,账号zhangsan,密码123456 */ //创建学生管理系统的对象 StudentManger sm = new StudentManger(); //创建一个学生的对象 Student stu = new Student("张三", "zhangsan", "123456"); //把stu注册到学生管理系统当中 sm.register(stu); //创建一个老师的对象 Teacher tea = new Teacher("刘亚楠", "liuyanan", "123456"); sm.register(tea); } }

1.5 小结

2 多态调用成员的特点

2.1 变量调用

调用成员变量: 编译看左边,运行也看左边
编译看左边:在把java文件编译成class文件的时候 ,看父类当中有没有这个变量,如果有编译成功,如果没有编译失败
运行看左边:在代码真正运行的时候,使用父类中的变量

2.2 方法调用

调用成员方法:编译看左边,运行看右边
编译看左边:看父类当中有没有这个方法,如果没有代码报错
运行看右边:在代码真正运行的时候,运行的是子类里面的方法,如果子类没有重写父类里面的方法,使用的还是父类

2.3 多态的弊端

多态的弊端:不能调用子类的特有方法
解决多态的弊端:把对象再转回子类类型的就可以了 例: Zi z = (Zi) f;

2.4 类型转换

转类型注意点:


// 爷爷 爸爸 儿子
//创建了爸爸的对象,赋值给了爷爷类型
//在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型

Ye y = new Fu();//创建了爸爸的对象,赋值给了爷爷类型
Fu f1 = (Fu)y;//正确
Zi z1 =(Zi)y; //报错 //创建了爸爸的对象,赋值给了爷爷类型
//在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型

解决方法:面对这种容易转错的情况,可以先对其进行判断
//判断一下,y是不是父亲类型的
if (y instanceof Fu) {
Fu f1 = (Fu) y;
f1.show();
} else {
System.out.println("请确定好类型再转换");
}

2.5 练习

Test2.Ye

package com.itstudy.Test2; public class Ye { String name="Ye"; public void fushow(){ System.out.println("ye类的fushow方法被调用啦!"); } public void show(){ System.out.println("ye的show方法被调用啦!"); } }

Test2.Fu

package com.itstudy.Test2; public class Fu extends Ye{ String name="Fu"; public void fushow(){ System.out.println("父类的fushow方法被调用啦!"); } public void show(){ System.out.println("父类的show方法被调用啦!"); } }

Test2.Zi

package com.itstudy.Test2; public class Zi extends Fu { String name="Zi"; //子类独有的方法 public void zishow(){ System.out.println("子类的zishow方法被调用啦!"); } //子类重写父类的方法 @Override public void show(){ System.out.println("子类重写的show方法被调用啦!"); } }

Test2.Test

package com.itstudy.Test2; public class Test { public static void main(String[] args) { /* * 变量调用: * 编译看左边,运行也看左边 * 方法调用: * 编译看左边,运行看右边 */ //利用多态方式创建对象 Fu f = new Zi(); // 调用成员变量: 编译看左边,运行也看左边 // 编译看左边:在把java文件编译成class文件的时候 // 看父类当中有没有这个变量,如果有编译成功,如果没有编译失败 // 运行看左边:在代码真正运行的时候,使用父类中的变量 System.out.println(f.name); // System.out.println(f.age); //调用成员方法:编译看左边,运行看右边 // 编译看左边:看父类当中有没有这个方法,如果没有代码报错 // 运行看右边:在代码真正运行的时候,运行的是子类里面的方法 // 如果子类没有重写父类里面的方法,使用的还是父类 f.show(); //问题一:为什么调用fushow方法程序没有报错? // 因为fushow方法在父类当中存在,编译不会报错(遵循编译看左边的原则) //问题二:程序运行的结果是什么? // 程序运行的结果是:父类的fushow方法被调用啦!(子类没有这个方法,使用的还是父类的) f.fushow(); // f.zishow(); 报错,因为zishow方法在子类当中不存在,编译会报错(遵循编译看左边的原则) //多态的弊端:不能调用子类的特有方法 //解决多态的弊端: // 把对象再转回子类类型的就可以了 Zi z = (Zi) f; z.zishow(); //注意点: // 爷爷 爸爸 儿子 //创建了爸爸的对象,赋值给了爷爷类型 //在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型 Ye y = new Fu(); /* Fu f1 = (Fu)y; //创建了爸爸的对象,赋值给了爷爷类型 Zi z1 =(Zi)y; //报错 //创建了爸爸的对象,赋值给了爷爷类型 //在进行强制类型转换的时候,只能转到爸爸类型,不能转成儿子类型 */ //面对这种容易转错的情况,可以先对其进行判断 //判断一下,y是不是父亲类型的 if (y instanceof Fu) { Fu f1 = (Fu) y; f1.show(); } else { System.out.println("请确定好类型再转换"); } } }

输出结果:

Fu
子类重写的show方法被调用啦!
父类的fushow方法被调用啦!
子类的zishow方法被调用啦!
父类的show方法被调用啦!

2.6 小结

3 多态的综合练习

test3.Person

package com.itstudy.test3; public class Person { private String name; private int age;//年龄 private String gender;//性别 public Person() { } public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } 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 getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public void useTransport(Transport transport){ transport.move(); // transport.honk();//多态中不能直接调用子类特有方法 if(transport instanceof Car){ Car c = (Car)transport; c.honk(); } else if(transport instanceof Bicycle){ Bicycle bic = (Bicycle)transport; bic.ringBell(); }else{ System.out.println("没有这个类型"); } } }

test3.Transport

package com.itstudy.test3; public class Transport { private String brand; private double speed; public Transport() { } public Transport(String brand, double speed) { this.brand = brand; this.speed = speed; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public double getSpeed() { return speed; } public void setSpeed(double speed) { this.speed = speed; } public void move() { System.out.println(brand+"的交通工具正在以"+speed+"的速度移动"); } }

test3.Bicycle

package com.itstudy.test3; public class Bicycle extends Transport { public Bicycle() { } public Bicycle(String brand, double speed) { super(brand, speed); } @Override public void move() { System.out.println(getBrand()+"的交通工具正在以"+getSpeed()+"的速度移动"); } public void ringBell() { System.out.println("自行车正在响铃"); } }

test3.Car

package com.itstudy.test3; public class Car extends Transport { public Car() { } public Car(String brand, double speed) { super(brand, speed); } @Override public void move() { System.out.println(getBrand()+"的交通工具正在以"+getSpeed()+"的速度移动"); } public void honk() { System.out.println("汽车正在鸣笛"); } }

test3.Test

package com.itstudy.test3; public class Test { public static void main(String[] args) { /* 练习 多态的综合练习 自行车:Bicycle 属性:品牌,行驶速度 行为:移动 move,响铃 ringBell() 汽车:Car 属性:品牌,行驶速度 行为:移动 move,鸣笛 honk() 人:Person 属性:名字,年龄,性别 行为:行驶交通工具(能使用所有交通工具) 交通工具 Transport */ Person per = new Person("张三", 18, "男"); //ai没有自动生成代码时:Alt+P 强制ai生成代码 或者 写注释,提示ai生成 //输出打印对象的所有信息 System.out.println(per.getName() + " " + per.getAge() + " " + per.getGender()); Bicycle bic = new Bicycle("凤凰牌自行车", 25); per.useTransport(bic); Car c = new Car("玛莎拉蒂汽车", 60); per.useTransport(c); } }

输出结果:

张三 18 男
凤凰牌自行车的交通工具正在以25.0的速度移动
自行车正在响铃
玛莎拉蒂汽车的交通工具正在以60.0的速度移动
汽车正在鸣笛

4 总结

5 课堂作业

5.1 学生使用图形的方法

5.2 动物饲养

http://www.jsqmd.com/news/1198151/

相关文章:

  • 【2027最新】基于SpringBoot+Vue的家教管理系统管理系统源码+MyBatis+MySQL
  • C++图像预处理实战:窗口分割技术提升处理效率与性能优化
  • 巧用ADC分压网络:单线实现多按键检测的硬件设计精要
  • 豆包推广实战:从0到日均50+用户的四步增长法
  • Claude Code本地化开发:Mac上离线运行Claude 3.5的VS Code深度集成方案
  • C++常量、指针与内存管理:核心概念详解与实践指南
  • 即梦豆包无水印视频直链提取与下载实战指南
  • FaaS 冷启动“龟速”真相:Spring Boot 函数计算从分钟级到毫秒级的进化之路
  • C++跨平台动态库互操作实战:Windows/Linux统一加载与接口设计
  • 深入Qt框架核心:从信号槽机制到模型视图架构的C++ GUI编程精髓
  • 【Springboot毕设全套源码+文档】基于SpringBoot的办公管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 从概念到量产:ISO 26262功能安全标准与ASIL等级实战解析
  • 电压反馈与电流反馈型运放的特性对比与应用指南
  • C++与Python图像处理混合编程:PyBind11实战与性能优化
  • cc-connect:Cursor 编辑器进程级外部控制方案
  • C++/CLI技术指南:实现原生C++与.NET无缝互操作的桥梁
  • C++ string类模拟实现:从深拷贝到动态扩容的底层原理
  • C++实现哈夫曼编码:从数据结构到文件压缩的完整项目指南
  • C++图像处理实战:从零构建像素化工具,掌握底层算法与性能优化
  • MySQL 9.7.0 是假版本?Windows 11 下正确安装 MySQL 8.4 LTS 指南
  • C++与OpenCV实战:基于形态学与轮廓分析的条码检测与识别
  • GRU门控循环单元:原理、实现与NLP应用实践
  • VTK C++点云数据导出:从vtkPoints到.xyz文件的完整实现
  • PCB设计自学指南:从入门到精通的成长路径
  • C++小根堆实现:从原理到工程实践,掌握优先级队列核心
  • C++字符串操作实战:从std::string到string_view的高效编程与避坑指南
  • 华为OD机试“最长的顺子”题解:滑动窗口算法与多语言实现
  • C++实现图像梯度锐化:从Sobel算子到工程实践
  • OSI七层模型详解:从比特流到应用服务的完整数据传输之旅
  • 多模态AI:能看能听能创作的全能时代