C# 基础(类)
Class:
- class是blueprint,用来描述What kinds of data the object holds and works with, What the object can do what its functionality is
- Usually, your C# programs will define their own classes, as well as use the classes that are provided by the .NET framework
- Class define two major things(Fields and Properties & Methords)
- Class can inherit attribute and methords from other clas
- Define class:
class myClass { //fields to contain the class data int myInteger; string myMessage; //methords that define the class functionality public int myFunction() { return myInteger; //whatever other logic there is } public myClass(string defaultMsg) { myMessage = defaultMsg; //这个是constructor, 一般用来给fileds赋值的 } }
6: Use Class: 使用实例.方法
使用new来创建类的实例
myClass myObj = new myClass("Hello");
7: 使用类的fields和方法用"."
int myResult = myObj.AddNumber(5, 10);
8:Static: 使用类名.方法
Console.WriteLine("Hello World");
9:Instance member VS Static member:
1 namespace DefiningAClass 2 { 3 class MyClass{ 4 int myIntegar; 5 string meMessage; 6 public static int myStaticInt = 100; //static variable 7 8 public int myFunction() { //instance member function 9 return myIntegar; 10 } 11 12 public MyClass() { //Constructor use to initial fields 13 myIntegar = 50; 14 meMessage ="This is made from constructor" 15 } 16 } 17 class Program 18 { 19 static void Main(string[] args) 20 { 21 MyClass myC = new MyClass(); //调用Constructor 22 Console.WriteLine("Calling instance member function : {0}", myC.myFunction()); //使用instance member 23 Console.WriteLine("Calling static variable : {0}", MyClass.myStaticInt); //使用static member 24 Console.ReadLine(); 25 } 26 } 27 }
10:Access Modifier:
Private:只可class itself访问
Public: 可以被其他object访问
protected:可以class itself和集成的subclass访问
internal:can be accessed by any class in the same assembly(package of code like a library or other program)
eg:
Wine.cs namespace AccessModifier //注意创建的新类Wine被放在以project名字的NS下 { class Wine { public string Name; public decimal Price; private string Description; protected decimal dicount; public Wine(string wineName, decimal winePrice) { Name = wineName; Price = winePrice; dicount = 0.0m; } } }
Program.cs namespace AccessModifier { class Program { static void Main(string[] args) { Wine myWine = new Wine("Jacky", 100); myWine.Name = "ZXX"; myWine.Price = 200m; } } }
Property:
- property 就像field只不过他还有背后的逻辑
- 从外部看,他们像是成员变量,但是表现上像成员函数
- 定义像field,内部包含get,set, get里即把什么数值return给调用property的用户, set就是用一个value来set一个private变量,getter,setter实际就是两个简写的方法。
- property是典型使用puiblic的情况,其他还有Methord,和Event,其他类型一般都是private或者sealed,protected。
- property可以是只读或者只写
好处
- 对于使用property的人来说实现了逻辑封装,用户不必知道property内部实现了什么样的逻辑,只需要用就好了。
- property的内部逻辑变化了,外部使用不变,也不用关心。
- property的get,set可以有逻辑在里面,判断值。
比如:
再比如:
class Wine{
private decimal wholesalePrice;
private decimal retailMarkup;
public decimal Price{ //property可由get来赋值private
get{return wholesalePrice * retailMarkup;} //Price property的使用者不用关心Price的值怎么得到。
}
}
使用property逻辑结构1: 需要构造函数按顺序一步步传递值
一般带property的class结构:
- 首先private变量(内部保存)
- 其次property用来get, set上面的变量,作为用户我只知道消费property,不知道内部逻辑get里有怎么样的运算。(外部接口)
- 最后构造函数用来初始化各个private变量(内部初始化)使用property逻辑结构1:
使用property逻辑结构2: 还有一种比较简便使用property的方式,直接给property赋值:
public class FieldType { public string ReadableName { get; set; } public string InternalName { get; set; } public string DateType { get; set; } public override string ToString() { return ReadableName; } public FieldType(string readableName, string internalName, string dateType) { ReadableName = readableName; //property可由public的构造函数的参数赋值 InternalName = internalName; DateType = dateType; } }
Union/Ordered Property:
Value Type VS Reference Type:
对于Value Type,其j=i实际是copy了i本来的“5”到j中,两个内存是分开的。i的值被重写3后,j还是5。
对于reference type(即class的),其不是cope数据而是reference到x,y的内存地址。所以改变任何P1.x, p2.x都会改变最终内存里的数值
所以:
1 public class Pointer{ 2 public int x; 3 public int y; 4 } 5 ... 6 7 Point p = new Point(); //在内存中创建了p并且另一块内存位置存储着x,y。p指向x,y 8 p.x = 10; 9 p.y = 10; 10 Console.WriteLine("p.x is {0}", p.x); //输出10 11 testFun2(p); 12 Console.WriteLine("p.x is {0}", p.x); //因为是reference所以也指向pt的位置,所以输出为20 13 Console.ReadLine(); 14 15 static void textFun2(Point pt){ 16 Console.WriteLine("pt.x is {0}", pt.x); //输出10 17 pt.x += 10; 18 Console.WriteLine("pt.x is {0}", pt.x); //输出20,内部改变了,x内存地址的数值 19 }
Overloading: 同一个方法,代入不同参数.
1 namespace ConsoleApplication1 2 { 3 class Wine 4 { 5 public int year; 6 public string name; 7 public decimal price; 8 9 public Wine(string s) { 10 name = s; 11 } 12 public Wine(string s, int y) 13 { 14 name = s; 15 year = y; 16 } 17 public Wine(string s, int y, decimal p) 18 { 19 name = s; 20 price = p; 21 year = y; 22 } 23 } 24 class Program 25 { 26 static void Main(string[] args) 27 { 28 Wine w1 = new Wine("Charless Shaw Merlot"); 29 Wine w2 = new Wine("Mark Ryan Dissident", 2004); 30 Wine w3 = new Wine("Dom Perignon", 1994, 120.00m); 31 32 Console.WriteLine("{0}", w1.name); 33 Console.WriteLine("{0} {1}", w2.year, w2.name); 34 Console.WriteLine("{0}{1}{2}", w3.year, w3.name, w3.price); 35 Console.ReadLine(); 36 } 37 } 38 39 }
注意:返回值要一样,函数名要一样,不一样的就是参数
private bool GetText(string startText, out bool outBool)
{
...
}
private bool GetText(string startText, out int outInt) {
...
}
private bool GetText(string startText, out double outDouble) {
...
}
Overrriding: change the behavior of methord in baseClasses
caller并不知道我有那种phone,他只是知道我有phone,所以程序根据每个用户的不同phone实现不同的ring()
三个关键词:
virtual: 用来在base class中告诉compiler如下methord可以被subclass 的methord override
public virtual int myFunction(){...}
override: 用来在subclass中,告诉compiler这个methord override base class中同名的methord
public override int myFunction(){...}
base: 用来在subclass中,call base class methord
base.myFunction();
应用1:
class Program {
class baseClass { public virtual void doSomething() { Console.WriteLine("This is call from base class."); } } class subClass : baseClass { public override void doSomething() { base.doSomething(); //在subClass里call baseClass的function
Console.WriteLine("This is call from sub class"); } }
static void Main(string[] args)
{
subClass obj1 = new subClass(); obj1.doSomething(); //输出为:This is call from base class 和 This is call from sub class baseClass obj2 = new subClass(); obj2.doSomething(); //输出为:This is call from base class 和 This is call from sub class. 因为是override,所以尽管创建的是baseClass的实例,也找subClass的方法 baseClass obj3 = new baseClass(); obj3.doSomething(); //输出为:This is call from base class } }
应用2:
1 public class FieldType 2 { 3 public string ReadableName { get; set; } 4 public string InternalName { get; set; } 5 public string DateType { get; set; }
6 public override string ToString() //override ToString()方法 7 { 8 return ReadableName; 9 }
10 public FieldType(string readableName, string internalName, string dateType) 11 { 12 ReadableName = readableName; 13 InternalName = internalName; 14 DateType = dateType; 15 } 16 }
Abstract Class: 自己不可以instantiate,需要derived class来instantiate
作用是上面实际的给类汽车类可以随时增加,他们都是Vehicle class的衍生类,需要override 抽象类的abstract member,用来group一些共通的property和function到一个抽象类,force用户override这些property和function,需要derived类来实现这些共通的方法。
- abstract class不可以自己instantiate实例,需要继承的subclass(derived class)来instantiate一个实例
- abstract class有abstract member, derived class must override in order to provide the functionality.
public abstract class myClass{
public abstract void function(int arg1); //abstract member 需要被derived class override
}
实例:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 myDerivedClass mbc = new myDerivedClass(); 6 int result = mbc.addMethord(5, 6); 7 Console.WriteLine("{0}", result); 8 Console.ReadLine(); 9 10 } 11 12 13 abstract class myAbstractClass 14 { 15 public abstract int addMethord(int arg1, int arg2); 16 } 17 class myDerivedClass : myAbstractClass 18 { 19 public override int addMethord(int arg1, int arg2) 20 { 21 return arg1 + arg2; 22 } 23 }
......
这里留下可能性,可以继续写继承抽象类其他类,并给出该类下的方法may be return (arg1 * arg2);
......
24 }
Sealed Class:
sealed class和abstract class相反,用户不能derived class
之前没加sealed关键字的时候,mySubClass还可以derived myClass,加上sealed后就不可以了