补习:C# 面向对象三大特性:封装、继承、多态

C# 面向对象三大基本特性

封装、继承、多态

1、封装
隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别。

C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。

一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:

● public:所有对象都可以访问;
● private:对象本身在对象内部可以访问;
● protected:只有该类对象及其子类对象可以访问;但不可以继承给子类
● internal:同一个程序集的对象可以访问;
● protected internal:访问限于当前程序集或派生自包含类的类型。

读写性

只读 readonly : {get;}
只写 writeonly : {set;}
读写 read-write : {get;set;}

2、继承

继承有一个很重要的原则,叫里氏替换原则:子类是父类;
如:
麻雀:鸟(麻雀继承鸟类),可以说,麻雀是鸟,但不能说鸟是麻雀。

在代码里也一样。

//前提:Eagle:Bird
var lstBird = new List<Bird>();
Eagle b1 = new Eagle();
lstBird.Add(b1);//是没毛病的

因为Eagle是Bird,所以List< Bird> 可以添加Eagle。Eagle拥有所有Bird需要的成员,包括private成员。

实际上,子类能继承父类除了构造函数以外的所有成员,public\protected\private等,与继承没有关系,仅是访问的可见性。子类能继承父类成员访问性的所有特性。但对于private,又有比较特殊的地方:子类无法访问到父类的private成员,也就是说在子类新建一个同名的成员,编辑器是不会提示重名的。但是实际上父类的private成员是被继承了的,只不过子类无法看到而已。如父类有一个private成员Color,如果父类的函数有一个WriteLine这个成员的函数,如果子类不重写此函数,输出是父类的Color;如果子类重写了,就算函数内容完全一致,输出的也是子类的Color;

父类的属性、方法会继承给子类,子类中可以访问直接访问public\internal的成员,但是无法直接访问private的成员。对于protected修饰的成员,只有在自己的作用范围内访问到protected的成员。也就是说,只有在代码Class {——–}内部,可以直接访问到protected成员,而当你在实例化类 时,你就不可以访问该成员了。
同理也继承到了子类处。

class Bird
    {
        public Bird(string sName,int sSize)
        {
            Name = sName;
            Size = sSize;
        }

        protected string Name;

        public int Size;

        public virtual void Cry()
        {
            Console.WriteLine("i am Bird");
        }

        public void GetName()
        {
            Console.WriteLine(Name);
        }
    }

    class Eagle : Bird
    {
        public Eagle(string Name, int Size) : base(sName: Name, sSize: Size){}

        public override void Cry()
        {
            Console.WriteLine($"i am {Name} !  come ,chickens");
        }
   }    

在Eagle类的内部,重写了Cry方法,可以直接访问到继承的protected成员Name。
而在

class Program
    {
        static void Main(string[] args)
        {
             var b1 = new Eagle("Huge",75);
             var b1Name = b1.Name;
        }
    }

在上述代码中则会报错:
这里写图片描述
仅能在内部访问,实例化后的成员不可访问。

3、多态

简单来说,多态指同一个实体同时具有多种形式。

重写 是多态的一个重要形式。

父类有一个virtual的方法,则子类可以继承并重写这个方法。

这里写图片描述

我举个例子。

  class Program
    {
        static void Main(string[] args)
        {
            var birdList = new List<Bird>();

            var b1 = new Eagle("Huge",75);

            var b2 = new Sparrow("Tiny", 12);
            birdList.Add(b2);

            birdList.Add(b1);

            foreach (var b in birdList)
            {
                b.Cry();
            }
            Console.Read();
        }

    }


    class Bird
    {
        public Bird(string sName,int sSize)
        {
            Name = sName;
            Size = sSize;
        }

        protected string Name;

        public int Size;

        public virtual void Cry()
        {
            Console.WriteLine("i am Bird");
        }

        public void GetName()
        {
            Console.WriteLine(Name);
        }
    }

    class Eagle : Bird
    {
        public Eagle(string Name, int Size) : base(sName: Name, sSize: Size){}

        public override void Cry()
        {
            Console.WriteLine($"i am {Name} !  come ,chickens");         
        }

    }

    class Sparrow : Bird
    {
        public Sparrow(string Name, int Size) : base(sName: Name, sSize: Size) { }

        public override void Cry()
        {
            Console.WriteLine($"i am  {Name} ! ");
        }
    }

操作结果如下:
这里写图片描述

即:不同的基类的同名方法实现了不同的操作,这就是重写,多态的体现。

多态还有其他体现方式,下回再补充。

补充一下:重载
重载与重写不同,重载是同名方法不同参数而体现出不同的操作,构造函数就是一个例子。一个类可以有多个构造函数,参数类型、参数个数成为区别函数主体的条件。

猜你喜欢

转载自blog.csdn.net/loveyou388i/article/details/78799596