(5)继承

来源:互联网 发布:淘宝商城加入注意什么 编辑:程序博客网 时间:2024/06/06 10:57

*派生类赋值给基类成为隐式转换。同时,该实例被引用为基类型,而他现在提供的功能也是基类的。

*基类赋值给派生类需要强制类型转换。并且可能抛出异常。

*从一个派生类中访问一个受保护的基类的成员,必须确定在编译时受保护的成员是派生类(或者它的某个子类)的一个实例。即派生类和派生类的实例才可以访问基类的受保护成员。

*C# 是单一继承的。如果需要多重继承,可以使用聚合(aggregation)[不理解]。B继承A,并且将C在B中重新定义,B调用委托给C。

*密封类(sealed):不能派生出其他类。密封类的例子:string 。

*重写基类

virtual 修饰符:c#支持重写实例方法和属性,但是不支持重写字段和任何静态变量。为了进行重写,要求在基类和派生类中都显示的执行一个操作。在基类中,必须将允许重写的每个成员标记为virtual 。在派生类中,用override来标识重写的方法或属性。重写标志着基类中的方法或属性可以在派生类中被重写(替换)。C#默认的是非虚方法,与java相反。重载一个成员,会造成“运行时”调用派生的最远的(most derived)实现。

是有实例成员是virtual的。

*new修饰符

public class Baseclass    {        public void displayName()        {            Console.WriteLine("BaseClass");        }    }    public class DerivedClass:Baseclass    {        public virtual void displayName()        {            Console.WriteLine("DerivedClass");        }    }    public class SubDerivedClass : DerivedClass    {        public override void displayName()        {            Console.WriteLine("SubDerivedClass");        }    }    public class SupSubDerivedClass : SubDerivedClass    {        public new void displayName()        {            Console.WriteLine("SupSubDerivedClass");        }    }    class Program    {        static void Main(string[] args)        {            SupSubDerivedClass superSubDerivedclass = new SupSubDerivedClass();            SubDerivedClass subDerivedclass = superSubDerivedclass;            DerivedClass derivedclass = superSubDerivedclass;            Baseclass baseclass = superSubDerivedclass;            superSubDerivedclass.displayName();            subDerivedclass.displayName();            derivedclass.displayName();            baseclass.displayName();            Console.ReadKey();        }    }


结果显示为:

SupSubDerivedClass
SubDerivedClass
SubDerivedClass
BaseClass

 **sealed修饰符 :禁止被继承。

class  A

{

public  virtual void Method()
{//……

}

}

class B :A

{

public override sealed void Mehod()

{//……

}

}

class C:B

{

//Error:cannot override sealed members

//public override void Method()

//{

//}

}

**base成员:重新声明一个成员时,开发者经常需要调用一个基类的一个成员。

 public class Adress    {        public string StreetAdress;        public string City;        public string State;        public string Zip;        public override string ToString()        {            return string.Format("{0}"+Environment.NewLine +"{1},{2}{3}",StreetAdress,City,State,Zip);         }    }    public class InternationalAdress : Adress    {        public string Country;        public override string ToString()        {            return base.ToString()+Environment.NewLine+Country;        }    }


说明:即使在Adress.ToString()实现中,也需要使用override修饰符,因为ToString()也是Object的一个成员。用override修饰符的任何成员都会自动成为virtual成员,是其他子类能进一步“特化”它的实现。

**构造器:实例化一个派生类,运行时首先调用基类的构造器,以避免基类构造器被绕过。假如基类没有可供访问的(非private的)默认构造器,就不清楚如何构造基类,而且编译器会报错。所以一般程序员在派生类构造器的头部显式的指定要运行哪一个基类构造器。

public class PadItem

{

   public PadItem(string name)

{

}

}

public class Contact :PadItem

{

public Contact(string name):base(name)

{

}

}

**抽象类(abstract):无法实例化一个抽象类,只能实例化从他派生的类。它包含抽象成员。派生类必须实现抽象成员。

                                         抽象成员是不具有实现的一个方法或属性,其作用是强制所有派生类提供实现。在派生类中实现抽象方法时,也用override来修饰。

                                         抽象类是实现多态的一种手段。基类指定方法的签名,而派生类提供具体的方法,

   public abstract class PadItem

{

public abstract string GetSummary();//只有声明,没有实现。

}

*所有类都是从System.Object派生。

Equals(object o):判断对象在值上相等。

ReferenceEquals(object a,object b):判断两个参数是否引用同一个对象。

GetHashCode()

GetType()

ToString()

MemberwiseClone():创建当前对象的一个浅表副本。引用会被复制,但是被引用类型中的数据不会被复制。

**使用is运算符验证基础类型

            int a = 234;            if (a is string)            {                Console.Write("yes");//a=234,执行不到这            }

**使用as运算符进行转换:尝试将对象转换为一个特定的数据类型,但是,假如源类型不是固有的(继承内部链的)目标as运算符会将null值赋给目标。