zoukankan      html  css  js  c++  java
  • 2017-9-23C#笔记(类的索引,事件,运算符,this访问器,派生,分部类,抽象类,封闭类,静态类,类与结构的不同)

    1.类的索引

    索引是一组get和set锋访问器,支持按照饮用数组元素的方法来引用对象.索引通常便是多个数据成员,并且它总是以雷类的事例成员的方式存在.声明索引的方法:

    返回类型     this  [参数列表]

    {

    Get

    {    }

    set

    {        }

    }

    例如:using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

     

    namespace ConsoleApplication1  //引入命名空间

    {

        class Program

        {

            class  Myclass{

                int x;

                int y;

                public int this[int index]   //声明索引

                {

                    get

                    {

                        if (index == 0)

                            return x;

                        else

                            return y;

                    }

                    set

                    {

                        if (index == 0)

                            x = value;

                        else

                            y = value;

                    }

                }

            }

            static void Main(string[] args)

            {

                Myclass mc = new Myclass();

                mc[0] = 10;  //使用索引访问私有字段X;

                mc[1] = 15;  //使用索引访问私有字段Y;

                Console.WriteLine("{0},{1}",mc[0], mc[1]);   //输出10,15;

                Console.Read();

            }

        }

    }

    2.事件

    事件是一种对对象或类能够提供通知的成员。客户端可以通过通过提供事件处理程序为相应的事件添加可执行代码。事件机制是以消息未基础的,特定的操作会发生形影的消息,而关注事件的对象接收到这些消息时,即开始执行指定的处理过程。也就是事件时消息传播的途径,各种指令的传递都是通过消息来完成的。产生事件的对象叫做事件发生者,或者世界接收者。

    3.运算符

    (1)运算符的定义

    运算符可以用于类实例的运算符含义,定义的形式如下:

    运算符修饰符           类型        operate          运算符号(参数列表)

    {

    语句序列}

    C#可重载的运算符:

    ①  :一元运算符:+,-,!,~,++,--,true,false

    ②:二元运算符:+,-,*,/,%,&,|,^,<<,>>

    ③:转换运算符:implicit,explicit;

    下列规则适用于所有的运算符声明:

    ①  运算符声明必须同时包含public 和static修饰符

    ②  运算符的形参必须是执值形参,在运算符声明中指定其他形参会导致编译时的错误

    ③  运算符的签名比喻不同于在同一个类中声明的所有的其他运算符的签名

    ④  运算符声明 中引用的所有类型都必须具有与运算符本省相同的可访问性

    ⑤  同一修饰符在一个运算中生声明中多次出现时错误的;

    4.this访问器

    This关键字是对当前对象的引用,this访问只能在实例构造函数、实例方法或属性和索引的实例访问中使用,不能再任何静态函数成员的代码中使用。它通常用作一下两个目的:

    ①   :用于区分类的成员和方法的本地变量参数

    ②:用作调用方法参数

    5.派生

    (1)继承,封装和多态性是面向对象编程的三个主要的特性

    (2)C#中的所有的类都默认继承与object类

    派生类的定义:

    访问修饰符       class  派生类名称:父类名称

    {

    成员列表

    }

    一般来说,派生类的成员列表中只定义派生类新增加的成员

    在设计派生类的时候,应注意:

    ① 派生类可以即形成鸡肋中除了实例构造函数,析构函数和静态构造函数之外的所有的其他成员,无论这些基类成员具有怎样的可访问性

    ② 派生类可以根据实际在继承积累的基础上添加新的成员,但是派生类并不能移除继承类的成员的定义

    ③ 派生类可以通过声明有相同名称(数据成员)或签名(函数成员)的新成员的同名基类成员,使被隐藏的成员在派生类中不可以直接访问

    (3)派生类的成员访问

    ①基类中声明为private的成员虽然可以被派生类继承,但是不能被派生类成员和派生类用户访问

    ②基类中声明为protected的成员可以被派生类成员访问但是不能被派生类用户访问

    ④ 基类声明为protected internal的成员可以被同一个程序中的派生类成员访问

    ⑤ 基类声明中为internal的成员可以被同一个程序中的派生类成员和派生类用户访问

    ⑥ 基类中声明为public的成员在派生类中访问同样不受限制

    (1)   派生类的构造函数

    在设计派生类的构造函数要考虑的是派生类新增成员和基类继承的数据成员的初始化;默认情况下,闯将派生类的实例时,基类的无参构造函数被调用。

    派生类的构造函数如下:

    public 派生类名称(参数列表):base(要调用的基类构造函数的参数列表)

    {

    函数体

    }

    声明不带函数初始化语句的构造函数有两种形式:

    //形式一

    public  派生类名称(参数了列表)//隐式调用基类的无参构造函数

    {

    函数体

    }

    //形式二

    public  派生类名称(参数列表): base()  //显示调用基类的无参构造函数

    {

    函数体

    }

    创建派生类的对象时,会先调用基类的构造函数,在调用派生类的构造函数

    销毁派生类对象时,会先调用派生类的析构函数,即有内层向外层的逐条的销毁。

    (2)   多态性

    同一操作应用于不同类的实例,不同类型将进行不同的解释产生不同的结构,即为多态。

    C#中通过继承实现多态,实现的方法就是:对基类的成员进行隐藏覆盖

    要隐藏一个基类成员:

    ①  对于数据成员来说,需要声明一个新的同样类型的成员,并使用相同的名称:对于函数成员来说,需要声明新的带有相同签名的函数成员

    ②  在派生类中声明用来隐藏基类成员的同名成员时需要使用new修饰符来修饰

    class Person // 基类定义

    { {

    public string  name; ;

    protected int Age; ;

    public void print ()

    { {

    Console. . WriteLine ("I am a Person.");

    } }

    } }

    class Student : : Person // 派生类定义

    { {

    internal string  Sno

    7.5.6 多态性

    7

    { { get; ; set ; }

    public string Smajor

    { { get; ; set ; }

    new protected int Age; ; // 隐藏基类数据成员 Age

    new public void print () // 隐藏基类方法 print

    { {

    Console. . WriteLine ("I am a student.");

    } }

    } }

    ① 访问基类被隐藏的成员,可以使用基类访问表达式,基类访问表达式如下:

    base.基类成员名

    ② 覆盖基类的成员

    如果有一个派生类对象的引用,使用类型准换算法把该引用转换成基类类型,就可以回去该基类部分的引用,格式如下:(基类名)派生类对象名,类似于数据的强制类型转换的方法,通过强制的转化从而获得某些相应的功能

    ③ 将派生类对象的引用转换成鸡肋用来访问派生类时,得到的是基类的成员

    ④ 需虚方法提供了是基类引用访问“升至”派生类内的方法

    ⑤ 虚方法即为使用关键字virtual声明的实例方法,没有使用关键字virtual声明的方法称为虚方法。

    借助虚方法使得基类引用派生类的方法需要猫族一下的条件:

    (1)   派生类的方法和基类的方法具有相同的方法恰名和返回类型

    (2)   基类的方法比空虚使用virtual声明为虚方法

    (3)   派生类的方法需要使用override标注为覆写方法

    使用虚方法和覆写方法时需要注意:

    (1)   虚放和覆写放必须具有同样的可访问性

    (2)   不能覆写静态方法和虚方法

    (3)   方法,属性,索引以及事件都可以使用vitrtual和override进行声明和覆写

    (4)   覆写方法可以出现在继承的任意层次

    当使用对象的基类引用电泳一个覆写方法时,方法的调用被沿派生层次追溯到标记override的放的最新派生版本,或称为继承序列中备份最小的版本。

    1. 1.       分部类

    如果一个类的内容很长,则可以将类的声明分割成几个部分来声明,每个部分称为一个分部类。

    (1)每个分部类的声明中都含有一些类成员的声明,这些分部类可以在一个文件中,也可以在不同文件中。

    (2)将类分割成几个分部类声明时,每个局部必须被标为partial class,而不是单独的关键字class

    (3)除了必须添加类型修饰符partial之外,分部类的声明和普通类声明相同

    下面是分部类的一般声明形式:

    partial class PartClass{ {

    成员1 1 的声明

    成员2 2 的声明

    ……

    } }

    partial class PartClass{ {

    成员n n 的声明

    成员n n+ +1 1 的声明

    ……

    } }

    组成所有类的分部类声明必须一起编译,并且这些分部类分、开声明和在一起声明应该具有相同的含义;分部类的各个部分必须具有相同的可访问性,如 public、private 等。

    1. 2.       抽象类

    抽象类即为使用abstract关键字修饰的类。

    抽象类的内部可能包括使用abstract修饰的没有实现的虚方

    法,称为抽象方法。

    抽象类是不完整的类,它只能用做基类来派生出其他类,其

    中包含的抽象方法必须在每个非抽象派生类中重写。例如:

    abstract class A A // 抽象类A A

    { {

    public abstract void F F (); // 抽象方法F F

    } }

    abstract class B B: : A A // 抽象类B B

    { {

    public void G G () {}

    } }

    class C C: : B B // 非抽象类C C

    { {

    public override void F F () { // 覆写基类中的抽象方法F F

    // actual implementation of F

    } }}

    使用抽象类时需注意:

    ①   抽象类不能直接实例化,并且对抽象类使用 new 运算符会导致编译时错误;

    ②允许但不要求抽象类包含抽象成员,但是包含抽象成员的类必须声明为抽象类;

    ③抽象类声明时不能使用sealed修饰符;

    ④当从抽象类派生非抽象类时,这些非抽象类必须具体实现所继承的所有抽象成员,从而重写那些抽象成员;

    ⑥ 对于每个抽象类,至少应提供一个具体的继承类型。

    1. 3.       封闭类

    如果类定义时使用sealed 修饰符进行修饰,则说明该类是一个密封类。密封类只能被用作独立的类,不能从密封类派生出其他类。如果一个密封类被指定为其他类的基类,则会发生编译时错误。密封类的一般定义形式:

    sealed class 类名

     {

    成员列表

    }

    密封类不能同时声明为抽象类。

    当调用密封类实例的虚函数成员时可以转换为非虚调用来处理。

    可以使用密封来限制开发人员扩展某些指定的框架。

    如果类满足如下条件,则应将其密封:

    ① 类是静态类;

    ② 类包含带有安全敏感信息的继承的受保护成员;

    ③ 类继承多个虚成员,并且密封每个成员的开发和测试开销

    明显大于密封整个类;

    ④ 类是一个要求使用反射进行快速搜索的属性。密封属性可

    提高反射在检索属性时的性能。

    不要在密封类中声明受保护成员或虚成员。因为如果类是密封的,则它不能有派生类。受保护成员只能从派生类进行访问,虚成员也只能在派生类中重写。

    1. 4.       静态类

    使用static修饰符声明的类称为静态类。静态类是密封的,不能实例化,不能用作类型,而且仅可以包含静态成员。

    使用静态类时需要遵守下面的规则,违反这些规则时将导致编译时错误:

    ①静态类不可包含 sealed 或 abstract 修饰符;

    ②静态类不能显式指定基类或所实现接口的列表,它隐式的从object类继承;

    ③静态类只能包含静态成员;

    ④静态类不能含有声明的可访问性为protected或protectedinternal的成员。

    静态类没有实例构造函数。静态类可以包含静态构造函数。如果非静态类包含需要进行重要的初始化的静态成员,也应定义静态构造函数。静态类的成员并不会自动成为静态的,成员声明中必须显式包含一个 static 修饰符(常量和嵌套类型除外)。

    例如:

    using System;

    public static class TemperatureConverter

    {

    public static double CelsiusToFahrenheit( ( stringtemperatureCelsius) )

     {

    double celsius = = Double. . Parse( ( temperatureCelsius );

    double fahrenheit = ( celsius * 9 9 / / 5 5 ) + 32;

    return fahrenheit; ;

     }

    public static double FahrenheitToCelsius( ( stringtemperatureFahrenheit) )

     {

    double fahrenheit = Double. . Parse( ( temperatureFahrenheit );

    double celsius = ( fahrenheit - -32 ) * 5 /  9;

    return celsius; ;

     }

    }

    class TestTemperatureConverter

     {

    static void Main ()

     {

    Console. . WriteLine ("Please select the convertordirection");

    Console. . WriteLine ("1. Celsius - - > Fahrenheit.");

    Console. . WriteLine (“2. Fahrenheit - - > Celsius.”);

    string selection = = Console. . ReadLine ();

    double F, C = 0 ;

    switch ( ( selection) )

    {

    case "1":

    F =TemperatureConverter. . CelsiusToFahrenheit( ( Console. . ReadLine( ());

    Console. WriteLine ("Temperature inFahrenheit: {0:F2}" , F );

    break; ;

    case "2":

    C = TemperatureConverter. . FahrenheitToCelsius( ( Console. . ReadLine( ());

    Console. . WriteLine ("Temperature in Celsius:{0:F2}" , C );

    break; ;

    default: :

    Console. . WriteLine ("Please select aconvertor.");

    break; ;

    }

    }

    }

    1. 5.       类与结构的不同

    (1)       数据类型不同

    结构式是值类型:值类型对象在栈中分配存储空间,所有的基类型都是结构类型

    类是引用类型:引用类型实例在堆中分配存储空间

    结构处理作为积累性对待的小对象,而类处理某个商业逻辑

    结构式值类型,所以结构之间的赋值可以创建新的结构;而类是引用类型,类实例之间的赋值只是复制引用

    注意:

    结构与类的基类型都是oblject

    结构对象分配在栈上而不是堆上,如果并不适用“新建(new)”那么初始化所有字段之间,字段将保持未赋值的状态,且对象不可用

    (2)       继承性‘

    结构:不能从另外一个结构或者类继承,本身不能被继承

    类:除非被显示声明为sealed,否则类可完全扩展,可以继承其他类和接口,自身也能被继承

    结构能够继承接口,语法与类继承接口一样。例如:

    interface IImage{

    void Paint ();

    struct Picture: : IImage{

    public void Paint (){

    //painting code goes here

    }

    private int x, y, z; ; //other struct members

    } }

    (3)       内部结构

    结构:添加构造函数时对系统生成的午餐构造函数没有影响;构造函数必须完成对结构所有成员的初始化;没有西沟含糊是;没有abstract和sealed修饰符;不能有protected修饰符,可以不适用new初始化,在结构中初始化实例字段是错误的

    类:添加构造函数时系统将不生成默认的无参构造函数;有析构函数;可以使用abstract和sealed有protected修饰符,必须使用new初始化

    ①     堆栈的空间有限,对于大量的逻辑对象,创建类要比创建结构好一些

    ②     结构表示如点,矩形和颜色的轻量对象

    ③     在表现抽象和多级别的对象层次时,类是最好的选择

    ④     大多数情况下该类型只是一些数据时,结构是最佳的选择

     

    每天进步一点点;不为琐事困扰,每日岁月静好。
  • 相关阅读:
    静态代理和动态代理
    Tomcat的作用思考及NIO的应用(要区分Java NIO和操作系统的NIO模型)
    破坏双亲委托机制的一些情况---Tomcat和JDBC,破坏后的安全问题
    springboot cache---本地缓存的使用
    springboot--异步执行的方法及定时执行的方法
    springboot--事务的使用
    数据结构--堆排序
    数据结构--树的非递归遍历
    最长公共子串的长度和构造
    2015 小结及其2016计划
  • 原文地址:https://www.cnblogs.com/Adaisme/p/7586154.html
Copyright © 2011-2022 走看看