C# 继承的实现方式

虚方法:

    如果要在派生类中继承方法或属性,那么就必须在基类中将该属性声明为virtual。

    方法或属性在默认情况下是不虚拟的,所以如果不在基类中显示声明,在派生类中用override重写该方法时就会报错。

    当然,如果在派生类中用new来隐藏基类方法也没有问题。

    我们看下面一个例子:

 public class A
    {
        public void MethodF() 
        { 
            Console.WriteLine("A.F"); 
        }
        public virtual void MethodG() 
        { 
            Console.WriteLine("A.G"); 
        }
    }
    public class B : A
    {
        new public void MethodF() 
        { 
            Console.WriteLine("B.F"); 
        }
        public override void MethodG() 
        { 
            Console.WriteLine("B.G"); 
        }
    }
    class Test
    {
        static void Main()
        {
            B b;
            b = new B();
            A a = b;
            a.MethodF();
            b.MethodF();
            a.MethodG();
            b.MethodG();
        }

它的结果是: 

A.F B.F B.G B.G

也许你会很奇怪为什么a.methodG()的结果为什么是B.G。

那是因为A的methodG方法是虚方法,如果有派生类继承了这个方法,那么它就会首先去找这个派生类的继承方法并实现它。

 

隐藏方法

    通常是在不重写基类方法,但又需要再派生类中创建一个相同方法时使用。

    只要在派生类方法的前面加一个new就能实现对基类方法的隐藏。

如:

class BaseClass
 {
        public int Add(int a, int b) {
            return a + b + 1;
        }
}

class Test1 : BaseClass
{
        new public int Add(int a,int b) 
        {
            return a + b;
        }
}

如果new一个基类,则调用Add方法时调的是基类的Add方法。

反之则调用Add方法时调的是派生类的Add方法。

 

密封类和密封方法:

    这个简单,只要在类或方法前声明一个sealed属性,就可以让该类或方法无法被继承。

    在C#中,string类就是一个sealed类。但是让我们认真分析一下string类,可以发现它还是有3个方法是可以继承的。

    GetHashCode(),ToString(),Equals()

    然后对比这三个方法与其他方法的不同,可以发现只有这三个方法是被声明了override属性。

    也就是说,在sealed类中,只要将方法声明为override,该方法就可以被继承。

 

派生类的构造函数

    我看的是C#高级编程第七版中的“派生类的构造函数”一节,老实说毕竟是翻译的书籍,理解起来有点深涩,于是上网找了一个略解,意思就清楚了。

    http://blog.csdn.net/liuzhenpolestar/article/details/5828187

   大概的意思是如有基类没有默认的无参构造函数,只有有参构造函数,派生类就必须要往基类传参。具体可以看上面链接里的内容。

   然后书中的例子也有些不当。

例子是:

class BaseClass
{
        private string name;

        public BaseClass(string name){
            this.name = name;
        }
}

class Test1 : BaseClass
{
        public Test1(string name):base(name)
        {
           
        }
}

 

像name这样的通用属性,一般不会用private属性进行修饰,而是用protected进行修饰。本来意思就是晦涩了,搞个不伦不类的例子,误导人啊这是!

改造后可以写成这样:

    class BaseClass
    {
        protected string name;

        public BaseClass(){}
    }

    class Test1 : BaseClass
    {
        public Test1(string name)
        {
            this.name = name;
        }
    }
posted @ 2012-11-22 18:03  のんきネコ  阅读(844)  评论(0编辑  收藏  举报