[Objectoriented] : 继承

前言 :

继承
是面向对象初学者,学完之后。觉得懂却又有点模糊的东西
笔者试着用展开程序代码的方式,来解释继承的运作。

继承 :

底下是一段继承的程序代码
这个程序代码很简单,就是ClassB继承ClassA而已

namespace ConsoleApplication1 
{ 
    public class ClassA
    {
        public void XXX()
        {
            // ClassA Code
        }

        private void YYY()
        {
            // ClassA Code
        }

        protected void ZZZ()
        {
            // ClassA Code
        }
    }

    public class ClassB : ClassA
    {
        public void AAA()
        {
            // ClassB Code
        }
    }	
}

我们在理解上,可以将这段程序代码展开成这样

namespace ConsoleApplication1 
{ 
    public class ClassA
    {
        public void XXX()
        {
            // ClassA Code
        }

        private void YYY()
        {
            // ClassA Code
        }

        protected void ZZZ()
        {
            // ClassA Code
        }
    }

    public class ClassB : ClassA
    {
        private ClassA base = new ClassA();

        public void XXX()
        {
            base.XXX();
        }

        protected void ZZZ()
        {
            base.ZZZ();
        }

        public void AAA()
        {
            // ClassB Code
        }
    }
}

当我们使用了继承的语法,ClassB继承ClassA的时候
我们可以看成编译程序的动作为:
1. 保留ClassB内的所有成员。
2. 在ClassB内建立一个名为base的ClassA对象。
3. 把ClassA内所有不是标示为private的所有成员,展开成为ClassB的成员。
4. 在ClassB展开的成员内,全部设订为呼叫ClassA的成员。

这样的思路看下来,
应该就可以理解继承,是如何的运作。

存取修饰词 :

这边再来说明继承会使用到的存取修饰词:public、protected、private

当ClassA内的成员:
宣告为public,   展开程序代码的时候:展开成为ClassB的 public成员。
宣告为protected,展开程序代码的时候:展开成为ClassB的 protected成员。
宣告为private,  展开程序代码的时候:不作任何的动作。

当我们针对类别成员使用不同的存取修饰词,对于延生的类别而言,会产生不同的影响。

覆写 :

最后再来说一个覆写好了
当我们写了这样一段程序代码

namespace ConsoleApplication1 
{ 
    public class ClassC
    {
        public virtual void XXX()
        {
            // ClassC Code
        }

        public virtual void YYY()
        {
            // ClassC Code
        }
    }

    public class ClassD : ClassC
    {
        public override void XXX()
        {
            // ClassD Code
        }
    }
}

我们在理解上,可以将这段程序代码展开成这样

namespace ConsoleApplication1 
{ 
    public class ClassC
    {
        public virtual void XXX()
        {
            // ClassC Code
        }

        public virtual void YYY()
        {
            // ClassC Code
        }
    }

    public class ClassD : ClassC
    {
        private ClassC base = new ClassC();

        public virtual void XXX()
        {
            // ClassD Code
        }
 
        public virtual void YYY()
        {
            base.YYY();
        }
    }
}

这段程序代码跟之前范例不同的地方在于多了virtual及override的宣告。
当我们宣告类别成员为virtual的时候,
就代表衍生的子类别,可以覆写这个成员。

当子类别使用override关键词覆写成员的时候
程序代码展开的规则,不会呼叫base的成员,
而是执行子类别撰写的程序代码。(如上面范例的 XXX())

当然啦~ 子类别也可以选择不覆写父类别的成员。
程序代码展开的规则就跟一般的成员一样,
会呼叫父类别的成员。(如上面范例的 YYY())

后记 :

本篇的文章,
描述了继承的运作,希望对大家有帮助^^

P.S.
本篇的内容大幅度的简化了计算器结构的内容,用以传达面向对象的概念。
实际计算机系统在运作的时候,比本篇说明的复杂很多 ^^"。

原文地址:https://www.cnblogs.com/clark159/p/2205020.html