面向对象程序设计语言的三大原则


一个面向对象的语言在处理对象时,必须遵循的三个原则是:封装、继承和多态。

(1)封装

   所谓“封装”,就是用一个框架把数据和代码组合在一起,形成一个对象。遵循面向对象数据抽象的要求,一般数据都被封装起来,也就是外部不能直接访问对象的数据,外部能见到的只有提供给外面访问的公共操作(也称接口,对象之间联系的渠道)。在C#中,类是对象封装的工具,对象则是封装的基本单元。

   封装的对象之间进行通信的一种机制叫做消息传递。消息是向对象发出的服务请求,是面向对象系统中对象之间交互的途径。消息包含要求接收对象去执行某些活动的信息以及完成要求所需要的其他信息(参数)。发送消息的对象不需要知道接收消息的对象如何对请求予以响应。接收者接收了消息,它就承担了执行指定动作的责任,作为消息的答复,接收者将执行某个方法,来满足所接收的请求。

   封装其实就是信息隐藏,隐藏一个对象的本质,让用户不再注意那些细节.提供一些向外的接口供别人使用。   就像电视的内部已经被封起来,你不需要知道它的内部是由哪些零件组成、如何工作。你只知道用遥控器来控制就好。

(2)继承

    世界是复杂的,在大千世界中事物有很多的相似性,这种相似性是人们理解纷繁事物的一个基础。因数事物之间往往具有某种“继承”关系。比如,儿子与父亲往往有许多相似之处,因数儿子从父亲那里遗传了许多特性;汽车与卡车、轿车、客车之间存在着一般化与具体化的关系,它们都可以用继承来实现。

    继承是面向对象编程技术的一块基石,通过它可以创建分等级层次的类。例如,创建一个汽车通用类,它定义了汽车的一般属性(如:车轮、方向盘、发动机、车门等)和操作方法(如:前进、倒退、刹车、转变等到)。从这个已有的类可以通过继承的方法派生出新的子类,卡车、轿车、客车等,它们都是汽车类的更具体的类,每个具体的类还可以增加自己一些特有的东西。继承是父类和子类之间共享数据和方法的机制,通常把父类称为基类,子类称为派生类。一个基类可以有任意数目的派生类,从基类派生出的类还可以被派生,一群通过继承相联系的类就构成了树型层次结构。

   如果一个类继承两个或两个以上直接基类,这样的继承结构被称为多重继承或多继承。

   尽管多继承从形式上看比较直观,但在现实上多继承可能引起继承操作或属性的冲突。当今的很多语言已不再支持多继承,C#语言也对多继承的使用进行了限制,它通过接口来实现。接口可以从多个基接口继承。接口可以包含方法、属性、事件和索引器。一个典型的接口就是一个方法声明的列表,接口本身不提供它所定义的成员的实现。所以接口不能被实例化,一个实现接口的类再以适当的方法定义接口中声明的方法。

   有仅如此,C#的接口概念十分适用于组件编程。在组件和组件之间、组件和客户之间都通过接口进行交互。继承可以理解为基类代码的复用. 当一个对象可以描述为另外一个对象的时候用继承(is-a)的关系. 当一个可以可以有另外一个对象的时候用组合(has-a)的关系. 当一个对象可以包含某个行为的时候用接口(can-do)的关系.

(3)多态性

    多态性就其字面上的意思是:多种形式或多种形态。在面向对象编程中,多态是指同一个消息或操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。例如,问甲同学:“现在几点钟”,甲看一看表回答说:“3点15分”,又问乙同学:“现在几点钟”,乙想一想回答说:“大概3点多钟”,又问丙同学:“现在几点钟”,两干脆回答说:“不知道”。这就是同一个消息发给不同的对象,不同的对象可以做出不同的反应。

    同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果, 这就是多态性。多态性通过派生类重载基类中的虚函数型方法来实现。 C#支持两种类型的多态性 编译时的多态性为我们提供了运行速度快的特点,而运行时的多态性则带来了高度灵活和抽象的特点。 编译时的多态性 编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。 运行时的多态性 运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中,运行时的多态性通过虚成员实现。

 

    ////需要熟练掌握  abstract,virtual,override,new,sealed,base的用法.
    #region abstractClass 抽象类
    /// <summary>
    /// 抽象类
    /// 可以将类声明为抽象类。方法是在类定义中将关键字 abstract 置于关键字 class的前面
    /// </summary>
    public abstract class abstractClass
    {
        private string mclassName;

        /// <summary>
        /// 抽象类构造方法
        /// </summary>
        /// <param name="mclassName"></param>
        public abstractClass(string mclassName)
        {
            this.mclassName = mclassName;
        }

        #region ClassName 抽象属性
        /// <summary>
        /// 
        /// </summary>
        public virtual string ClassName
        {
            get
            {
                return mclassName;
            }
        }
        #endregion

        #region DoWork 抽象方法
        /// <summary>
        /// 抽象方法
        /// 1.抽象类也可以定义抽象方法。方法是将关键字 abstract 添加到方法的返回类型的前面。
        /// 2.抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块。
        /// 3.抽象类的派生类必须实现所有抽象方法。当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法。
        /// </summary>
        /// <param name="i"></param>
        public abstract void DoWork(int i);
        #endregion

        #region DoWork 虚方法
        /// <summary>
        /// virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
        /// 1.virtual 修饰符不能与 static、abstract、private 或 override 修饰符一起使用。
        /// 2.在静态属性上使用 virtual 修饰符是错误的。
        /// 3.除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。
        /// 4.通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性。
        /// </summary>
        /// <param name="message"></param>
        public virtual void DoWork(string message)
        {

        }
        #endregion

    }
    #endregion

    #region DemoClass  继承抽象类 派生类
    /// <summary>
    /// 派生类可以包含与基类方法同名的方法
    ///1.基类方法必须定义为 virtual。
    ///2.如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new 关键字一样执行操作。
    ///3.如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法。
    ///4.如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不是调用基类方法。
    ///5.可以从派生类中使用 base 关键字调用基类方法。
    ///6.override、virtual 和 new 关键字还可以用于属性、索引器和事件中
    /// </summary>
    public class DemoClass : abstractClass
    {
        private string motherName;

        #region  DemoClass base的用法
        /// <summary>
        /// 子类继承父类(抽象类)的构造方法
        /// </summary>
        /// <param name="mclassName"></param>
        /// <param name="motherName"></param>
        public DemoClass(string mclassName, string motherName)
            : base(mclassName)
        {
            this.motherName = motherName;
        }
        #endregion

        #region ClassName  实现抽象属性
        /// <summary>
        /// 
        /// </summary>
        public string OtherName
        {
            get
            {
                return motherName;
            }
        }
        #endregion

        #region DoWork
        /// <summary>
        /// 
        /// </summary>
        /// <param name="i"></param>
        public override void DoWork(int i)
        {

        }
        #endregion
    }
    #endregion

    #region sealedClass 密封类
    /// <summary>
    /// 1.在class前使用 sealed 修饰符时会阻止其他类从该类继承.
    /// 2.在重写基类中的虚方法或虚属性的方法或属性上使用.则他的继承类无法重写相应的方法或属性.
    /// </summary>
    public sealed class sealedClass : abstractClass
    {
        public sealedClass(string mclassName)
            : base(mclassName)
        {
        }

        #region DoWork 密封方法
        /// <summary>
        /// 
        /// </summary>
        /// <param name="i"></param>
        public sealed override void DoWork(int i)
        {

        }
        #endregion
    }
    #endregion

 

 

 

 

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM