以下是《JAVA2核心技术》一书中的一个关于计算员工工资的实例,有几个问题不太明白。
import java.util.*;public class ManagerTest
{
public static void main(String args[])
{
Manager boss = new Manager("Simon Lo", 80000, 2008, 11, 26);
boss.setBonus(5000);
Employee staff[] = new Employee[3];
staff[0] = boss;
staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);
for (Employee e : staff)
{
System.out.println("Name = " + e.getName() + "\t\tSalary = " + e.getSalary());
}
}
}class Employee
{
private String name;
private double salary;
private Date hireDay;
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month -1, day);
hireDay = calendar.getTime();
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
}class Manager extends Employee
{
private double bonus;
public Manager(String n, double s, int year, int month, int day)
{
super(n,s,year,month,day);
bonus = 0;
}
public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b)
{
bonus = b;
}
}请教问题如下:
1、在代码中的raiseSalary()方法为什么没有生效?
2、整段代码中在class Employee和class Manager中各定义了一个getSalary()方法,那么在class ManagerTest中的main方法里,JVM又是如何确定到底调用的是哪一个getSalary()的?
import java.util.*;public class ManagerTest
{
public static void main(String args[])
{
Manager boss = new Manager("Simon Lo", 80000, 2008, 11, 26);
boss.setBonus(5000);
Employee staff[] = new Employee[3];
staff[0] = boss;
staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);
for (Employee e : staff)
{
System.out.println("Name = " + e.getName() + "\t\tSalary = " + e.getSalary());
}
}
}class Employee
{
private String name;
private double salary;
private Date hireDay;
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month -1, day);
hireDay = calendar.getTime();
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
}class Manager extends Employee
{
private double bonus;
public Manager(String n, double s, int year, int month, int day)
{
super(n,s,year,month,day);
bonus = 0;
}
public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b)
{
bonus = b;
}
}请教问题如下:
1、在代码中的raiseSalary()方法为什么没有生效?
2、整段代码中在class Employee和class Manager中各定义了一个getSalary()方法,那么在class ManagerTest中的main方法里,JVM又是如何确定到底调用的是哪一个getSalary()的?
解决方案 »
- 三目运算你懂吗?懂就来看下.
- struts2 execAndWait拦截器空指针
- swing做的拼图简单移动的事例---求帮我看下为什么出错
- 有没有人有jspsmartupload.jar这个包
- 关于线程的问题
- base64的编码,解决给分!! 谢谢,急急!!
- MDI application
- 请问mm.mysql的jdbc Driver是否支持jdbc2.0(ConnectionPool)?
- 请问:java怎样访问COM组件
- 简单的java问题 必给分!
- 我自编了个小程序,但在界面处理上不爽,我想JPanel周围出现立体凹痕,并且,三个slider竖排,求助
- 用 Dtree做了一个树形结构 请问如何在树的节点上添加右键菜单
raiseSalary()方法没有生效,是因为你并没有调用该方法,你不是继承了Manager吗,那么Employee自然也会拥有Manager里面的所有public方法和public的属性(),除非你不想要里面的方法,把它重写了。
如果想要看到raiseSalary()的效果那么就应该把boss.setBonus(5000); 改为
double raiseSalaryPercent = ((5000)/(double)boss.getSalary())*100;
boss.raiseSalary(raiseSalaryPercent);
只是为了让你理解这个raiseSalary方法到底干嘛才这么复杂的写了那么多,raiseSalary方法是按照百分比来增加工资回答你第二问题:
首先我把你执行的过程分为编译期和运行期
编译期,由编译器将代码文件(.java)编译成字节码文件(.class),编译期不关jvm的事,只是进行一系列检查。
boss是一个Manager的引用指向的是一个Manager的对象,所以没什么好说的。
然后你把staff[0] = boss;staff[0]是一个Employee引用,此时staff[0]和boss都指向了一个Manager对象。
for (Employee e : staff)就不用的解释了jdk5.0才有的特性,我就根据你的意思大概这样写下staff[0]:
System.out.println("Name = " + staff[0].getName() + "\t\tSalary = " + staff[0].getSalary());
编译器会看看staff[0]是啥类型(Employee类型),然后在看看Employee有没有这个方法,没有编译出错,不信你把
Employee里面的getSalary()删除(其他关联的也得更改下,否则会出现其他错误)由类加载器将字节码加载到jvm中……进入运行期后,在堆空间里创建一个Manager对象,在栈空间里分配空间给一个
Manager引用,然后返回Manager对象给Manager引用boss,即
Manager boss = new Manager("Simon Lo", 80000, 2008, 11, 26);
接下来是将一个Employee引用指向boss所指的那个对象,
如果你是
System.out.println(staff[0].getSalary());
jvm会看看该引用所指向的对象里有没有该方法,如果有就调用此getSalary(),如果没有当然是调用的是引用类里的getSalary()方法,不过你在Manager类里重写了getSalary()方法,那调用的是Manager类里的getSalary()。
可能是多态你没怎么深度理解吧,呵呵
上面对于你的问题应该解释的很详细了吧,不过我建议你最好先研究一下多态
还有一个建议:先看一下尚学堂马士兵的java基础视频,电驴上有下,期待你的提高,呵呵
对于你的问题
1.byPercent没有被赋值,默认为0,所以salary += raise等于salary
2.那是java的动态绑定机制决定的。怎么区别的,一般是通过构造方法区分.
这个题更好办了,你直接构建的Manager实例,它就知道了,
如果是Employee类的对象,则调用Employee的getSalary(),
如果是Manager类的对象,则现在this域(自己本身类)里getSalary(),如果有定义这个方法,
则调用。如果没有,则到super域(父类,Employee类中)中找,如果找到了就调用方法,否则会再向上(父类,这里假设还有继承关系,比如Employee继承Person类)找。
给你提的建议。
1.不要盲目的提问。
2.java的几个重要特性你应该都理解到。
3.把学习中的问题记下来。等把书看完了。你回头再看看你的问题还有不明白的再问。这样理解的深刻。
学习就是逐步提高的过程。不要把希望都寄托在别人身上。