zoukankan      html  css  js  c++  java
  • 【学习笔记】面向对象三大特性封装、继承和多态

    一、封装

      1、隔离,外部不用关心怎么实现,只要接口不变,内部可以随意扩展。

      2、数据安全 private protected 数据结构,只能通过公开方法来访问,而不是随便改。

      3、降低耦合  提高重用性  尽量隐藏更多的东西。

    二、继承

      1、子类拥有父类的一切属性和行为,代码重用。

      2、单继承,也就是只有一个父类。

    三、多态

      1、一个类可以用做多个类型,就是多态,当然还有方法。

      2、编译时多态、运行时多态、接口多态、继承多态。

    接下来我们来看个Demo,首先我们准备一些测试类

    using System;
    
    namespace MyOO
    {
        /// <summary>
        /// 面向对象测试类
        /// </summary>
        public class OOTest : IFlyable, ISwimable
        {
            /// <summary>
            /// 实现IFlyable接口
            /// </summary>
            public void Fly()
            {
                Console.WriteLine("OOTest Fly");
            }
    
            /// <summary>
            /// 显示实现ISwimable接口,用于解决方法的重名问题
            /// </summary>
            void ISwimable.Swin()
            {
                Console.WriteLine("OOTest Swin");
            }
    
            /// <summary>
            /// OOTest自己的Swin方法
            /// </summary>
            public void Swin()
            {
                Console.WriteLine("我是OOTest自己的Swin方法");
            }
        }
    
        /// <summary>
        /// 飞接口
        /// </summary>
        public interface IFlyable
        {
            /// <summary>
            ////// </summary>
            void Fly();
        }
    
        /// <summary>
        /// 游泳接口
        /// </summary>
        public interface ISwimable
        {
            /// <summary>
            /// 游泳
            /// </summary>
            void Swin();
        }
    
        /// <summary>
        /// 父类(抽象类)
        /// </summary>
        public abstract class ParentClass
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            public ParentClass(int id)
            {
    
            }
    
            /// <summary>
            /// 普通方法 
            /// </summary>
            public void CommonMethod()
            {
                Console.WriteLine("ParentClass CommonMethod");
            }
    
            /// <summary>
            /// virtual  虚方法  必须包含实现 但是可以被重载
            /// </summary>
            public virtual void VirtualMethod()
            {
                Console.WriteLine("ParentClass VirtualMethod");
            }
    
            /// <summary>
            /// 虚方法重载
            /// </summary>
            /// <param name="name"></param>
            public virtual void VirtualMethod(string name)
            {
                Console.WriteLine("ParentClass VirtualMethod");
            }
    
            /// <summary>
            /// 抽象方法(必须放在抽象类中)
            /// </summary>
            public abstract void AbstractMethod();
        }
    
        /// <summary>
        /// 子类
        /// </summary>
        public class ChildClass : ParentClass
        {
            /// <summary>
            /// 实例化子类的时候,是先完成父类的实例化的
            /// </summary>
            public ChildClass()
                : base(1)//调用父类的构造函数
            {
    
            }
    
            /// <summary>
            /// new 隐藏
            /// </summary>
            public new void CommonMethod()
            {
                Console.WriteLine("ChildClass CommonMethod");
            }
    
            /// <summary>
            /// 普通方法重载一
            /// </summary>
            /// <param name="name"></param>
            public void CommonMethod(string name)
            {
                Console.WriteLine("ChildClass CommonMethod OverLoad1");
            }
    
            /// <summary>
            /// 普通方法重载二
            /// </summary>
            public void CommonMethod(string name, int id)
            {
                Console.WriteLine("ChildClass CommonMethod OverLoad2");
            }
    
            /// <summary>
            /// virtual 可以被覆写
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public override void VirtualMethod()
            {
                Console.WriteLine("ChildClass VirtualMethod");
                base.VirtualMethod();//base表示调用直接父类的这个方法
            }
    
            /// <summary>
            /// 抽象方法必须覆写(标记为sealed密封方法则不允许子类再去重写它)
            /// </summary>
            public sealed override void AbstractMethod()
            {
                Console.WriteLine("ChildClass AbstractMethod");
            }
        }
    
        /// <summary>
        /// 派生类
        /// </summary>
        public class GrandClass : ChildClass
        {
            //这是错误的,密封的,无法进行重写
            //public override void AbstractMethod()
            //{
            //    base.AbstractMethod();
            //}
    
            /// <summary>
            /// 重写虚方法
            /// </summary>
            public override void VirtualMethod()
            {
                base.VirtualMethod();
            }
        }
    }

    然后来看下具体使用

    using System;
    
    namespace MyOO
    {
        /// <summary>
        /// 小结:
        /// 使用父类声明接收子类对象
        /// 实现多态的几种方式:方法的隐藏、方法的重载、虚方法、抽象方法、接口
        /// 1、方法的隐藏
        ///     使用new关键字,这是个普通方法,普通方法调用是由编译时决定,调用的是父类的方法还是子类的方法取决于它的声明类型
        ///    
        /// 2、方法的重载
        ///     这是编译时多态,方法的调用是由编译时决定的
        ///     
        /// 3、虚方法
        ///     用virtual关键字,子类可以用override去重写它,这是运行时多态,如果子类有去实现父类的虚方法则调用子类的方法,否则调用父类的方法
        /// 
        /// 4、抽象方法
        ///     用abstract关键字,子类需要用override关键字去覆写它,这是运行时多态,调用子类的方法
        ///     含有抽象方法的类一定是抽象类,抽象类不能被实例化,抽象类中可以有抽象成员也可以有非抽象成员
        ///  
        /// 4、接口
        ///     用interface关键字,子类去实现接口成员不需要用override关键字,这是运行时多态,调用子类的方法
        ///     接口不能被实例化,接口成员不允许添加访问修饰符,默认是public
        ///     接口成员必须是函数成员(本质都是方法),并且都是抽象成员不能有任何的实现,不能有常量和字段
        ///     接口成员包括方法、属性、索引器、事件,不能有字段和构造函数
        ///     接口可以继承多个接口
        ///     显示实现接口的目的是为了解决方法的重名问题
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                //使用父类声明接收子类对象
                ParentClass parent = new ChildClass();
    
                //方法的隐藏
                Console.WriteLine("下面是parent.CommonMethod()");
                parent.CommonMethod();//子类new隐藏  父类方法   普通方法由编译时决定--提高效率
                Console.WriteLine(); //换行
    
                //虚方法
                Console.WriteLine("下面是parent.VirtualMethod()");
                parent.VirtualMethod();//子类覆写的虚方法  子类方法  虚方法由运行时决定的--多态灵活
                Console.WriteLine(); //换行
    
                //抽象方法
                Console.WriteLine("下面是parent.AbstractMethod()");
                parent.AbstractMethod();//子类实现的抽象方法  子类方法  抽象方法由运行时决定的--多态灵活
                Console.WriteLine(); //换行
    
                //接口
                Console.WriteLine("下面是fly.Fly()");
                IFlyable fly = new OOTest();
                fly.Fly();//子类实现的抽象方法  子类方法  抽象方法由运行时决定的--多态灵活
                Console.WriteLine(); //换行
    
                Console.WriteLine("下面是swim.Swin()");
                ISwimable swim = new OOTest();
                swim.Swin();//子类实现的抽象方法  子类方法  抽象方法由运行时决定的--多态灵活
                Console.WriteLine(); //换行
    
                Console.WriteLine("下面是test.Swin()");
                OOTest test = new OOTest();
                test.Swin();//OOTest自己的Swin方法
    
                Console.ReadKey();
            }
        }
    }

    最后我们来总结下多态的情况

    1、编译时多态:方法的重载,这个就不必多说了。

    2、运行时多态:虚方法、抽象类、接口

      1)什么时候用虚方法来实现多态?

        可以抽象出一个父类,并且父类中可以写出这几个子类共有的方法,且知道具体实现方式,且还需要创建父类对象。

      2)什么时候用抽象类来实现多态?

        可以抽象出一个父类,并且父类中可以写出这几个子类共有的方法,但又不知道如何具体实现这些方法。

      3)什么时候用接口来实现多态?

        在几个类中根本找不出父类,但它们具有共同的行为、共同的能力。

    Demo源码:

    链接:https://pan.baidu.com/s/1-PWuGw5Yw3D_bSWuCDk26w 
    提取码:z9gh
  • 相关阅读:
    zw版【转发·台湾nvp系列Delphi例程】HALCON CropPart
    zw版【转发·台湾nvp系列Delphi例程】HALCON ObjToInteger1-4
    zw版【转发·台湾nvp系列Delphi例程】HALCON TestObjDef
    zw版【转发·台湾nvp系列Delphi例程】HALCON DispCross
    ios-toolchain-based-on-clang-for-linux
    使用gdb调试theos tweak插件
    设置RabbitMQ远程ip登录
    ARC下带CF前缀的类型与OC类型转换
    laravel部署常用命令
    国产手机插入mac os 系统中无法被识别的解决方法
  • 原文地址:https://www.cnblogs.com/xyh9039/p/12593539.html
Copyright © 2011-2022 走看看