值参数:
在方法声明时不加修饰的形参就是值参数,它表明实参与形参之间按值传递。当这个方法被调用时,编译器为值参数分配存储单元,然后将对应的实参的值赋值到形参中。实参可以是变量、常量、表达式,但要求其值的类型必须与形参声明的类型相同或者能够被隐式地转化为这种类型。这种传递方式的好处是,在方法中对形参的修改不影响外部的实参,也就是说数据只能传入方法而不能从方法传出,所以值参数有时也被称为入参数。
引用参数:
引用与值参数不同,引用参数并不创建新的存储单元,它与方法调用中的实在参数变量同处一个存储单元,因此在方法内对形参的修改就是对外部实参变量的修改。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Method_Sort 7 { 8 class Myclass 9 { 10 public void Sort(ref int x, ref int y, ref int z) 11 { 12 int tmp; 13 if (x > y) 14 { 15 tmp = x; 16 x = y; 17 y = tmp; 18 } 19 if (x >z) 20 { 21 tmp = x; 22 x = y; 23 y = tmp; 24 } 25 if (y >z) 26 { 27 tmp = x; 28 x = y; 29 y = tmp; 30 } 31 32 } 33 34 } 35 class Program 36 { 37 static void Main(string[] args) 38 { 39 Myclass m = new Myclass(); 40 int a, b, c; 41 a = 30; 42 b = 20; 43 c = 10; 44 m.Sort(ref a, ref b, ref c); 45 Console .WriteLine ("a = {0}, b = {1}, c = {2}",a, b, c); 46 Console .Read (); 47 } 48 } 49 }
使用ref时注意:
1、ref关键字仅对跟在它后面的参数有效,而不能应用于整个参数列表。
2、在调用方法时,也用ref修饰实参变量,因为是引用参数,所以要求实参与形参的数据类型必须完全匹配,二期实参必须是变量,不能是常量或者表达式。
3、在方法外,ref参数必须在调用之前明确赋值,在方法内,ref参数被视为已赋过初始值。
this关键字表示引用当前对象实例的成员,在实例方法体内也可以省略this,直接引用numItems,实际上两者的语义相同,而静态方法不与对象关联,理所当然地不能用this指针。this关键字一般用于实际构造函数、实例方法和实例访问器,以访问对象实例成员。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 /*商品销售管理,每一种商品对象要存储的是商品总数和商品的单价,没销售意见商品要计算销售额和库存*/ 6 namespace cashRegister 7 { 8 class cashRegister 9 { 10 int numItems; //商品总数 11 double cost; // 商品单价 12 static double cashSum; //cashSum是静态变量,计算销售总额 13 public cashRegister(int numItems, double cost) 14 { 15 this.numItems = numItems; 16 this.cost = cost; 17 18 } 19 public cashRegister() 20 { 21 numItems = 0; 22 cost = 0.0; 23 24 } 25 static cashRegister() 26 { 27 cashSum = 0.0; 28 // this.cashSum = 0.0; 错误,静态方法不允许使用this 29 } 30 public void makeSale(int num) //实例方法 31 { 32 this.numItems -= num; 33 cashSum += cost * num; 34 } 35 public static double productCost() // 静态方法可以访问静态成员 36 { 37 return cashSum; 38 // return this.cashSum; 错误,静态方法不能使用this 39 } 40 public int productCount() 41 { 42 return numItems; 43 } 44 } 45 class Program 46 { 47 static void Main(string[] args) 48 { 49 cashRegister Candy = new cashRegister(200, 1); 50 cashRegister Chips = new cashRegister(500, 3.5); 51 Candy.makeSale(5); 52 Console.Write("Candy.numItems = {0} ", Candy.productCount()); 53 // 调用实例方法与对象Candy相关联 54 Console.Write("cashSum = {0} 元 ", cashRegister.productCost()); 55 // 调用静态方法与类cashRegister相关联 56 Chips.makeSale(10); 57 Console.Write("Chips.numItems = {0} ", Chips.productCount()); 58 // 调用实例方法与对象Chips相关联 59 Console.WriteLine("cashSum = {0} 元 ", cashRegister.productCost()); 60 // cashSum计Candy和Chips售出总价 61 Console.Read(); 62 } 63 } 64 }
方法的重载与覆盖
一个方法的名字和形式参数的个数、修饰符及类型共同构成了这个方法的签名,同一个类中不能有相同签名的方法。如果一个类中有两个或者两个以上的方法同名,而它们的形参个数或形参类型不同是允许的,它们属于不同的方法签名。但是仅仅是返回类型不同的同名方法,编译器是不能识别的。
override virtual
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace virtual_override 7 { 8 class A 9 { 10 public void F() 11 { 12 Console.WriteLine("A.F"); 13 } 14 public virtual void G() 15 { Console.WriteLine("A.G"); } 16 } 17 class B : A 18 { 19 new public void F() 20 { Console.WriteLine("B.F"); } 21 public override void G() 22 { 23 Console .WriteLine ("B.G"); 24 } 25 } 26 27 class Program 28 { 29 static void Main(string[] args) 30 { 31 B b = new B(); 32 A a = b; //a是class A类型的引用,b是class B类型的引用 33 a.F(); 34 b.F(); 35 a.G(); 36 b.G(); 37 Console.Read(); 38 } 39 } 40 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace virtual_override1 7 { 8 public class Shape //定义基类 Shape 9 { 10 protected string Color; 11 public Shape() { } 12 public Shape(string Color) 13 { 14 this.Color = Color; 15 } 16 public string GetColor() 17 { 18 return Color; 19 } 20 public virtual double GetArea() 21 { 22 return 0.0; 23 } 24 } 25 public class Circle : Shape // 定义Cicle类,从Shape类中派生 26 { 27 private double Radius; 28 public Circle(string Color, double Radius) 29 { 30 this.Color = Color; 31 this.Radius = Radius; 32 } 33 public override double GetArea() 34 { 35 return System.Math.PI * Radius * Radius; 36 } 37 } 38 public class Rectangular : Shape //派生类Rectangular,从Shape类中派生 39 { 40 protected double Length, Width; 41 public Rectangular(string Color, double Length, double Width) 42 { 43 this.Color = Color; 44 this.Length = Length; 45 this.Width = Width; 46 } 47 public override double GetArea() 48 { 49 return Length * Width ; 50 } 51 public double PerimeterIs() //周长 52 { 53 return (2 * (Length + Width)); 54 } 55 } 56 public class Square : Rectangular //派生类Square 从Rectangular类中派生 57 { 58 public Square(string Color, double Side) : base(Color, Side, Side) { } 59 } 60 61 class Program 62 { 63 static void Main(string[] args) 64 { 65 Circle Cir = new Circle("orange", 3.0); 66 Console.WriteLine("Circle color is {0},Circle area is {1} ", Cir.GetColor(), Cir.GetArea()); 67 Rectangular Rect = new Rectangular("Red", 13.0, 2.0); 68 Console.WriteLine("Rectangular color is {0},Rectangular area is {1},Rectangular perimeter is {2} ", Rect.GetColor(), Rect.GetArea(), Rect.PerimeterIs()); 69 Square Squ = new Square("Green", 5.0); 70 Console.WriteLine("Square color is {0},Square area is {1},Square perimeter is {2} ", Squ.GetColor(), Squ.GetArea(), Squ.PerimeterIs()); 71 Shape Shp = Cir; 72 Console.WriteLine("Circle area is {0} ", Shp.GetArea()); 73 Shp = Rect; 74 Console.WriteLine("Rectangular area is {0} ", Shp.GetArea()); 75 Console.Read(); 76 } 77 } 78 }
抽象类:
抽象类是一种特殊的基类,并不与具体的事物相联系,抽象类的定义使用关键字abstract。抽象类不能被实例化,它只能作为其他类的基类。例如,并没有“图形”这种具体的事物,所以将“图形”定义为抽象类,派生了“圆形”和“四边形”这样一些可以产生具体实例化的普通类。
在抽象类中也可以使用关键字abstract定义抽象方法,要求所有的派生非抽象类都要重载实现抽象方法。引入抽象方法的原因在于,抽象类本身是一种抽象概念,有的方法并不要求具体实现,而是留下来让派生类来重载实现。所以abstract的方法不能带有方法体,abstract与{}(方法体)不能共存。
抽象类和抽象方法的实现:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace abstract_override 7 { 8 public abstract class Shape 9 { 10 protected string Color; 11 public Shape() { } 12 public Shape(string Color) 13 { 14 this.Color = Color ; 15 } 16 public string GetColor() 17 { 18 return Color; 19 } 20 public abstract double GetArea(); //抽象方法 21 } 22 public class Circle : Shape 23 { 24 private double Radius; 25 public Circle(string Color, double Radius) 26 { 27 this.Color = Color ; 28 this .Radius = Radius ; 29 } 30 public override double GetArea() // 重载 31 { 32 return System.Math.PI * Radius * Radius; 33 } 34 } 35 public class Rectangular:Shape 36 { 37 protected double Length, Width; 38 public Rectangular(string Color, double Length, double Width) 39 { 40 this.Color = Color; 41 this.Length = Length; 42 this.Width = Width; 43 } 44 public override double GetArea() // 重载 45 { 46 return Length * Width; 47 } 48 public double PerimeterIs() 49 { 50 return (2 * (Length + Width)); 51 } 52 } 53 public class Square : Rectangular 54 { 55 public Square(string Color, double Side) : base(Color, Side, Side) { } 56 } 57 58 class Program 59 { 60 static void Main(string[] args) 61 { 62 Circle Cir = new Circle("orange", 3.0); 63 Console.WriteLine("Circle color is {0},Circle area is {1} ", Cir.GetColor(), Cir.GetArea()); 64 Rectangular Rec = new Rectangular("red", 13.0, 2.0); 65 Console.WriteLine("Rectangula color is {0},Rectangula area is {1},Rectangula perimeter is {2} ", Rec.GetColor(), Rec.GetArea(), Rec.PerimeterIs()); 66 Square Squ = new Square("green", 5.0); 67 Console.WriteLine("Square color is {0},Square area is {1},Square perimeter is {2} ", Squ.GetColor(), Squ.GetArea(), Squ.PerimeterIs()); 68 Console.Read(); 69 } 70 } 71 }