题目代码:
class 毕姥爷{ void 讲课(){ System.out.println("企业管理"); } void 钓鱼(){ System.out.println("钓鱼"); } } class 毕老师 extends 毕姥爷{ void 讲课(){ System.out.println("JAVA"); } void 看电影(){ System.out.println("看电影"); } } class { public static void main(String[] args) { 毕姥爷 x = new 毕老师(); //毕老师对象被提升为了毕姥爷类型。 x.讲课(); // 这句对不对 x.看电影(); //为什么错. 毕老师 y = (毕老师)x; //将毕姥爷类型强制转换成毕老师类型。 y.看电影();// 对不对 } }
解释:
class { public static void main(String[] args) { // 毕姥爷 x = new 毕老师(); //毕老师对象被提升为了毕姥爷类型。 x.讲课(); // JAVA。因为讲课在子类毕老师内重写过,所以这里输出的应该是子类的内容。 x.钓鱼(); // 钓鱼。 x.看电影(); // 错误。当父类引用指向子类对象时,只能访问父类中具备的方法,不可以访问子类中特有的方法。 // // // 那么,再看下面最原始的用法。 毕姥爷 s = new 毕姥爷(); s.讲课(); // 企业管理。 s.钓鱼(); // 钓鱼。 s.看电影(); // 错误。这边用的是父类,和子类没有任何关系。 // // // 总结:子类提升为父类,父类中的方法只有在未被子类重写的情况下,才能调用。也就是在父类的基础上,增加了子类重写的内容。也是多态的一个体现。 // // // 毕老师 y = (毕老师)x; // 将毕姥爷类型强制转换成毕老师类型。 y.讲课(); // JAVA。 y.钓鱼(); // 钓鱼。 y.看电影(); // 看电影。 // // // 同样地,看看最基本的用法。 毕老师 r = new 毕老师(); r.讲课(); // JAVA。子类重写了父类的方法。 r.钓鱼(); // 钓鱼。调用了父类的方法 r.看电影(); // 看电影。 // // // 总结:显然,两者的结果是一样的。所以一般没有必要的情况下,都不用强制转换,以避免未知的错误。 } }