俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

《C#与.NET3.5高级程序设计(第4版)》笔记5

C#编程语言,从本质上讲是一组类型声明。所以,本人认为第一个要区分的点是:类型!=类。

public class Class_public
   {
       public void fun_public()
       {
           fun_protected();//通过其一的方式进行访问
        }
       protected void fun_protected()
       { } 

   }

public class Class_child_public:Class_public
    {
        public void fun_test()
        {
            Class_public PublicClass = new Class_public();
            PublicClass.fun_public();
            PublicClass.fun_internal();
            //PublicClass.fun_protected();//不能通过此方式访问哦,这是通常犯得理解错误
              fun_protected();//通过其三的方式访问
              Class_child_public PublicChildClass = new Class_child_public();
            PublicChildClass.fun_protected();//这是我们加以约束的其二方式进行访问                       //当然也可以是通过Class_child_public的子孙类来访问
        }
    }

public class Class_other

    {

         public void fun_test()
         {
            Class_child_public PublicChildClass = new Class_child_public();
            // PublicChildClass.fun_protected();//无法访问哦,因为这不是在继承链上

          }

    }

本文中,我们不必管具体地类怎么定义,怎么继承,怎么调用,怎么回收。

属性也可以是静态的哦,当然,静态属性和静态方法的操作是一致的,静态属性只能操作静态数据。

三.类怎么分类与类与类之间的关系

  • private修饰类的成员或嵌套类型,由定义他们的类(或结构)访问;

我们需要了解类是什么,类的作用是什么,类怎么分类,类与类之间的关系是什么,类在整个程序集中的地位是什么

  • 一个类只能定义一个静态构造函数;

  • 静态构造函数不允许访问修饰符(如public static 是不对的),也不接受任何参数;

  • 无论创建多少类型的对象,静态构造函数只执行一次(也就是只能对静态成员设置一次);

  • 运行库创建类实例或者首次访问静态成员之前,运行库调用静态构造函数(也就是第一次并且只有第一次使用了这个类,执行静态构造函数);

  • 静态构造函数执行先于任何实例级别的构造函数;

  • 显然也就无法使用this和base来调用构造函数。

  • 若类存在静态成员变量,系统会自动提供一个默认静态构造函数,否则默认不提供。

类如要被访问,或者访问程序集中其他类,则涉及到类的访问级别问题。类具有public与internal两个访问级别。public级别的类可以被外部程序集访问,internal级别的类只能被所在程序集引用,这也是默认的访问级别。

这句话比较难以理解,稍微详细解释一下:如果某类有一个成员声明为protected internal,则位于同一程序集的类可以访问此成员,但位于另一个程序集中的类不可访问它,除非这个位于另一个程序集的类是这个成员所在类的子类。 这其实是internal和protected的可访问性的并集,符合任何一个都行。

其实,从以下几个方面描述类应该是比较清晰的:

需要强调的是,这两种方法的使用目的是一致的,属性优点就是对象的用户可以只使用一个命名项就能操作内部数据。

如果你学习过数据结构,就应该知道数据类型仅仅是对数据的定义。在C#中类型分为预定义类型和自定义类型,而类属于6种自定义类型中一个,所以可以称类为类类型,英文名为class。

这里,this就代表被调用的构造函数,后面跟着被调用构造函数的参数。

当然,如果想要系统的学习C#还是应该先了解一下.Net框架,本文目的只是从相对宏观的角度讲清楚C#中的类。关于类的实现的具体细节网络上到处都有。本文适合初学C#的新手。

注意:区分多态接口和接口概念,多态接口的虚拟或抽象成员,能够让派生类实现类似于接口的功能。

二.类在整个程序集中的地位

 

一,类是什么?

this关键字用于对当前实例(对象)的访问,也就是代表当前实例,因此,this无法用于类级别,如静态方法中,就不能使用。

每一个程序集都有命名空间namespace,如果还不太理解程序集的概念,可以先认为是某一个.cs文件就是一个程序集。在命名空间中是不可以直接定义预定义类型的,要从类或者其他自定义类型开始编程。为什么要有命名空间?因为它保证了不同程序集同时被调用的时候,即使有相同的命名存在,也可以兼容。

  • 类型名(上面的emp)必须一致;

  • 定义在相同的命名空间中。

当然,也可以分为实例类和静态类,如果对C#有一些了解的话应该知道实例与静态的含义。

注意:既然是链形式的调用,不正确的调用可能导致死循环!例如:  

对于C#中的类,只有两种,要么是object类,要么是派生类。所有的派生类都继承自object类,不同的是有的派生类是直接继承object类,有的派生类是间接继承object类。这里不必知道到底怎么实现继承,但是应该知道的是类可以继承该类所在程序集中其他类,也可以继承其他程序集中的访问级别为public的类。

5.6常量数据和只读字段

  类是C#中一种预定义的类型,一种类型就会包含数据成员与函数成员,对于类,其数据成员是“字段与常量”,其函数成员是“方法,属性,索引,事件,构造函数,析构函数,运算符”。对于其中的任何一个成员,都可以讲解一个篇章,相信大部分C#参考书上都有,这里不做赘述。

(1)定义静态方法(和字段)

(3)定义静态构造函数

在OOP中还有另一种形式的代码重用(不是继承),就是包含/重用模型(has-a关系,也叫聚合,如在一个类中包含另外一个类)。

注意,只能定义成员和成员变量,不能对成员进行操作,比如重新赋值等,这些操作只能在成员中进行操作!

有点儿混乱,那么既然都是常量数据,不如也让只读字段为隐式静态的就ok啦,为什么还提供对象级别的访问呢。主要是因为只读字段可以在构造函数进行赋值,因此,可能对不同的对象,需要不同的常量值,这时就要在构造函数时设置不同的常量值啦。

这里需要注意的是,仅当属性同时具有 get 访问器和 set 访问器时,才能对访问器使用可访问性修饰符哦,也就是只有set或者之后get时,不能对他们进行单独的修饰符。可以理解,因为既然只有一个,那么干脆就将这个属性设置为protected吧,单独设置一个单独的访问器,意义好像不大。

疑问:从文章第155页可以看出,实际上嵌套类型也可以使用public和internal修饰符,为什么文中没有给出呢?

(1)定义一对传统的访问方法和修改方法

class motorcycle 
{ public string name;//成员变量叫name 
public void setdrviername(string name)//传入参数也叫name 
{ 
name=name;
//那么这句话是把哪个值赋值给哪个呢,本意应该是将参数值赋值给成员变量,//但是实际上此句执行了将参数值name赋值给参数值name了。 
this.name=name;
//这才是将参数值赋值给成员变量的意思 
} 
}

this关键字有两个用途:

第五章 定义封装的类类型

要知道,如果类定义了非静态数据(实例数据),则类型的每个对象都会维护字段的独立副本,每个类实例都会分配独立的内存。

主要有:

当然,对于常规方法,为了防止构造函数中冗余代码,可以专门设计一个方法,构造函数进行调用,但是一个更简洁的方法就是,让一个接收最多参数个数的构造函数座位“主构造函数”,实现必须的验证逻辑等。其余构造函数使用this关键字把传入的参数转发给主构造函数,并且提供所有必须的其他参数,这需要功过冒号运算符来实现,如:

封装概念的核心是,对象的内部数据不应该从公共接口直接访问。封装提供了一种保护状态数据完整性的方法。与定义公共字段相比(很容易发生数据损坏),应该更多的定义私有数据字段,这种字段可以由调用者间接地操作,操作方法有:

另外,也不能对两个访问器set和get同时设置修饰符,会提示“不能为属性的两个访问器同时指定可访问性修饰符”。还需要注意的是,对于set或get域的访问修饰符,一定不能比此属性的修饰符的可访问性大哦。

5.4  访问修饰符

可以对整个属性的可访问性使用修饰符(不修饰则为私有的,无法访问。)

car mycar=new car();

在封装时,必须考虑类型的哪个方面对我们应用程序的哪部分可见。准确的说,类型以及他们的成员总是使用某个关键字来定义,用于控制他们对应用程序其他部分如何可见。

(4)定义静态类

尽管第一种已经可以满足要求,但是还是提倡使用属性来强制数据保护。对于CLR来说,属性总是映射到“实际的”访问方法和修改方法。

默认的访问修饰符:

它使用一种叫做“构造函数链”的技术来设计类,当一个类中存在多个构造函数,并且构造函数中存在冗余代码(比如都要进行某种检查验证等),这可以使用。

因此,静态成员只能操作静态数据,非静态方法可以使用静态数据和非静态数据,因为静态数据对类型的所有实例都是可用的。

只需在方法定义前加static即可。注意,静态成员只能操作静态数据或调用类的静态方法,如果尝试调用非静态类数据或非静态方法,将编译错误!

类是由数据字段(也叫成员变量)和操作这个数据的成员(构造函数、属性、方法、事件等)所构成的自定义类型。其中的字段数据用于表示类实例(也称对象)的“状态”,对象就是表示使用new关键字创建的某个类类型的实例。对象必须使用new关键字来分配到内存,如果不使用new,在使用这个对象时,产生编译器错误。例如对于下句:

属于

默认的成员可访问性

该成员允许的声明的可访问性

enum

public

class

private

public

protected

internal

private

protected internal

interface

public

struct

private

public

internal

private

继承是指基于已有类定义来创建新类定义的语言能力。这种is-a的关系也叫经典继承。

俄罗斯贵宾会,封装就是让用户不必了解实现细节,来保护数据完整性。

  • protected修饰类的成员或嵌套类型,被定义它的类型或派生类(包括直接访问和通过派生类实例来访问(若是非静态的))访问;

只读字段:

问:第128页中说默认构造函数自动设置为私有的,应该不对吧?私有的还怎么使用啊?

public class MyClass
{
    int a=0;
    //int b=this.a;//成员变量初始值处不能用this
public static void RunSnippet()
{
    //public int c=this.a;//静态方法中不能用this;
}
}

注意:this 关键字将引用类的当前实例。静态成员函数没有 this。
this 关键字可用于从构造函数、实例方法和实例访问器中访问成员。
在静态方法、静态属性访问器或字段声明的变量初始值设定项中引用 this 是错误的。

答:是这样的,如果类没有给出默认构造函数,则系统提供的默认构造函数确实不是私有的,如果是自己写的默认构造函数,并且不加修饰,则就是私有的,无法访问,因此必须加上public修饰符。

提示:其实应用程序对象(Main入口点所在类)就可以定义为一个静态类(默认不是哦),让他只包含静态成员并且不能直接创建。

5.3  OOP的支柱

  • protected internal(或者internal protected )修饰类的成员或嵌套类型,在定义它的程序集或类型中或者派生类中可用。其含义是“访问范围限定于此程序集那些由它所属的类派生的类型”。

5.2 static关键字

private string empssn; 
public string socialnumber//类似于定义变量,没有()哦 
{ 
get
{return empssn;}//使用return返回属性值 
set
{ empssn=value;}//value关键字是属性被设置的值! 
}

只读字段用readonly修饰,和常量类似,只读数据字段不能在赋初值后改变。和常量不同的是,赋给只读字段的值可以在运行时决定,因此,构造函数作用域中进行赋值是合法的,但是其他地方不行(运行时,非构造函数中不能赋值给只读字段)。另外,若不给他赋值,系统会给出一个默认值的!

属性由作用域中定义的get和set两个作用域组成。之所以上面是加了引号的实际的方法,是因为在底层,c#属性也是使用方法来真正执行操作的。实际上属性被映射到由CLR内部调用的隐藏的set_xxx/get_xxx方法。因此,如果你设置了一个叫做name的属性,那么就别在类中定义set_name和get_name这样的方法(当然这个名称的数据字段也不行)了哦~~否则编译时候会提示冲突滴!

class motorcycle 
{ 
public int driverintensity; 
public string drivername; 
public motorcycle() 
{} 
public motorcycle(int intensity):this(intensity,"") 
{} 
public motorcycle(string name):this(0,name) 
{} 
public motorcycle(int intensity,string name) 
{ //相关代码 }
} 

C#中的构造函数是一种特殊方法,在使用new关键字创建对象时被间接调用,它不会有返回值(void都不行),名字和类名一致。

  • internal修饰类型(或结构)或者类的成员,只能在程序集内部访问,其含义是“只有属于同一程序集的类可以访问此类或此成员”;

类的构造函数:

本文由俄罗斯贵宾会发布于编程,转载请注明出处:《C#与.NET3.5高级程序设计(第4版)》笔记5

您可能还会对下面的文章感兴趣: