ad_qqread_mid_big">面向类型观点
图1的uml类图给出了类和类型的简单继承关系,以便于解释多态机制。模型中包含5种类型,4个类和一个接口。虽然uml中称为类图,我把它看成类型图。如"thanks type and gentle class," 一文中所述,每个类和接口都是一种用户定义的类型。按独立实现的观点(如面向类型的观点),下图中的每个矩形代表一种类型。从实现方法看,四种类型运用了类的结构,一种运用了接口的结构。

图1:示范代码的uml类图
以下的代码实现了每个用户定义的数据类型,我把实现写得很简单。
用这样的类型声明和类的定义,图2从概念的观点描述了java指令。
derived2 derived2 = new derived2();

图2 :derived2 对象上的引用
上文中声明了derived2这个对象,它是derived2类的。图2种的最顶层把derived2引用描述成一个集合的窗口,虽然其下的derived2对象是可见的。这里为每个derived2类型的操作留了一个孔。derived2对象的每个操作都去映射适当的代码,按照上面的代码所描述的那样。例如,derived2对象映射了在derived中定义的m1()方法。而且还重载了base类的m1()方法。一个derived2的引用变量无权访问base类中被重载的m1()方法。但这并不意味着不可以用super.m1()的方法调用去使用这个方法。关系到derived2这个引用的变量,这个代码是不合适的。derived2的其他的操作映射同样表明了每种类型操作的代码执行。
既然你有一个derived2对象,可以用任何一个derived2类型的变量去引用它。如图1所示,derived, base和itype都是derived2的基类。所以,base类的引用是很有用的。图3描述了以下语句的概念观点。
base base = derived2;

图3:base类引用附于derived2对象之上
虽然base类的引用不用再访问m3()和m4(),但是却不会改变它derived2对象的任何特征及操作映射。无论是变量derived2还是base,其调用m1()或m2(string)所执行的代码都是一样的。
两个引用之所以调用同一个行为,是因为derived2对象并不知道去调用哪个方法。对象只知道什么时候调用,它随着继承实现的顺序去执行。这样的顺序决定了derived2对象调用derived里的m1()方法,并调用derived2里的m2(string)方法。这种结果取决于对象本身的类型,而不是引用的类型。
尽管如此,但不意味着你用derived2和base引用的效果是完全一样的。如图3所示,base的引用只能看到base类型拥有的操作。所以,虽然derived2有对方法m3()和m4()的映射,但是变量base不能访问这些方法。
运行期的derived2对象保持了接受m3()和m4()方法的能力。类型的限制使base的引用不能在编译期调用这些方法。编译期的类型检查像一套铠甲,保证了运行期对象只能和正确的操作进行相互作用。换句话说,类型定义了对象间相互作用的边界。 >>>更多专题请看java的类专题
图1的uml类图给出了类和类型的简单继承关系,以便于解释多态机制。模型中包含5种类型,4个类和一个接口。虽然uml中称为类图,我把它看成类型图。如"thanks type and gentle class," 一文中所述,每个类和接口都是一种用户定义的类型。按独立实现的观点(如面向类型的观点),下图中的每个矩形代表一种类型。从实现方法看,四种类型运用了类的结构,一种运用了接口的结构。

图1:示范代码的uml类图
以下的代码实现了每个用户定义的数据类型,我把实现写得很简单。
| /* base.java */ public class base { public string m1() { return "base.m1()"; } public string m2( string s ) { return "base.m2( " + s + " )"; } } /* itype.java */ interface itype { string m2( string s ); string m3(); } /* derived.java */ public class derived extends base implements itype { public string m1() { return "derived.m1()"; } public string m3() { return "derived.m3()"; } } /* derived2.java */ public class derived2 extends derived { public string m2( string s ) { return "derived2.m2( " + s + " )"; } public string m4() { return "derived2.m4()"; } } /* separate.java */ public class separate implements itype { public string m1() { return "separate.m1()"; } public string m2( string s ) { return "separate.m2( " + s + " )"; } public string m3() { return "separate.m3()"; } } |
用这样的类型声明和类的定义,图2从概念的观点描述了java指令。
derived2 derived2 = new derived2();

图2 :derived2 对象上的引用
上文中声明了derived2这个对象,它是derived2类的。图2种的最顶层把derived2引用描述成一个集合的窗口,虽然其下的derived2对象是可见的。这里为每个derived2类型的操作留了一个孔。derived2对象的每个操作都去映射适当的代码,按照上面的代码所描述的那样。例如,derived2对象映射了在derived中定义的m1()方法。而且还重载了base类的m1()方法。一个derived2的引用变量无权访问base类中被重载的m1()方法。但这并不意味着不可以用super.m1()的方法调用去使用这个方法。关系到derived2这个引用的变量,这个代码是不合适的。derived2的其他的操作映射同样表明了每种类型操作的代码执行。
既然你有一个derived2对象,可以用任何一个derived2类型的变量去引用它。如图1所示,derived, base和itype都是derived2的基类。所以,base类的引用是很有用的。图3描述了以下语句的概念观点。
base base = derived2;

图3:base类引用附于derived2对象之上
虽然base类的引用不用再访问m3()和m4(),但是却不会改变它derived2对象的任何特征及操作映射。无论是变量derived2还是base,其调用m1()或m2(string)所执行的代码都是一样的。
| string tmp; // derived2 reference (figure 2) tmp = derived2.m1(); // tmp is "derived.m1()" tmp = derived2.m2( "hello" ); // tmp is "derived2.m2( hello )" // base reference (figure 3) tmp = base.m1(); // tmp is "derived.m1()" tmp = base.m2( "hello" ); // tmp is "derived2.m2( hello )" |
两个引用之所以调用同一个行为,是因为derived2对象并不知道去调用哪个方法。对象只知道什么时候调用,它随着继承实现的顺序去执行。这样的顺序决定了derived2对象调用derived里的m1()方法,并调用derived2里的m2(string)方法。这种结果取决于对象本身的类型,而不是引用的类型。
尽管如此,但不意味着你用derived2和base引用的效果是完全一样的。如图3所示,base的引用只能看到base类型拥有的操作。所以,虽然derived2有对方法m3()和m4()的映射,但是变量base不能访问这些方法。
| string tmp; // derived2 reference (figure 2) tmp = derived2.m3(); // tmp is "derived.m3()" tmp = derived2.m4(); // tmp is "derived2.m4()" // base reference (figure 3) tmp = base.m3(); // compile-time error tmp = base.m4(); // compile-time error |
运行期的derived2对象保持了接受m3()和m4()方法的能力。类型的限制使base的引用不能在编译期调用这些方法。编译期的类型检查像一套铠甲,保证了运行期对象只能和正确的操作进行相互作用。换句话说,类型定义了对象间相互作用的边界。
| 上一页 1 2 3 4 5 下一页 |
| 相关内容:效果 设计 技巧 java |
| 【收藏此页】【大 中 小】【打印】【关闭】 | |
| 上一篇:利用des加密算法保护java源代码 下一篇:java实现的18位身份证格式验证算法 10万个软件免费高速下载 | |
| ||||||||||||||
|
|
-
关于我们
公司介绍 最新动态 联系我们 -
产品与服务
域名注册 jsp空间 php空间 -
常见问题
空间操作手册 网站备案相关 退款相关问题 -
技术支持
技术 QQ :178966803 联系电话:13616026886 联系邮箱:fjjsp@vip.163.com
扫描关注微信公众号
闽公网安备 35060202000074号