JAVA有关超类与子类关系的语法坑之一

java是纯粹面向对象编程的语言,弄懂类、对象、方法等之间的关系极其重要。我在学习的时候一下子就踩了一个坑。先给大家推荐一下我正在看的书:《Java核心技术 卷I》。打算入门java的同学可以选择这本书,绝对不亏(虽然我刚才还被这个问题困扰了很久,但后来发现只不过是我看书不用心罢了)。

问题的产生

在学习类的继承时,看到某代码中将子类变量赋值给所对应的超类的变量(staff[0]=boss),

package inheritance;

/**
 * This program demonstrates inheritance
 * @version 1.00 2020-01-07
 * @author 梦劫~VEZ'NAN
 */
public class ManagerTest {
    public static void main(String[] args)
    {
        //construct a Manager object
        Manager boss=new Manager("Carl Cracker",80000,1987,12,15);
        boss.setBonus(5000);

        Employee[] staff=new Employee[3];

        //fill the array with Manager and Employee object

        staff[0]=boss;  //疑惑
        staff[0].setBonus(1);
/*        Manager bos=(Manager) staff[0];
        bos.setBonus(1);
        System.out.println(bos.getSalary());*/
        staff[1]=new Employee("Harry Hacker",50000,1989,10,1);
        staff[2]=new Employee("Tommy Tester",40000,1990,3,15);

        //print out information about all Employee objects
        for(Employee e:staff)
        {
            System.out.println("name="+e.getName()+";salary="+e.getSalary()+";hireDay="+e.getHireDay());
        }
    }
}

于是产生了疑惑:在for each环节对staff[0]使用getSalary方法时为什么会调用Manager类中的getSalary方法呢(从输出结果看出来调用的是Manager中的方法)?除非staff[0]是Manager的实例。后来发现本书在这个代码的前面明确指出:“staff[0]对应的是Manager对象”(真搞不懂我之前是不是眼瞎了)。

进一步探索

于是我尝试对staff[0]使用setBonus方法,然而编译器报错了(第二十行报错)。

不是说好了staff[0]是Manager对象吗?为什么不能对它使用setBonus方法?
于是又开始在百度、CSDN上疯狂寻找合理的解释,无功而返。继续看书,恍然大悟。

这是书上的一句原话

“在这个例子中,变量staff[0]与boss引用同一个对象。但编译器将staff[0]看成Employee对象。
这意味着,可以这样调用

	boss.setBonus(5000);	//OK

但不能这样调用

	staff[0].setBonus(5000);	//Error

这是因为staff[0]声明的类型是Employee,而setBonus不是Employee类的方法。”

也就是说

staff[0]与boss引用的是同一个Manager对象(通过断点调试可以很明显地看出来),但是只有在对staff[0]使用getSalary方法(超类与子类重载的方法)时编译器才会把staff[0]看作Manager对象,其它情况都将staff[0]强制看作是Employee对象(置换法则)。

在这里插入图片描述
写完这篇博客心里舒服多了。这个法则是真的坑啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值