C#2005 .NET3.0高级编程学习笔记————类和结构,类的数据成员,类的函数成员(方法、属性)

  类和结构

类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供罗勒处理和访问数据的方法。类定义了每个类对象(实例)可以包含什么数据和功能。例如一个类表示一个顾客,就可以定义字段CustomerID,FirstName,LastName和Address,以及 包含该顾客的信息,还可以定义处理存储在这些字段中的数据的功能。

class   Customer
{
        
public int CustomerID;
        
public string FirstName;
        
public string LastName;
        
public string Address;
}

         结构与类的区别是它们在内存中的存储方式(类是存储在堆(heap)上的引用类型,而结构是存储在堆栈(stack)上的值类型)、访问方式和一些特性(如结构不支持继承)。较小的数据类型使用结构可提高性能。但在语法上,结构与类非常相似,主要区别是使用关键字struct代替class来声明结构

struct   CustomerStruct
{
        
public int CustomerID;
        
public string FirstName;
        
public string LastName;
        
public string Address;
}

       对于类和结构,都使用关键字new来声明实例:这个关键字创建对象并对其进行初始化。

Customer   myCustomer = new  Customer();
CustomerStruct   myCustomer2
= new  CustomerStruct();

       类成员

     类中的数据和函数称为类的成员。除了这些成员外,类还可以包含嵌套的类型(例如其他类)。类中的所有成员都可以声明为public或private。

       数据成员

       数据成员包含了类的数据——字段、常量和事件。数据成员可以是静态数据(与整个类相关)或实例数据(类的每个实例都有它自己的数据副本)。通常,对于面向对象的语言,类成员总是实例成员,除非用static进行了显式声明。

        字段是于类相关的变量。前面的例子已经使用了Customer类中的字段,一旦实例化Customer对象,就可以使用语法Object.FieldName来访问这些字段。

Customer  myCustomer = new  Customer();
myCustomer.FirstName
= " Jerry " ;

       常量与类的关联方式同变量与类的关联方式一样。

       事件是类的成员,在发生某些行为(如改变类的字段或属性,或者进行了某种形式的用户交互操作)时,它可以让对象通知调用程序。

        函数成员

       函数成员提供了操作类中数据的某些功能,包括方法、属性、构造函数和终结器(finalizer)、运算符以及索引器。

       方法是与某个类相关的函数,它们可以是实例方法,也可以是静态方法。实例方法处理类的某个实例,静态方法提供了更一般的功能,不需要实例化一个类。

       属性是可以在客户机上访问的函数组,其访问方式与访问类的公共字段类似。

       构造函数是在实例化对象时自动调用的函数。它们必须与所属类同名,且不能有返回类型。构造函数用于初始化字段的值。

      终结器(析构函数)类似于构造函数,它们的名称与类相同,但前面有一个~符号。终结器在C#中用得少,因为CLR会自动进行垃圾收集。另外不可能预测什么时候调用终结器。

      运算符执行的最简单的操作就是+和-。C#还允许指定把已有的运算符应用于自己的类(运算符重载)。

      索引器允许对象以数组或集合的方式进行索引。

          方法

            方法的声明

         在C#中,每个函数成员都必须与类或结构相关。正式的C#术语实际上区分了函数和方法:“函数成员”不仅包含方法,而且月包含类或结构的一些非数据成员,例如索引器、运算符、构造函数和析构函数等,甚至还有属性。

          在C#中,每个方法都单独声明为public或private,不能使用public:块把几个方法定义组合起来。所有的C#方法都在类定义中声明和定义。方法的定义包括方法的修饰符、返回值的类型、方法名、输入参数的列表和方法体。

[modifiers]   return_type  MethodName([Parameters])
{
      Method  body
}

        每个参数都包括参数的类型名及在方法体中的引用名称。但如果方法体有返回值,return语句就必须与返回值一起使用,以指定出口点。

public   bool  Test( int  x, int  y)
{
       
return (x==y);
}

       如果方法没有返回值,就把返回类型指定为void。如果不带参数,仍需要在方法名后面写上一对空的圆括号()。此时return语句是可选的,注意方法可以包含任意多个return语句。

public   bool  Test( int  value)
{
      
if(value<0)
      
{
            
return false;
      }

      
return  true;
}

            调用方法     

         C#中调用方法时,必须使用圆括号。下面的例子MathTest说明了类的定义和实例化、方法的定义和调用的语法。

using  System;
namespace  Ling.Note.One
{
     
class  MainEnterpoint
      
{
            
static void  Main()
             
{
                   Console.WriteLine(
"Pi  is "+MathTest.GetPi());
                   MathTest  math
=new MathTest();
                   math.value 
= 30;
                   Console.WriteLine(
"Value field  of "+ math.value);
                       Console.WriteLine("Square is"+ math.Getsquare());
             }

      }


      
class  MathTest
       
{
            
public  int value;
            
public  int Getsquare()
            
{
                  
return  value*value;
            }

           

            
public  static double GetPi()
            
{
                  
return 3.14159;
            }

       }

}

         给方法传递参数     

       参数可以通过引用或值传递给方法。在变量通过引用传递给方法时,被调用的方法得到的就是这个变量,所以在方法内部对变量进行的任何改变在方法退出后仍旧发挥作用。而如果变量是通过值传递给方法的,被调用的方法得到的是变量的一个副本,在方法退出后,对变量进行的修改会丢失。

          C#中所有参数都是通过值来传递的,除非特别说明。

using  System;
namespace   Ling.Note.One
{
       
class  ParameterTest
        
{
             
static void  SomeFunction(int[]   ints,int  i)
             
{
                     ints[
0]=100;
                     i
=100;
             }


            
public static int Main()
            
{
                 
int i=0;
             
int[]  ints={0,1,2,4,8};
                SomeFunction(ints , i);
                Console.WriteLine(
"i =" + i );
                Console.WriteLine(
"ints[0] =" + ints[0] );
                
return 0;
            }

        }

}

          结果是i=0,ints[0]=100。注意字符串是不同的,因为字符串是不能改变的(如果改变字符串的值,就会创建一个全新的字符串),所以字符串无法采用一般引用类型的行为方式。在方法调用中,对字符串所做的任何改变都不会影响原来的字符串。

             ref参数

           通过值传递变量是默认的,也可以迫使值参数通过引用方式传送给方法。需要使用ref关键字。如果把一个参数传递给方法,且这个方法的输入参数前带有ref关键字,则该方法对变量所作的任何改变都会影响原来对象的值。

static   void  SomeFunction( int []  ints,  ref    int  i)
{
      ints [
0=100;
      i
=100;
}

       在调用该方法时,还需要添加ref关键字:

SomeFunction(ints,   ref   i);

       out关键字

      C#要求变量在被引用前必须用一个初值进行初始化。尽管在把输入变量传递给函数前,可以用没有意义的值初始化它们,因为函数将使用真实、有意义的值初始化它们,但这样做是没有必要的,有时甚至会引起混乱。C#编译器使用out关键字来初始化输入参数,当在方法的输入参数前面加上out关键字时,传递给该方法的变量可以不初始化。该变量通过引用传递,在调用该方法时,还需要使用out关键字,与在定义该方法时一样

static   void  SomeFunction( out   int  i)
{
        i
=100;
}


public   static   int  Main()
{
       
int i;
       SomeFunction(
out i);
       Console.WriteLine(i);
       
return 0;
}

              out关键字是C#中的新增内容,该关键字的引入使C#更安全,更不容易出错。

         方法的重载

          C#支持方法的重载——方法的几个不同签名(名称,参数个数,参数类型)的版本,为了重载方法,只需要声明同名但参数个数或类型不同的方法即可。

class   Test
{
       
void DoSomething(string result)
       
{
             .........
       }

        
void  DoSomething(int result)
        
{
            ..........
        }

}

         因为C#不支持可选参数,所以需要使用方法重载来达到此目的。

class   MyClass
{
       
int   DoSomething(int x)
       
{
             DoSomething(x,
10);
       }

       
int  DoSomething(int  x,int y)
       
{
                .........
       }

}
 

          两个方法不能仅在返回类型上有区别,不能仅根据参数是声明为ref还是out来区分。

       属性

          属性是一个方法或一对方法,在客户机代码看来,他们是一个字段。

mainForm.Height  =   400 ;

      在语法上,上面的代码类似于设置一个字段,但实际上是调用了属性访问器,它包含的代码重新设置了窗体的大小。

        在C#中定义属性,可以使用下面的语法:

public    string  SomeProperty
{
     
get
      
{
            
return  "this is the property value";
      }

      
set
       
{
            .............
       }

}

       get访问器不带参数,且必须返回属性声明的类型。也不应为set访问器指定任何显式参数,但编译器假定它带一个参数,其类型也于属性相同,并表示为value。

private    string  foreName;
public   string  ForeName
{
       
get
        
{
              
return  foreName;
        }

        
set
        
{
               
if(value.Length > 20)
               
{
                  ......
               }

               
else
               
{
                     foreName 
= value;
               }

        }

}

           在属性定义中省略set访问器,就可以创建只读属性。

private   string  foreName;
public    string   ForeName
{
      
get
        
{
              
return  foreName;
        }

}

       同样,在属性定义中省略get访问器,就可以创建只写属性。

      C#允许给属性的get和set访问器设置不同的访问修饰符,在get和set访问器中,必须有一个具备属性的访问级别。

     JIT编译器可以生成高度优化的代码,并在适当的时候内联代码(用内联代码代替函数调用)。如果某个方法或属性的执行代码仅是调用另一个方法,或返回一个字段,则该方法或属性肯定是内联的。(在何处内联代码的决定完全由CLR作出,无法控制)。


 

你可能感兴趣的:(C#2005 .NET3.0高级编程学习笔记————类和结构,类的数据成员,类的函数成员(方法、属性))