“变态”的类

请看以下“变态”的类

ParentChildTest.Java示例

public class ParentChildTest {

public static void main(String[] args) {

Parent parent=new Parent();

parent.printValue();

Child child=new Child();

child.printValue();

parent=child;

parent.printValue();

parent.myValue++;

parent.printValue();

((Child)parent).myValue++;//

parent.printValue();

}

}

class Parent{

public int myValue=100;

public void printValue() {

System.out.println("Parent.printValue(),myValue="+myValue);

}

}

class Child extends Parent{

public int myValue=200;

public void printValue() {

System.out.println("Child.printValue(),myValue="+myValue);

}

}

1. 程序运行结果是什么? 2.   你如何解释会得到这样的输出? 3.   计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?

程序运行结果:

解释:

父类对象被定义成子类类型(家族的具体化)

既然子类继承父类,所以子类更能代表这一个家族的具体表现,一个父类的对象被定义成子类类型时就具有了父类的属性和方法。

反过来子类对象不能被定义成父类类型

子类对象为什么不能被定义成父类类型呢?因为子类继承于父类,因此子类拥有的方法很可能比父类多,因为除了继承自父类的全部属性和方法外,子类有可能定义了其他的方法,所以大体上看子类的量级要比父类大,所以父类对象可以定义成子类对象,因为多出来的方法可以直接使用子类的,而反过来的话就不行了,因为子类对象不知道如何砍掉那些多出来的方法。

所以,一句话就是小盒子(父类对象)可以套进大盒子(子类)里,大盒子(子类对象)不能套进小盒子(父类)里。

同理,父类对象可以被子类对象赋值(被定义成子类类型),子类对象不能被父类对象赋值。

父类对象只有当明确转换为子类对象时才可以直接控制对象中的属性,只是通过赋值来使父类对象变成子类类型的办法不能使父类对象完全控制对象中的属性。

如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。

换言之,一旦子类父类具有相同名称的字段,就会使继承的情况变得复杂,子类中的父类同名变量或方法就会褪色而不易被调用。

比如,父类子类都有名为F的属性或方法,那么在继承时,子类就会有两个F属性或方法,一个继承于父类(由父类定义),而另一个由子类自己定义。生成一个子类对象时,子类对象一旦调用F属性或执行F方法就会优先使用子类自己的F属性或执行子类自己的F方法,如果要强行使用父类的F属性或执行父类F方法,得在子类定义中使用super.F()来调用。

总结:(1)当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
这个特性实际上就是面向对象“多态”特性的具体表现。

(2)如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。
如果子类被当作父类使用,则通过子类访问的字段是父类的!
牢记:(验证结论发博客)
 在实际开发中,要避免在子类中定义与父类同名的字段。不要自找麻烦!——但考试除外,考试中出这种题还是可以的。

时间: 2024-11-04 14:07:27

“变态”的类的相关文章

多态动手动脑

一.怎样判断对象是否可以转换?可以使用instanceof运算符判断一个对象是否可以转换为指定的类型,参看实例: TestInstanceof.java public class TestInstanceof { public static void main(String[] args) { //声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类 //但hello变量的实际类型是String Object hello = "Hello"

动手动脑

1.可以使用instanceof运算符判断一个对象是否可以转换为指定的类型:Object obj="Hello";if(obj instanceof String) System.out.println("obj对象可以被转换为字符串"); 验证: public class TestInstanceof { public static void main(String[] args) { //声明hello时使用Object类,则hello的编译类型是Object,

MongoDB学习笔记~大叔框架实体更新支持N层嵌套~递归递归我爱你!

回到目录 递归递归我爱你!保要你想做,就一定能成功! 从一到二,从二到三,它是容易的,也是没什么搞高的,或者说,它是一种流水线的方式,而从三到十,它注定要有一个质的突破,否则,它会把你累死,代码写的让你自己都觉得想吐!有时,我们是被逼出来的,对于一种功能的实现,我们有时需要有从三到十的态度…… 回归回实例,在mongodb中实体可以嵌套,这在C#里叫做复杂属性,即类中也有类级的属性,这在面向对象里叫做“组合”,它经常在日常开发环境中见到,大家都耳熟能详了,呵呵,而在mongodb里,如果希望对N

Java(多态)动手动脑

1> 请看以下"变态"的类(参看示例ParentChildTest.java) 上述代码的特点是: 子类和父类定义了一模一样的字段和方法 运行以下测试代码 1. 上边的程序运行结果是什么? 2. 你如何解释会得到这样的输出? 第一个100:是parent调用PrintValue方法输出parent类中myValue值为100: 第二个200:是child调用PrintValue方法输出child类中myValue值为200: 第三个200:是parent = child,将子类对

动手动脑,11.9

为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来? 构造函数的功能主要用于在类的对象创建时定义初始化的状态.构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量. 子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化. 不能反过来调用也是这个原因,因为父类根本不知道子类有什么变量,子类也得不到初始化的父类变量.所以程序不能运行. 2.不可变的"类"有何用? 可以方便和安全地用于多线程环境中,访问

重学Java面向对象 之 final

final 的套路: 当初在背面试题的时候final出现的概率可以说是相当高了,在各种面试题库中都少不了它的身影,一说起final ,那打开方式差不多就是这样的: 1.  对于基本类型变量:final 修饰的变量不可修改 2.  对于引用型变量: final 修饰的对象,引用本身不可修改,但是被引用的内容可以修改. 3. 对于 方法 : 方法不能重写 4. 对于类:类不能被继承 因为当时看了太多遍同时内容简单又好背,现在不看书也能写出来了,至于具体的代码示例这里就不放了,网上也比较多. 但是自己

【很变态】PHP类实例化对象竟然可以访问类的“静态(static)方法”!!!

之前发现一个PHP的变态问题:PHP中静态(static)调用非静态方法详解 这次看了下 ThinkPHP 的源码 function.inc.php ,里面有个函数: /** * 取得对象实例 支持调用类的静态方法 * * @param string $name 类名 * @param string $method 方法 * @param string $args 参数 * @return object 对象实例 */ function get_instance_of($name, $metho

Qt 类外调用一个 private slots 函数

MainWindow中 private slots 函数 void print_on_log(QString strtemp);输出一个字符串到编辑窗口中 class MainWindow:publicQMainWindow {Q_OBJECTpublic:explicitMainWindow(QWidget*parent=0);~MainWindow();privateslots:voidprint_on_log(QStringstrtemp); 定义一个新类Test_one在此类中调用上面的

Category-分类

概念 1OC中提供了一种与众不同的方式-Category,可以动态地为经已存在的类添加新的方法. 变态啊,不改变.m 和.h 2可以保证类的原始设计规模大小,功能增加时再逐步扩展. 3Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的文件中. 只是方法,不能拓展成员变量 ----------------------------------- new->Cocoa->OC category Category: Test Category on: Student