【C#复习知识点2】 类、继承

——类

访问权限

public:所有类都可以访问,包括其他程序集
private:只有该类自己可以访问。
protected:只有继承该类的派生类可以访问,包括其他程序集的派生类。
internal:程序集内,都可以访问。
protected internal:程序集内,都可以访问,并且其他程序集的派生类也可以访问。

类的访问权限

类只有public和internal两种访问权限修饰符,internal只允许程序集内可见。

静态字段和静态函数

静态字段和静态函数都通过类名调用,并且静态函数中无法访问实例成员,只能访问静态成员。

常量

类中字段常量和静态字段类似,都可以在类不实例化的情况,通过类型调用。不过与静态字段不同的是,常量没有自己的存储位置,在编译时被编译器替换。并且常量不允许设置为static。

属性

属性属于函数成员。
属性的get和set访问器不可以显示使用,只能隐示使用。




属性的另个访问器必须有一个,否则会报错。
属性也可以声明为静态,表示静态的函数成员,和静态方法的用法基本一样。

构造函数

构造函数用来初始化实例的状态,如果声明为public,表示允许在类外部实例化,构造函数不允许有返回值。如下,构造函数在函数体内初始化类的实例成员,前提是这些程序是public
静态构造函数

静态构造函数会初始化类的静态字段。
静态构造函数由系统会自动调用。
它的调用在引用任何静态成员之前,在创建类的任何实例之前(也就是说会在普通构造函数之前)。
一个类只能有一个静态构造函数,并且不能有参数,也不能有访问修饰符。
不能访问所在类的实例成员。

readonly

表示只读的,它的效果和const效果一样,不过readonly更像是把变量标注为只读。
const需要在声明语句中初始化,而readonly可以在声明语句初始化,也可以在构造函数中初始化,都不可以在函数成员中初始化
const的值只能在编译时决定,而readonly可以再运行时决定。
const总是静态的,readonly可以是实例,也可以用static修饰为静态,
const在内存中没有存储位置,readonly有存储位置。

this关键字

this关键字在类中使用,用来引用当前的实例,相对的,它无法引用静态字段;同时由于静态函数成员无法使用实例成员,因此this关键字无法在静态函数成员中使用。
this关键字的主要作用就是区分成员和本地变量。

索引器

索引器可以让我们以数组访问的行书对实例的成员字段进行操作,索引器跟属性很类似,可以说属性是为一个数据成员提供get和set,索引器为多个相同类型的成员提供get和set。
它有许多和属性一样的性质,不过,它不能声明为static。
下面是一个索引器的例子

    class QuickSort
    {
        private string str1;
        private string str2;
        private string str3;

        //注意,与属性不同的是,索引器没有名字,使用this关键字,后面跟上中括号,里面是一个索引
        public string this[int idx]
        {
            set
            {
                switch (idx)
                {
                    case 0: str1 = value; break;
                    case 1: str2 = value; break;
                    case 2: str3 = value; break;
                    default:
                        break;
                }
            }
            get
            {
                switch (idx)
                {
                    case 0: return str1;
                    case 1: return str1;
                    case 2: return str1;
                    default:
                        return null;
                }
            }
        }

下面是使用这个索引器

QuickSort sort = new QuickSort();
sort[0] = "abc";
sort[1] = "bcs";
sort[2] = "saa";
string s = sort[2];
string s2 = sort[0];

索引器可以重载,如果重载,需要有不同的参数列表。


分部类

分部类使用partial修饰符,分部类可以让一个类分在几个文件中完成,在socket网络游戏编程这部书中,处理协议的函数就是写在一个类的许多分部类中。
分部方法

分部方法是在分部类中,分部方法把一个方法分割为一个方法的声明,和一个方法的实现。它有以下几个要求:
1、返回类型必须是void。
2、签名不能包括访问修饰符,也就是说分部方法是分部类的隐式私有的。
3、参数列表不能包含out参数。
4、声明个实现部分都是用partial上下文关键字,放在void前面。

如下是一个分部方法:

——继承

可以使用父类引用,子类实例,因为子类包含父类需要的一切,在子类实例化时,有一部分是基类,所以基类可以去引用;但是基类实例化是没有派生类的,所以不可以反过来。

new和virtual、override的区别

new和virtual、override容易让人混淆头晕
首先new关键字用于派生类不希望使用基类的成员(函数成员字段成员都可以使用,不能对static使用)时,可以做到屏蔽的作用,不会干扰到基类的成员。比如:

    class Base
    {
        public string str = "base";
        public void Print()
        {
            Console.WriteLine(str);
        }
    }
    class Child : Base
    {
        new public string str = "child";
        new public void Print()
        {
            str += " this";
            Console.WriteLine(str);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Base bas = new Base();
            Child child = new Child();
            Base bas1 = new Child();
            bas.Print();    //打印base
            child.Print();  //打印child this
            bas.Print();    //打印base

            Console.ReadLine();
        }
    }

而virtual、override只能作用于函数成员,如方法,属性等,不能重写static类型,虽然也能做到派生类屏蔽基类成员的作用,这与new关键字效果相同。但是更重要的是,在父类引用,派生类实例时,创建的对象会向上找,找到最高的那个重写(忽视低的)然后调用。

   class Base
    {
        public string str = "base";
        virtual public void Print()
        {
            Console.WriteLine(str);
        }
    }
    class Child : Base
    {
        override public void Print()
        {
            string str = "child";
            Console.WriteLine(str);
        }
    }
    class Second : Child
    {
        public override void Print()
        {
            string str = "second";
            Console.WriteLine(str);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Base bas = new Base();
            Child child = new Child();
            Second second = new Second();
            Base bas1 = new Child();
            Base bas2 = new Second();
            Child child1 = new Second();

            bas.Print();        //打印base
            child.Print();      //打印child
            second.Print();     //打印second
            bas1.Print();       //打印child
            bas2.Print();       //打印second
            child1.Print();     //打印second

            Console.ReadLine();
        }
    }
构造函数的执行

在继承链中,每个类执行自己的构造函数体之前都会执行其基类的构造函数。因此,不要在基类构造函数中调用虚函数,因为基类构造函数执行时,调用虚函数,而派生类还没有完全初始化。

派生类使用基类构造函数有两种形式,第一种是使用base,第二种是使用this。一般都是用base,this更好的用法是用在一个类拥有多个构造函数时,把多个构造函数相同的部分提取出来,然后其他构造函数通过this使用这个提取出来的构造函数,如下:

    class Base
    {
        public string str = "base";
        public Base()
        {
            str = "new base";
        }
        public Base(string str) : this()//通过this使用其他的构造函数
        {
            Console.WriteLine(str + this.str);
        }
    }
     class Program
    {
        static void Main(string[] args)
        {
            Base bas = new Base("this ");//打印this new base
            
            Console.ReadLine();
        }
    }
抽象类和抽象函数成员

使用abstract关键字修饰。
抽象类有以下要求:
1、不能被实例化。
2、主要用途用于被继承,并且抽象类可以继承其他抽象类。
3、抽象类既可以有抽象函数成员,又可以有普通函数成员。
抽象函数成员:
1、只能有签名,不能有函数体。
2、只能设置函数成员(方法,属性,事件,索引器),不能设置字段成员。
3、继承该抽象类,必须重写所有的抽象函数成员。

密封类

使用sealed关键字修饰,表示这个类不允许类继承。

静态类

静态类就是用static修饰的类,主要用途就是作为工具类,具有以下特点:
1、所有成员必须全部都是静态的,不允许普通成员。
2、静态类不允许被继承,也就是隐式密封类。

3、可以有一个静态构造函数,但是不允许有普通构造函数,因为不允许实例化。
扩展方法

这是一个十分实用的功能
它的作用是让你可以向第三方的静态类中添加我们自己定义的函数,然后依然通过第三方静态类调用。它有几个条件:
1、扩展方法必须卸载静态类中。
2、扩展方法必须包含关键字this的参数作为第一个参数,并在后面跟上要扩展的类的类的名称和引用。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358