本章会由一个示例浅谈JAVA的多态性——对象的类型转换
实验题目:公司支出的总薪水:
要求:
- 有一个abstract类,类名为Employee。Employee的子类有YearWorker、MonthWorker、WeekWorker。YearWorker对象按年领取薪水,MonthWorker按月领取薪水,WeekWorker按周领取薪水。
- Employee类有一个abstract方法:public abstract earnings();子类必须重写父类的earnings()方法,给出各自领取报酬的具体方式。
- 有一个Company类,该类用Employee对象数组作为成员,Employee对象数组的单元可以是YearWorker对象的上转型对象、MonthWorker对象的上转型对象或WeekWorker对象的上转型对象。程序能输出Company对象一年需要支付的薪水总额。
源码:
package salaries;
abstract class Employee {
public abstract double earnings();
}
//YearWorker对象按年领取薪水,
class YearWorker extends Employee {
int n;
double ns; // 工作年数与年薪
YearWorker(int a, double b) // 构造函数
{
n = a;
ns = b;
}
public double earnings() {
return n * ns;
}
}
//MonthWorker按月领取薪水,
class MonthWorker extends Employee {
int m;
double ms; // 工作月数与月薪
MonthWorker(int a, int b) {
m = a;
ms = b;
}
public double earnings() {
return m * ms;
}
}
// WeekWorker按周领取薪水
class WeekWorker extends Employee {
int w;
double ws; // 工作周数与周薪
WeekWorker(int a, double b) {
w = a;
ws = b;
}
public double earnings() {
return w * ws;
}
}
class Company {
double sum;
Employee[] employee;
Company(Employee[] employee) {
this.employee = employee;
}
double pay() {
for (int i = 0; i < 30; i++) {
sum += employee[i].earnings();
}
return sum;
}
}
public class CompanySalary {
public static void main(String[] args) {
Employee[] employee = new Employee[30]; // 公司共有30名员工
// 把员工分为年薪、月薪、周薪员工
for (int i = 0; i < employee.length; i++) {
if (i % 3 == 0)
employee[i] = new WeekWorker(1, 1000); // 上转型对象
if (i % 3 == 1)
employee[i] = new MonthWorker(1, 10000);
if (i % 3 == 2)
employee[i] = new YearWorker(1, 200000);
}
Company company = new Company(employee);
System.out.println("该公司的薪水总额是" + company.pay() + "元");
}
}
JAVA的对象转换类型分为向上转型和向下转型
- 向上转型
即将子类对象当作父类类型使用,调用父类中定义,子类中实现的方法;
格式:父类 对象名1 = new 子类()
例子:Animal an1 = new Dog();
上文中的例子:
employee[i] = new WeekWorker(1, 1000);
其中 employee[i] 是父类中定义的对象数组,WeekWorker是子类,
WeekWorker(1, 1000)是子类WeekWorker中的构造函数,
这即是调用父类中定义,子类中实现的方法,
也即所谓的向上转型.
- 向下转型
若想调用子类中特有的方法,则需将父类类型的对象强制转换为子类类型.
格式:子类 对象名2 = (子类) 对象名1
注释:对象名1指向上转型时父类的对象名,对象名2指此时定义的子类对象名
例子:
Animal an1 = new Dog();
Dog an2 = (Dog) an1;
可能会出现的错误
1.The method 方法名 ()is undefined for the type 父类名
如果出现这种错误,即在向下转型时,你未在父类中定义×××方法
解决方法:在父类中定义即可
2.如果你首先将A子类对象当作父类类型使用,但又将此时的父类类型强制转换为B子类类型,调用子类特有的方法,此举时错误的!
简单说就是:你与你儿子A的身份互换,此时你是A,A和他老婆一起吃饭,这很正常,但是你却想和你哥哥B的老婆吃饭,你想干嘛??记住此刻你是A!!想吃饭,你得把你A弟弟的身份换成B哥哥才可以!
解决方法:关键字instanceof可以判断一个对象是否为某个(类或者接口)的实例或子类实例.
语法格式:
对象名A instanceof 类名A //判断对象名A是不是类名A类型
可以用一个if语句来进行判断输出
例子:
if(an1 instanceof Dog)
{
Dog an2 = (Dog) an1;
an2.shout();
}
else
{
Systrm.out.println("该类型的对象不是Dog类型!");}