zoukankan      html  css  js  c++  java
  • 继承和多态

    
    sealed关键字

    如果我们将类标记为sealed,编译器将不会允许我们从这个类型派生。(C#结构总是隐式密封的。因此,我们永远不可以从结构继承结构,从类继承结构或从结构继承类。结构只能用于建模独立的、用户定义的数据类型。如果希望是is-a关系,就必须使用类。)


    使用base关键字控制基类的创建


    protected关键字

    派生类型不再需要使用公共方法或属性来间接访问数据了。当然,可能的坏处在于:如果派生类型有权直接访问其父类内部数据,有可能会偶尔绕过公共属性内设置的既有业务规则。当定义受保护成员时,也就创建了一种父类和子类之间的信任级别,编译器不会捕获任何违背类型业务规则的异常。


    包含/委托编程

    class BenefitPackage

    {

       public  double  ComputePayDeduction()

       {  return 125.0;  }

    }

    partial class Employee

    {

        protected BenefitPackage  empBenefits=new BenefitPackage();

        public double GetBenefitCost()

        {   return empBenefits.ComputePayDeduction();  }

        public BenefitPackage Benefits

        {   get { return empBenefits;  }

            set { empBenefits=value;  }

        }

        .......

    }


    嵌套类型

    public class OuterClass

    {

         //公共嵌套类型可以被任何人使用

         public class PublicInnerClass { }

         //私有嵌套类型只可以被包含类的成员使用

         public class PrivateInnerClass { }

    }

    嵌套类型的特征:

    通过嵌套类型可以完全控制内部类型的访问级别,也就是可以声明为私有的(回忆一下,非嵌套类不能使用private关键字来声明)。

    由于嵌套类型是包含类的成员,所以它可以访问包含类的私有成员。

    通常,嵌套类型只用做外部类的辅助方法,而不是外部世界所准备的。

    //Employee嵌套BenefitPackage

    public partial class Employee

    {

        // BenefitPackage嵌套BenefitPackageLevel

        public class BenefitPackage

        {

            public enum BenefitPackageLevel

            {   Standard,Gold,Platinum  }

         }

         public double ComputePayDeduction()

         {  return 125.0  }

    }

    在这种嵌套关系里需要注意如何使用枚举:

    Employee.BenefitPackage.BenefitPackageLevel myBenefitLevel=Employee.BenefitPackage.BenefitPackageLevel.Platinum;


    virtual和override关键字

    多态为子类提供了一种方式,使其可以定义为由其基类定义的方法,这种过程叫做方法重写。

    partial class Employee

    {

         poblic virtual void GiveBonus(float amount)

         {  Pay+=amount ; }

    ......

    }

    用virtual关键字标记的方法成为虚方法。

    如果子类希望改变虚方法的实现细节,就必须使用override关键字。

    class SalesPerson:Employee

    { .......

    //销售人员的奖金受销量的影响

         public override void GiveBonus(float amount)

         {

                int salesBonus=0;

                if(numberOfSales>=0&&numberOfSales<=100)

                      salesBonus=10;

                else

                 {  if(numberOfSales>=101&&numberOfSales<=200)

                        salesBonus=15;

                    else

                        salesBonus=20;

                 }

                 base.GiveBonus(amount*salesBonus);

          }

    }

    class Manager:Employee

    { .......

         public override void GiveBonus(float amout)

         {    base.GiveBonus(amount);

               Random r=new Random();

               numberOfOptions+=r.Next(500);

         }

    }


    密封虚成员

    class SalesPerson:Employee

    {  ........

       public override sealed void GiveBonus(float amount)

       {  .......  }

    }

    sealed class PTSalesPerson:SalesPerson

    { .......

         public PTSalesPerson(string fullName,int age,int empID,float currPay,string ssn,int numbOfSales)

              :base(fullName,age,empID,currPay,ssn,numbOfSales)

               {  }

         // 编译器错误!不能在PTSalesPerson类中重写这个方法,因为它是被密封的

         public override void GiveBonus(float amount)

         {   }

    }


    抽象类

    由于很多基类都是比较模糊的尸体,好的设计师会防止在代码中直接创建新的Employee对象。

    abstract partial class Employee

    {   ........  }


    构建多态接口

    成员投影

    基类/派生类的转换规则


    as关键字

    //我们不能强制转换frank为Hexagon,但编译没问题

    Hexagon hex=(Hexagon)frank;

    //使用“as”来测试兼容性

    Hexagon hex2=frank as Hexagon;

    if(hex2==null)

         Console.WriteLine("Sorry,frank is not a Hexagon...");


    is关键字

    除了is关键字,C#语言还提供了is关键字来测试两个项是否兼容。然而,和as关键字不同的是,如果类型不兼容,is关键字就返回false而不是null引用。


    超级父类:System.Object

    System.Object的核心成员

    Equals() 默认情况下,如果被比较的项指向内存中同一个项,则方法会返回true。因此,Equals()用于比较对象引用,而不是对象的状态。一般情况下,这个方法被重写为:如果被比较的对象有相同的内部状态值(也就是基于值的语义),则返回true。要知道,如果重写Equals(),则还需要重写GetHashCode(),因为这些方法在内部用于Hashtable类型从容器读取子对象。ValueType类为所有结构重写了该方法,它们进行的比较是基于值的。

    Finalize() 这个方法(在重写后)在对象销毁之前被调用来释放所分配的资源。

    GetHashCode() 这个方法返回int来标识指定的对象实例。

    ToString() 这个方法是用<namespace>,<type name>格式(叫做完全限定名)返回对象的字符串表示。这个方法可以被子类重写来返回名称/值对的标识字符串以表示对象的内部状态,而不是它的完全限定名。

    GetType() 这个方法返回Type对象,它完整描述当前指向的对象。简而言之,这是所有对象都可用的运行时类型标识方法。

    MemberwiseClone() 这个方法的作用是逐个成员地返回当前对象的副本,通常用于克隆对象。

    版权声明:本文为 NoMasp柯于旺 原创文章,如需转载请联系本人。

  • 相关阅读:
    跑Linux内存占用率的shell脚本
    Mysql数据导入导出功能(设置及使用)
    Python刷CSDN阅读数(仅供娱乐)
    SSH、SCP命令及使用说明
    2020.6.7 时间记录
    3年经验,中级Java开发招聘信息
    中级Java程序员要求
    提升自身内部核心竞争力要素
    三级联动页面
    大公司和小公司程序员
  • 原文地址:https://www.cnblogs.com/NoMasp/p/4786191.html
Copyright © 2011-2022 走看看