索引器
索引器可以使类对象像数组似的使用,比如我定义了个类对象Apple?apple,那么如果Apple类里声明了索引器,并且是int类型的话,我就可以这样访问:apple[0],apple[1],apple[2]..等,那么从apple[0]里读取到的是什么呢,这就得看你自己怎么定义set和get函数了,因为你也可以把这些“数组元素“看作一个个变量,而“数组索引”就是它们的区别。
先来看看索引器的声明:
public?int?this[int?index]
上面第一个int表明这个对象“数组”是什么类型的,而this关键字是固定的,C++里,这个this是一个指针,它指向自身的对象,可以说是代表着对象。
那么这种this[int?index]定义就可以看得清楚了,跟apple[0],apple[1]是对应的。
上面说了这么多,如果不看代码的话,我想也很难理解,不过这也没关系,因为上面这些只是为了更好的理解下面的代码,代码看的懂就算是成功了。
看例子:
using?System;
class?Apple
{
????public?int?this[int?index]
????{
????????set
????????{
????????????Console.WriteLine("赋值{0},但实际并没有存储",?value);
????????}
????????get
????????{
????????????Console.WriteLine("我只是返回索引加10的数字,它是{0}",?index?+?10);
????????????return?index?+?10;
????????}
????}
}
class?Program
{
????static?void?Main(string[]?args)
????{
????????Apple?apple?=?new?Apple();
????????apple[0]?=?100;
????????apple[1]?=?50;
????????int?Num?=?apple[10];
????????Num?=?apple[5];
????}
}
如果想存储值的话,在类里面定义一个相应的数组就可以了。
另外,索引的类型也可以是字符串,浮点型,字符。
看下例:
using?System;
class?Apple
{
????public?int?this[string?str]
????{
????????set
????????{
????????????Console.WriteLine("赋值{0},但实际并没有存储,索引字符串:{1}",?value,str);
????????}
????????get
????????{
????????????Console.WriteLine("取值的索引字符串:{0}",?str);
????????????return?100;
????????}
????}
}
class?Program
{
????static?void?Main(string[]?args)
????{
????????Apple?apple?=?new?Apple();
????????apple["abcd"]?=?100;
????????apple["Trust"]?=?50;
????????int?Num?=?apple["1234"];
????????Num?=?apple["Thanks"];
????}
}
base关键字
在C++中,如果子类和父类有一个相同的函数,那么在子类中要调用父类的相同函数,可以在函数前加上类名,就是调用父类的函数了,子类构造函数中调用父类的构造函数也是如此。
先来回顾一下C++中是怎么调用的:
#include<iostream.h>
class?CFruit
{
public:
????CFruit()
????{
???????cout<<"父类CFruit的构造方法被调用"<<endl;
????}
????void?PutFruit()
????{
???????cout<<"父类的PutFruit方法被调用"<<endl;
????}
};
????
class?CApple:public?CFruit
{
public:
????CApple()
???????:CFruit()//CFruit()调用父类构造函数
????{
???????cout<<"子类CApple的构造方法被调用"<<endl;
????}
????void?PutFruit()
????{
???????CFruit::PutFruit();//调用父类PutFruit函数
???????cout<<"子类的PutFruit方法被调用"<<endl;
????}
};
int?main(int?argc,?char*?argv[])
{
????CApple?apple;
????apple.PutFruit();
????return?0;
}
而c#中,差不多就是用base代替了父类名,如下:
using?System;
class?Fruit
{
????public?Fruit()
????{
????????Console.WriteLine("父类Fruit的构造方法被调用");
????}
????public?void?PutFruit()
????{
????????Console.WriteLine("父类的PutFruit方法被调用");
????}
}
class?Apple:Fruit
{
????public?Apple()
????????:?base()//base()调用父类的构造方法
????{
????????Console.WriteLine("子类Apple的构造方法被调用");
????}
????public?void?PutFruit()
????{
????????base.PutFruit();//调用父类的PutFruit方法
????????Console.WriteLine("子类的PutFruit方法被调用");
????}
}
class?Program
{
????static?void?Main(string[]?args)
????{
????????Apple?apple?=?new?Apple();//构造方法被调用
????????apple.PutFruit();//调用PutFruit方法
????}
}
另sealed关键字修饰的类不可以被继承。
看下面这个类:
sealed?class?Fruit
{
????public??void?PutFruit()
????{
????????Console.WriteLine("父类的PutFruit方法被调用");
????}
}
Fruit是不可以派生出其它类的。
partial关键字可以使类分开来定义。
看下例:
partial?class?Apple//partial关键字,分开定义。
{
????public?void?OutApple()
????{
????????Console.WriteLine("OutApple()");
????}
}
partial?class?Apple
{
????public?int?Number?=?100;
????public?void?OutNumber()
????{
????????Console.WriteLine("{0}",?Number);
????}
}
class?Program
{
????static?void?Main(string[]?args)
????{
????????Apple?apple?=?new?Apple();
????????apple.OutApple();
????????apple.OutNumber();
????}
}
分开来定义类的格式就是上面那样,只要用partial关键字修饰就行了。上面的局部类都是在同一个文件里,也可以写在不同的文件里。