1: class baseclass 2: { 3: public void testmethod() 4: { 5: console.writeline("baseclass::testmethod"); 6: } 7: } 8: 9: class derivedclass:baseclass 10: { 11: new public void testmethod() 12: { 13: console.writeline("derivedclass::testmethod"); 14: } 15: }
使用了附加的new修饰符,编译器就知道你重定义了基类的方法,它应该屏蔽基类方法。但是,如果
你按以下方式编写: derivedclass test = new derivedclass(); ((baseclass)test).testmethod(); 基类方法的实现就被调用了。这种行为不同于改写方法,后者保证大部分派生方法获得调用。 5.3 类属性 有两种途径揭示类的命名属性——通过域成员或者通过属性。前者是作为具有公共访问性的成员变量而被实现的;后者并不直接回应存储位置,只是通过 存取标志(accessors)被访问。 当你想读出或写入属性的值时,存取标志限定了被实现的语句。用于读出属性的值的存取标志记为关键字get,而要修改属性的值的读写符标志记为set。在你对该理论一知半解以前,请看一下清单5.9中的例子,属性squarefeet被标上了get和set的存取标志。 清单 5.9 实现属性存取标志 1: using system; 2: 3: public class house 4: { 5: private int m_nsqfeet; 6: 7: public int squarefeet 8: { 9: get { return m_nsqfeet; } 10: set { m_nsqfeet = value; } 11: } 12: } 13: 14: class testapp 15: { 16: public static void main() 17: { 18: house myhouse = new house(); 19: myhouse.squarefeet = 250; 20: console.writeline(myhouse.squarefeet); 21: } 22: }
house类有一个命名为squarefeet的属性,它可以被读和写。实际的值存储在一个可以从类内部访问的变量中——如果你想当作一个域成员重写它,你所要做的就是忽略存取标志而把变量重新定义为: public int squarefeet; 对于一个如此简单的变量,这样不错。但是,如果你想要隐藏类内部存储结构的细节时,就应该采用存取标志。在这种情况下,set 存取标志给值参数中的属性传递新值。(可以改名,见第10行。) 除了能够隐藏实现细节外,你还可自由地限定各种操作: get和set:允许对属性进行读写访问。 get only:只允许读属性的值。 set only:只允许写属性的值。 除此之外,你可以获得实现在set标志中有效代码的机会。例如,由于种种原因(或根本没有原因),你就能够拒绝一个新值。最好是没有人告诉你它是一个动态属性——当你第一次请求它后,它会保存下来,故要尽可能地推迟资源分配。
5.4 索引 你想过象访问数组那样使用索引访问类吗 ?使用c#的索引功能,对它的期待便可了结。
语法基本上象这样: 属性 修饰符 声明 { 声明内容}
具体的例子为 public string this[int nindex] { get { ... } set { ... } }