高级编程与设计模式

面向对象的三大特征

封装

隐藏内部实现,稳定外部接口->系统安全性进行提升

继承

子类继承父类成员,实现代码的复用->开发和维护效率提高

继承的使用

特点

  1. 从生活中理解继承

    父母->儿女->孙辈

    交通工具->飞机(直升飞机、战斗机、波音)、汽车(卡车、公交车、小轿车)、轮船

  2. 继承的特点

    1. 继承的顺序不可逆:继承从上往下依次继承,而不能逆序继承

    2. 继承的延续性:在继承的顺序中,下一级完整的具备上一级的属性和特征

为什么要使用继承

继承使用的必要性

  1. 提高代码的复用,减少代码的冗余

  2. 一处更新,处处更新

玩具厂商要实现一些玩具的程序

分析:所有的玩具都会有一些特征

  1. 属性:姓名、自身的颜色、类别

  2. 行为:跳舞、唱歌。。。

程序实现:

当人给玩具发送一个指令:这个玩具就会做出与他们对应的行为

如何实现继承

继承的步骤

  1. 抽象公共部分,放到一个特定的类中(父类、基类)

  2. 其他类(子类、派生类)只需要继承父类,即可拥有父类的特征(属性、方法)

  3. 根据子类的需求添加属于自己的特征和方法

具体实现

在子类后面使用继承符号":"继承父类

继承中的关键字

继承关系

Animal(父类)<<<<-----[Cat,Frog] (派生类)

概念

  1. 子类继承父类,父类派生子类

  2. 子类又叫派生类,父类又叫基类(超类)

  3. 子类继承父类成员,也可以有自己的独立程序

  4. 继承具有传递性:A->B;B->C C就具有A的特性

  5. 继承的单根性:一个类只能有一个父类,一个父类可以有任意多个子类

继承的必要条件

继承必须要符合关系:is-a的关系 【Cat is an Animal】

关键字

this关键字:可以访问自身也可以访问父类

base关键字:1.调用父类的构造函数 2.调用父类的属性和方法

和继承有关的访问修饰符

问题:如果父类中的某个成员只允许其子类访问应该如何实现

父类成员:

  1. 使用public修饰:所有的类都可以访问

  2. 使用private修饰:只有自己可以访问

  3. 使用protected修饰:仅允许子类访问,而不允许其他非子类访问

修饰符类内部子类其他类
public可以可以可以
private可以不可以不可以
protected可以可以不可以

 

多态

不同子类对同一消息,做出不同反应->系统扩展性增强

概念:

  1. 不同对象,接收相同消息,产生不同行为,称为多态

  2. 多态是由“聪明的”虚拟机自行决定的

实现:

使用继承实现多态

  1. 父类中必须有抽象方法或虚拟方法

  2. 子类必须重写父类中的抽象方法或选择重写父类中的虚拟方法

  3. 子类对象必须转成父类类型去使用

方法

  1. 方法的重载

  2. 构造重载

  3. 方法的重写:重写不能改变方法签名

里式替换原则

  1. 子类的对象能够替换其父类、

  2. 父类对象不能够替换子类

  3. 父类的方法都要在子类中实现或重写

is与as操作符

  1. is主要用作检查对象是否是指定类型兼容,如果转换失败程序中断

  2. as主要用作在兼容的引用类型之间执行转换,转换失败返回null

抽象

父类和子类相互转换

            Cat cat = new Cat()
            {
                Name = "小黄",
                Type = AnimalType.Mammal
            };
​
            Frog frog = new Frog()
            {
                Name = "小青",
                Type = AnimalType.Amphibious
            };
​
            List<Animal> list = new List<Animal>();
            //子类隐式转换为父类
            list.Add(cat);
            list.Add(frog);
            foreach (Animal item in list)
            {
                //将父类强转成对应的子类
                if (item is Cat)
                {
                    ((Cat)item).Work();
                }
                if (item is Frog)
                {
                    ((Frog)item).Work();
                }
            }
  1. 父类类型可以添加子类对象,子类自动转换成父类类型

  2. 将父类类型转成子类对象时,父类类型的对象必须强制转换成对应的子类对象,才能调用子类的独立成员

抽象类的使用

  1. 使用关键字abstract修饰的类称为抽象类

  2. 抽象类只是用来列举一个类所具有的行为,不能单独通过创建对象来使用

  3. 抽象类中可以有抽象成员,也可以没有任何抽象成员

  4. 抽象类不能是静态的或密封的

抽象方法的使用

  1. 抽象方法必须放在抽象类中

  2. 抽象方法使用关键字abstract修饰

  3. 抽象方法只是一个方法的声明,没有方法体

  4. 抽象方法仅表示一个应该具备的行为,具体的实现由子类完成

  5. 抽象方法在子类中必须被实现,使用关键字override重写

  6. 子类必须重写父类的所有抽象方法,除非子类本身也是抽象类

虚拟

问题:如果需要在父类中提供一个方法,该方法有自己的方法体,子类根据自身的需要再去决定是否重写该方法,这个方法重写不重写取决于子类自身的需求。

虚拟方法抽象方法
使用virtual使用abstract
必须提供方法体和正常方法一致不允许有方法体,只能有方法签名
子类可以选择重写也可不重写子类必须重写抽象方法
除了密封类中都可以写只能在抽象类中

 

访问修饰符

public

private

protected

internal

protected internal/protected internal

密封类

使用关键字:sealed

  1. 当一个类使用sealed修饰后,该类不能被继承

  2. sealed对于保护知识产权起到一定作用,一定程度上限制别人二次开发

接口

什么是接口

应用接口之后,程序的可扩展性、可维护性会大大增强

接口的定义和实现

接口的定义类似于USB,主要作用是一共一个电源头

接口的实现类似于U盘或者USB线鼠标或者USB线键盘等等,主要作用是接口功能的体现

接口定义规范

  1. 使用关键字interface定义,接口类名通常使用“I”开头

  2. 接口中的属性、方法等,只是做一个声明,而没有任何实现

  3. 接口中的属性、方法等,默认都是public,不需要“画蛇添足”

接口的实践

问题:打印机对象:打印、复印、传真。市场流行的打印机:HP/SONY......

  1. 实现打印机接口

        /// <summary>
        /// 多功能打印机接口
        /// </summary>
        public interface IMultiPrinter
        {
            /// <summary>
            /// 打印功能
            /// </summary>
            /// <param name="contents"></param>
            void Print(string contents);
            /// <summary>
            /// 复印功能
            /// </summary>
            /// <param name="contents"></param>
            void Copy(string contents);
            /// <summary>
            /// 传真功能
            /// </summary>
            /// <param name="contents"></param>
            void Fax(string contents);
        }
  2. 在具体对象中实现接口所提出的功能

        class HPMultiPrinter : IMultiPrinter
        {
            public void Copy(string contents)
            {
                Console.WriteLine("惠普复印:"+contents);
            }
    ​
            public void Fax(string contents)
            {
                Console.WriteLine("惠普传真:" + contents);
            }
    ​
            public void Print(string contents)
            {
                Console.WriteLine("惠普打印:" + contents);
            }
        }

接口的特点

  1. 接口具有强制性,实现接口的类必须实现接口的所有成员

  2. 一个类既可以实现多个接口,也可以同时继承其他的类,前提是一般将继承的父类写在接口之前

  3. 类继承了多少个接口(间接继承、直接继承),对所有的接口都要进行实现

    间接继承:A接口->B接口->C类

    直接继承:A接口->C类,B接口->C类

接口的实践应用

  1. 接口提高团队成员并行开发项目的效率

    1. 接口的使用者只需要考虑接口的应用功能,而不用考虑接口的实现细节

    2. 接口的实现者只关心如何实现接口内部的细节,而不用考虑谁使用

  2. 接口能够提高系统的可维护性

    当用户的需求改变时,只需要修改接口的实现,系统即可完成更新

接口的应用总结

  1. 接口的应用场合

    1. 如果某一个功能点需求变化比较多,应使用接口保证系统的可维护性

    2. 如果想实现团队成员的并行开发,可以使用接口来规范对象的使用

  2. 接口编写规范

    1. 接口成员只能是一个声明

    2. 实现接口的类必须全部实现接口中规定的属性、方法

  3. 特别说明

    接口的使用不是必须的,要根据用户的需求来决定

接口实现多态

继承多态实现的条件

  1. 父类中必须有抽象方法或者虚拟方法

  2. 子类必须重写父类中的抽象方法或者虚方法

  3. 子类对象必须转换成父类去使用

接口多态实现的条件

  1. 一个接口必须被两个或两个以上类实现

  2. 接口实现类必须转成接口类型去使用

接口和抽象

 抽象类接口
不同点用abstract定义用interface定义
 只能被继承一个可以实现多个接口被继承
 非抽象派生类必须实现抽象方法实现接口的类必须实现所有的成员
 需要使用override实现抽象方法直接实现
   
相似点都不能直接实例化 
 都包含未实现的方法 
 子类或“接口实现类”必须实现未实现的方法 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值