多态——一个编程小白的Java SE学习日志7【极客BOY-米奇】

前言(转载请说明作者!)4.8编写

在学习日志Ⅵ(继承)中,我们使用学生类和教师类来继承人类,从而有效解决了一些代码冗余的问题,实现了代码的复用。

而在多态中,我们还有更加简便的方式来解决同一种方法,参数属于同一父类的方法,使得程序更加简洁。

多态

学校门禁系统实现

导引

我们在继承中编写了程序,现根据它来增加一个学校类(Shool),学校类中有门禁系统,可以为学生和老师开门。

代码(非多态实现)

Person类
public class Person {
	private String name;
	private int age;

	// 有参构造方法
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public void printInfo() {
		System.out.println("姓名:" + name + "\n年龄:" + age);
	}

	// getter/setter
	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;
	}
}
Student类
public class Student extends Person {
	private String department;

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public Student(String name, int age, String department) {
		super(name, age);
		this.department = department;
	}

	public void printInfo() {
		super.printInfo();
		System.out.println("系别:"+department);
	}
}
Teacher类
public class Teacher extends Person {
	private String major;

	public String getMajor() {
		return major;
	}

	public void setMajor(String major) {
		this.major = major;
	}

	public Teacher(String name, int age, String major) {
		super(name, age);
		this.major = major;
	}

	public void printInfo() {
		super.printInfo();
		System.out.println("专长:" + major);
	}
}
School类(非多态)
public class School {
	// 为学生开启门禁
	public void openDoor(Student stu) {
		stu.printInfo();
		System.out.println("允许进入!");
	}
	
	// 为老师开启门禁
	public void openDoor(Teacher t) {
		t.printInfo();
		System.out.println("允许进入!");
	}
}
主类(EX8_1)
public class EX8_1 {
	public static void main(String[] args) {
		School sc = new School();
		Student stu = new Student("小明", 20, "音乐学院");
		sc.openDoor(stu);
		System.out.println("*****************************");
		Teacher t = new Teacher("刘老师", 30, "信息工程");
		sc.openDoor(t);
	}
}

输出:

姓名:小明
年龄:20
系别:音乐学院
允许进入!


姓名:刘老师
年龄:30
专长:信息工程
允许进入!

本章会改进此案例,把它加入多态的特性。

什么是多态?

多态,顾名思义,字面意义是“多种状态”,就是指 不同的对象调用相同的方法执行的操作不同

后面我们会学习接口相关的知识,也可以说同一实现接口,使用不同的实例可以执行不同的操作

在学校类的开启 门禁就是学校提供的一个接口,这个接口应该可以为不同类型的人开启门禁 ,比如可以为学生,教师,管理员等开启门禁,这就是一种多态。

如何实现多态?

对象的上转型对象

上转型类型类似基本数据类型的转换。

e.g.1 整形可以转换为双精度浮点型

int n = 23; double m = n; 最终m的值为23.0。

e.g.2 双精度型转换为整形需要强制类型转换

int n = (int)8.2; 最终n的值为8。

定义

在引用数据类型的子类和父类之间也存在转换问题,子类对象可以赋给父类对象(不需要强制类型转换)叫做子类对象向上转型父类对象称为子类对象的 上转型对象

Person p;
Student stu = new Student();
p = stu;	// 称作stu向上转型

上述的 p = stu 中的 p称作 stu的上转型对象。

上述的代码还可以简写成:

Person p = new Student();

p就称为 new Student()对象的上转型对象

特点

上转型对象的类型是父类类型实体 却是 由子类 负责 创建 的。

  • 上转型对象 会失去子类对象的一些属性和方法 。上转型对象不能操作子类新增的成员变量(即丢失了这部分属性),不能使用子类新增的方法(即丢失了这部分方法)。
  • 上转型对象 可以操作子类继承或者隐藏成员变量 ,也 可以使用子类继承的或者重写的方法
  • 上转型对象操作子类继承或者重写的方法时,就是通知对应的子类对象来调用这些方法。所以, 如果子类重写了父类的某个方法,对象的上转型对象调用这个方法时,一定是调用了重写后的方法
  • 可以将对象的上转型对象再强制转换到一个子类对象 ,这时,该子类又会具备子类所具有的属性和功能
上转型对象的案例
主类(EX8_2)

PS:其他类同非多态实现的门禁系统

public class EX8_2 {
	public static void main(String[] args) {
		Person p;
		Student stu = new Student("小红", 22, "外语系");
		p = stu;	// p是stu的上转型对象
		// p不能调用新增的setDepartment方法
		p.setName("小花");
		p.printInfo();
		Student stuNew = (Student) p;
		stuNew.setDepartment("信工");
		stuNew.printInfo();
	}
}

输出:

姓名:小花
年龄:22
系别:外语系
姓名:小花
年龄:22
系别:信工

多态的实现

根据上述的了解,我们现在可以尝试制作程序来对门禁系统进行改进。

School类的修改

其他类均为进行修改,即可实现与之前完全相同的结果。

public class School {
//	// 为学生开启门禁
//	public void openDoor(Student stu) {
//		stu.printInfo();
//		System.out.println("允许进入!");
//	}
//	
//	// 为老师开启门禁
//	public void openDoor(Teacher t) {
//		t.printInfo();
//		System.out.println("允许进入!");
//	}
	
	// 多态的实现
	public void openDoor(Person p) {
		p.printInfo();
		System.out.println("允许进入!");
	}
}

温馨提示:

p.printInfo()方法调用的是子类重写后的方法 ,所以实现了多态 ,即不同参数传入相同的方法,结果却不相同。

如果我们再创建一个管理员类,并且是Person的子类,那么门禁系统不需要进行修改即可对管理员进行放行。有效避免了代码的重写。

多态实现的条件

多态实现有三个条件:继承、重写、向上转型。

继承

在多态中必须存在有继承关系的子类和父类 。如上述例子中:Student和Teacher都继承父类Person。

重写

子类对父类中某些方法进行重写,在调用这些方法时就会调用子类重写的方法 。如上述例子中:Student和Teacher都重写了父类Person中的printInfo()方法。

向上转型

在多态中需要将子类的引用赋给父类对象编译时按照父类来处理!!!!不能调用新增的成员!!!!! ,运行时绑定子类,调用子类重写方法 。如上述例子中:Student对象和Teacher对象向父类Person转型后调用相应重写后的printInfo()方法,输出不同,体现多态。

!!!!不能调用新增的成员!!!!

Instanceof运算符

这里的知识点较为简单,可以简述为:

实例 instanceof 类 == true;

instanceof就是判断前面的是否是后面的实例 。是就为true,不是就false。(即返回值类型为布尔型)

主要用途

可以用在多态方法中,用来分支运行不同子类的不同方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客BOY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值