1 多态基础概念
1.1 多态理解

1.2 多态的使用场景

1.3 多态基础

1.4 练习
学生类:
属性:姓名,账号,密码
行为:work:学生的工作是学习
老师类:
属性:姓名,账号,密码
行为:work:老师的工作是教书
管理员:
属性:姓名,账号,密码
行为:work:管理员的工作是管理网站
学生管理系统:
行为:注册register
要求:能注册所有的角色
输出:姓名为张三的同学注册成功,账号zhangsan,密码123456
test1.Person
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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
java
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 动物饲养
