1.接受任意多个参数示例
static int SumVals(params int [] Vals) {....}
int valSum=SumVals(1,2,4,5,8);
2.ref关键字的使用(如下myNumber声明为const、或未赋值(如int myNumber)声明为ref非法)
static void ShowDouble(ref int val)
{ val *= 2; Console.WriteLine("val doubled = {0}",val);}
调用:
int myNumber=5;
Console.WriteLine("myNumber = {0}",myNumber);
ShowDouble(ref myNumber); //函数
Console.WriteLine("myNumber = {0}",myNumber);
结果:myNumber=5; val doubled=10; myNumber=10;
3.out关键字的使用(用法与ref基本相同,区别:out参数引用需声明为未赋值(如int myNumber))
4.static关键字定义的变量在同一空间中的任何函数都可使用
5.结构函数(简化代码)
struct customerName
{
public string firstName,LastName;
public string Name()
{
return fristName+" "+lastName;
}
}
customerName=myCustomerName;
myCustomerName.firstName="Will";
myCustomerName.lastName="Smith";
Console.WriteLine(myCustomerName.Name());
6.委托的运用(使用范围事件、列表排序有几个不同的方法)
Class Program
{
delegate double ProccessDelegate(double param1,double param2);
static double Multiply(double param1,double param2)
{ return param1* param2; }
stattic double Divide(double param1,double param2)
{ return param1/param2; }
static void Main(string[] args)
{
ProccessDelegate process;
Console.Write("Enter 2 numbers separated with a comma:");
string input=Console.ReadLine();
int commaPos=input.Indexof(','); //获取","所在位置
double param1=Convert.ToDouble(input.SubString(0,commaPos-1));
double param2=Convert.ToDouble(input.SubString(commaPos+1,input.Length-commaPos-1));
Console.WriteLine("Enter M to Multiply or D to Divide:");
string input=Console.ReadLine();
if (input="M")
proccess=new ProcessDelegate(Multiply); //可简写为:proccess=Multiply;
else
proccess=new ProcessDelegate(Divide);
Console.WriteLine("Result:{0}",proccess(param1,param2));
Console.ReadLine();
}
}
7.调试的两种方式
VS(可修改断点属性)和VCE, 可使用checked关键字强制抛出异常,对于投入生产的应用程序应把调试写入日志文件。
调试语句:Debug.write(),Trace.write();Debug.writeIf()
8.析构函数
如果在删除对象实例前,需要完成一些重要的操作,就应提供特定的析构函数。
9.接口
方法和属性组合封装特定功能的一个集合,接口不能单独存在。在发布接口后最好不要修改,应创建新的进行扩展,如新版本X2。
可删除的对象是,IDisposable接口中的Dispose()方法using:
<ClassName> <VariableName>=new <ClassName>; using(<VariableName>){ ... }
10.继承
C#中的 对象仅能直接派生一个基类,基类也有自己的基类。基类的成员可以是虚拟的,派生类需要重写。internal关键字的类不能继承基类和不能被继承。
类(seal)可以是密封的,密封的类不能用作基类,所以没有派生类。
注:接口可继承多个接口,类也可继承多个接口,但只能继承一个基类。
11.多态性
继承的一个结果是派生基类的类在方法和属性上有一定的重叠,因此,可以使用相同的语法处理从同一个基类实例化的对象。
例:基类Animal有一个EatFood()方法,则派生于它的Cow和Chicken调用这方法,语法:
Cow myCow=new Cow(); Chicken myChicken=new Chicken();
myCow.EatFood(); myChick.EatFood();
多态性则更推进一步,可把某个派生类型的变量赋给基本类型的变量:
Animal myAnimal=myCow;
不需要的进行强制类型转换,就可通过这个变量调用基类:
myAnimal.EatFood();
可把基类转换为派生变量,调用派生类的方法:
Cow myNewCow=(Cow)myAnimal;
myNewCow.Moo();
多态性是一种极有效的技巧,其使用的代码最少,只要子类和孙子类在继承层次结构中有一个相同的类,就可使用同样的方式利用多态性。
12. 接口的多态性
接口不能实例化,但可建立接口变量,利用变量访问接口提供的方法和属性。
例:不使用基类Animal提供的方法,把方法放在IConsume上
Cow myCow=new Cow(); Chicken myChicken=new myChicken();
IConsume consumeInterface;
consumeInterface=myCow; consumeInterface.EatFood();
consumeInterface=myChicken; consumeInterface.EatFood();
13.windows应用程序中的OOP
1.事件的调用(单击button创建一个新的button,再单击此button改变文本):
private void button1_Click(object sender,System.EventArgs e)
{
((Button)sender).Text="Clicked!"; //多态性,object
Button newButton=new Button(); //新建一个button
newButton.Text="New Button";
newButton.Click+=new EventHander(newButton_Click); //新建的button调用的单击处理事件(重载处理注册为click事件)
Controls.add(newButton);
}
private void newButton_Click(object sender,System.EventArgs e)
{
((Button)sender).Text="new Clicked!";
}
2.类和接口的实例运用:
2.1 为下述类和接口绘制UML图
>抽象类HotDrink,它有方法Drink()、AddMilk()和AddSugar(),以及属性Milk和Sugar。
>接口ICup,它有方法Refill()和Wash(),以及属性Color和Volume。
>派生于HotDrink的类CupOfCoffee支持ICup接口,还有一个属性BeanType。
>派生于HotDrink的类CupOfTea支持ICup接口,还有一个属性LeafType。
UML图,属性和方法加分开线就可,^表连线方向,->表实现的接口:
HotDrink <Interface>ICup
Milk Color
Sugar Volume
Drink() Refill()
AddMilk() Wash()
AddSugar()
^
CupOfCoffee->ICup CupOfTea->ICup
BeanType LeafType
2.2为一个函数编写代码,接受上述两个杯子对象中的任意一个,作为一个参数,该函数可以为它传送任何杯子对象调用AddMilk()、Drink()、Wash()方法。
static void ManipulateDrink(HotDrink drink)
{
drink.AddMilk();
drink.Drink();
ICup cupinterface=(ICup)drink; //很危险,可给这个函数传递其它类(类不支持ICup接口)
cupinterface.wash();
}
改为:
static void ManipulateDrink(HotDrink drink)
{
drink.AddMilk();
drink.Drink();
if (drink is ICup) //检查类drink是否支持ICup接口
{
ICup cupInterface=drink as ICup;
cupInterface.wash();
}
}
14.利用多态时,GetType()和typeof(C#运算符,把类名转换为System.Type对象)
例:当比较类名时
MyComplexClasss myObj=new MyComplexClasss();
if ( myObj.GetType()==typeof(MyComplexClass) ) { ... }
15.构造函数和析构函数
在类的构造函数中执行多个任务,把这些代码放在一个地方是非常方便的。
public class MyBaseClass
{
public MyBaseClass() { }
public MyBaseClass( int i ) { }
}
public class MyDerivedClass:MyBaseClass
{
public MyDerivedClass() { }
public MyDerivedClass( int i ) { }
public MyDerivedClass( int i,int j ) { }
}
1.无论在派生类上使用什么构造函数(默认的构造函数或非默认的构造函数),除非明确指定否则就使用基类的默认构造关於生命的,如执行上面代码:
MyDerivedClass myObj=new MyDerivdClass(4);
执行顺序如下:
1.1.执行System.Object.Object()构造函数
1.2.执行MyBaseClass.MyBaseClass()构造函数
1.3.执行MyDerivedClass.MyDerivedClass(int i)构造函数
2.若要执行MyBaseClass(int i)和MyDerivedClass(int i,int j )构造函数,则实现如下:
public class MyDerivedClass:MyBaseClass
{
public MyDerivedClass():this(5,6) //指定在执行MyDerivedClass()前先执行MyDerivedClass(int i,int j)
{ }
public MyDerivedClass(int i) { }
public MyDerivedClass(int i,int j):base(i) //指定执行基类中的MyBaseClass(int i)构造函数,就不会执行MyBaseClass()构造函数
{ }
}
执行顺序如下:
2.1执行System.Object.Object()构造函数
2.2执行MyBaseClass.MyBaseClass(int i)构造函数
2.3执行MyDerivedClass.MyDerivedClass(int i,int j)构造函数
2.4执行MyDerivedClass.MyDerivedClass()构造函数
3.如下构造函数无效,成了无限循环
public class MyDerivedClass:MyBaseClass
{
public MyDerivedClass():this(5) { }
public MyDerivedClass(int i):this() { }
}
16.抽象类与接口
抽象类主要是用作对象系列的基类,共享某些主要特性,例如,共同的目的和结构。则主要用于类,这些类在水平上有所不同,但仍可以完成某些相同的任务。
类与结构的主要区别是类是引用类型,结构是值类型。
浅度复制与深度复制,(复制值与引用的方式)
17.如何定义不能创建的类?把它定义为静态类,或者将其所有构造函数定义为私有。
不能创建的类可以通过它们拥有的静态成员来使用,实际上,可以通过这些静态成员来访问它的实例。如下所示:
class CreateMe()
{
private CreateMe() { }
static public CreateMe GetCreateMe() { return new CreateMe(); }
}这里,公共构造函数可以访问私有构造函数,因为它在同一个类的定义中。
18..NET中字段的命名方法
public int MyInt;
private int myInt;
19.类的关键字:virtual、abstract、override、extern(方法放在其他地方)、new关键字(隐藏方法、可以隐藏接口的基类成员)
20.隐藏成员(new)
public class MyBaseClass
{
public void DoSomething() { }
}
public class MyDerivedClass:MyBaseClass
{
new public void DoSomething() { }
}
21.重写成员(virtual)
public class MyBaseClass
{
public virtual void DoSomething() { Console.WriteLine("Base imp"); }
}
public class MyDerviedClass:MyBaseClass
{
pubic override void DoSomething() { Console.WriteLine("Dervied imp");}
}
MyDerivedClass myObj=new MyDerivedClass();
MyBaseClass myBaseObj=myObj;
myBaseObj.DoSomething();
执行结果为:Derived imp
22.隐藏基类的方法 (new) :(接口中隐藏的基接口也使用new)
基类如上
public class MyDerivedClass:MyBaseClass
{
new public void DoSomething() { Console.WriteLine("Dervied imp"); }
}
执行结果:Base imp
23.调用重写或隐藏的基类方法
要对派生类的用户隐藏继承的公共成员,但仍能在类中访问其功能。
要给继承的虚拟成员添加实现代码,而不简单的用重写的新执行代码实现它。
public class MyBaseClass
{
public virtual void DoSomething() { }
}
public class MyDerviedClass:MyBaseClass
{
public override void DoSomething()
{
//Derived implementation
base.DoSomething();
//More implementation
}
}
24.部分类(partial):部分类的任何参数都不能是out参数,但可以是ref参数; 部分方法也不能使用virtua、abstract、override、new、sealed、extern修饰符。
24.1 注意:应用于部分类的结果是也会应用于整个类。
public partial class MyClass:IMyInterface1 { ... }
public partial class MyClass:IMyInterface2 { ... }
结果等同于:
public class MyClass:IMyInterface1,IMyInterface2{ ... }
24.2partial部分(部分方法在编译代码时非常重要)
public partial class MyClass
{
partial void DoSomethingElse();
public void DoSomething()
{
Console.WriteLine("DoSomething() Execution Started.");
DoSomethingElse();
Console.WriteLine("DoSomething() Execution Finished.");
}
}
public partial class MyClass
{
partial void DoSomethingElse()
{
Console.WriteLine("DoSomethingElse() Called.");
}
}
调用DoSomething(),执行结果如下:
DoSomething() Execution Started.
DoSomethingElse() Called.
DoSomething() Execution Finished.
25.第10章习题5洗牌功能键需要处理