类和对象
曾经一次面试,有人问我,说到面向对象,你最先想到什么,我说继承、多态等,他说不,应该是封装,你说的这些都是封装。
只写C#里关于类和对象的问题。
1、类型参数
public class Pair<TFirst,TSecond>
{
public TFirst First;
public TSecond Second;
}
要声明为采用类型参数的类类型称为泛型类类型。结构类型、接口类型和委托类型也可以是泛型。
2、构造函数
构造函数也可以这样写
public class Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Point3D: Point
{
public int z;
public Point3D(int x, int y, int z): base(x, y) {
this.z = z;
}
}
3、引用参数
在C#里引用参数用ref修饰。
4、输出参数
输出参数用out修饰,输出参数,可是不用初始化。
5、参数数组:允许向方法传递可变数量的实参。参数数组使用 params 修饰符声明。只有方法的最后一个参数才可以是参数数组,并且参数数组的类型必须是一维数组类型。例: public class Console
{
public static void Write(string fmt, params object[] args) {...}
public static void WriteLine(string fmt, params object[] args) {...}
...
}
在具有参数数组的方法的调用中,既可以传递参数数组类型的单个实参,也可以传递参数数组的元素类型的任意数目的实参。在后一种情况下,将自动创建一个数组实例,并使用给定的实参对它进行初始化。例:
Console.WriteLine("x={0} y={1} z={2}", x, y, z);
等同于:
string s = "x={0} y={1} z={2}";
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);
6、索引器
支持按照索引数组的方法来索引对象。索引器的声明与属性类似,不同的是该成员的名称是 this,后跟一个位于定界符 [ 和 ] 之间的参数列表。在索引器的访问器中可以使用这些参数。与属性类似,索引器可以是读写、只读和只写的,并且索引器的访问器可以是虚的。例:
public class List<T>
{
T[] items;
public T this[int index] {
get {
return items[index];
}
set {
items[index] = value;
OnChanged();
}
}
}
引用:
List<string> names = new List<string>();
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
string s = names[i];
names[i] = s.ToUpper();
}
索引器可以被重载,这意味着一个类可以声明多个索引器,只要其参数的数量和类型不同即可。
7、事件
一种使类或对象能够提供通知的成员。事件的声明与字段类似,不同的是事件的声明包含 event 关键字,并且类型必须是委托类型。例:
public class List<T>
{
protected virtual void OnChanged() {
if (Changed != null) Changed(this, EventArgs.Empty);
}
public event EventHandler Changed;
}
在声明事件成员的类中,事件的行为就像委托类型的字段(前提是该事件不是抽象的并且未声明访问器)。该字段存储对一个委托的引用,该委托表示已添加到该事件的事件处理程序。如果尚未添加事件处理程序,则该字段为 null。
客户端通过事件处理程序 (event handler) 来响应事件。事件处理程序使用 += 运算符附加,使用 -= 运算符移除。下面的示例向 List<string> 类的 Changed 事件附加一个事件处理程序。
using System;
class Test
{
static int changeCount;
static void ListChanged(object sender, EventArgs e) {
changeCount++;
}
static void Main() {
List<string> names = new List<string>();
names.Changed += new EventHandler(ListChanged);
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
Console.WriteLine(changeCount); // Outputs "3"
}
}
总例:
using System;
public class List<T>
{
const int defaultCapacity = 4;
T[] items;
int count;
public List(int capacity ) {
items = new T[capacity];
}
public int Capacity {
get{
return items.Length;
}
set{
if (value<count) value = count;
if (value!=items.Length){
T[] newItems=new T[value];
Array.Copy(items,0,newItems,0,count);
items = newItems;
}
}
}
public T this[int index]{ //索引器
get{
return items[index];
}
set{
items[index]=value;
OnChanged();
}
}
public void Add(T item){
if (count == Capacity) Capacity = count * 2;
items[count]= item;
count++;
OnChanged();
}
protected virtual void OnChanged(){
if (Changed != null) Changed(this,EventArgs.Empty);
}
public override bool Equals(object other) {
return Equals(this, other as List<T>);
}
public override int GetHashCode(){
return base.GetHashCode();
}
public event EventHandler Changed; //事件
}
class Test
{
static int changeCount;
static void ListChanged(object sender, EventArgs e) {
changeCount++;
}
static void Main() {
List<string> names = new List<string>(4);
names.Changed += new EventHandler(ListChanged);
names.Add("Zhang San");
Console.WriteLine(changeCount);
names.Add("Li Si");
Console.WriteLine(changeCount);
}
}

浙公网安备 33010602011771号