博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#面向对象编程及三大特性(二)
阅读量:6432 次
发布时间:2019-06-23

本文共 12950 字,大约阅读时间需要 43 分钟。

1、继承关系实现多态:一种调用,多种实现。    1)多态:隐藏基类 —new 则隐藏,隐藏看类型(来决定调用父类还是子类的方法):	  条件:父类子类写同名方法,子类方法名前加new(可以不加new)      结果:对象的类型是子类则调用子类方法;是父类则调用父类方法	      2)多态:重写 —over重写,重写只管新(调用新重写的方法):     条件1: 继承、里氏转换原则,且父类和子类有同名的方法		     在父类方法前加上virtual,在子类方法前加上override     结果:  实现用父类对像调用子类方法    3)隐藏基类应用:重写的子类调用自定义方法,不重写的继承父类方法,实现多态	  父类提供ToString方法,子类继承下来,可以直接调用ToString方法。      不重写:如果子类,没有提供ToString方法,那么直接使用object提供的。      重写:如果用户提供了ToString方法,那么调用时,就可以调用自定义的方法。           (开放封闭原则:对扩展开放,对修改封闭。)    4)重写方法实例:父类根据指向的子类不同,调用不同子类的方法,实现多态。   
View Code
class Program    {        static void Main(string[] args)        {            Father f = null;            Console.WriteLine("你要使用什么元件?(1、手机;2、灯)");            switch (Console.ReadLine())            {                case "1": f = new Phone("手机"); break;                case "2": f = new Light("Usb灯"); break;            }            f.Usb();        }    }    class Father    {        string name;         ---此处省略数行---        public virtual void Usb()        {            Console.WriteLine("父类方法!");        }    }    class Phone : Father    {        public Phone(string name) : base(name)        { }        public override void Usb()        {            Console.WriteLine("正在充电!");        }    }    class Light : Father    {        public Light(string name) : base(name)        { }        public override void Usb()        {            Console.WriteLine("亮灯!");        }    }

 

2、抽象类(难点)带有abstract的类  抽象类是对一类事物或对象的抽象,统一了一类对象。    ->抽象类当中的成员		->抽象成员:方法、属性(、索引、事件声明)		->非抽象成员,如Shape类中name    ->抽象类的使用		->抽像类就是为了实现多态的,在使用多态的地方几乎都可以使用抽象		->抽象类是不能被实例化的,抽象类有构造方法(给非抽象成员赋初值)   ->抽象成员的使用	(1)抽象方法的使用 			父类:[]abstract 返回类型 方法名() {}子类:[]override 返回类型 方法名() {}	(2)抽象属性的使用  快捷键Shift+Alt+F10	(3)抽象属性		-> 抽象与自动属性,本质不同			-> 自动属性,后台会有一个字段生成,体统会自动的添加对应的方法体			-> 抽象属性,因为没有方法体,所以get,set中什么都没有		-> 抽象与自动属性,结果不同			-> 自动属性,get,set必须共存			-> 抽象属性是可以有:只读、只写、可读可写之分的3、抽象方法实现多态(简单的说与继承关系父类使用多态相似)	不知道怎么实现;不需要实现,[public] abstract 返回类型 方法名( );	   抽象方法必须在抽象类中,方法和类前面都有abstract   抽象方法是为了实现多态,子类必须重写父类中的抽象方法	public override 父类提供的方法名(){}   特例:如果子类也是抽象的,可以不重写父类分抽象方法   实例:形状类(抽象父类),圆形、长方形、正方形三个子类,实现父类调用子类方法求周长和面积

  

View Code
namespace AbstractClass    {        class Program        {            static void Main(string[] args)            {                while (true)                {                    Shape[] s = {                                     new Circle("小圆",10),                                    new Rectangle("小长",27.5,30),                                    new Square("小方",100)                                };                    for (int i = 0; i < s.Length; i++)                    {                        s[i].Introduction();                        Console.WriteLine("我的面积是:{0}",s[i].Area());                        Console.WriteLine("我的周长是:{0}",s[i].Perimeter());                     }                    Console.ReadKey();                }            }        }    }    abstract class Shape    {        //字段 属性        string name;        public string Name        {            get { return name; }            set { name = value; }        }        double pi = 3.14;        public double Pi        {            get { return pi; }            set { pi = value; }        }        //构造方法        public Shape(string name)        {            this.name = name;        }        //抽象父类方法        public abstract void Introduction();        public abstract double Area();        public abstract double Perimeter();    }    class Circle : Shape    {        //字段 属性         double r;        public double R        {            get { return r; }            set { r = value; }        }                //构造方法        public Circle(string myname,double r1):base(myname)        {            r = r1;        }        //圆形子类方法        public override void Introduction()        {            Console.WriteLine("我是一个圆:我叫{0}",Name);        }        public override double Area()        {            double area = 0;            area = Pi * r * r;            return area;        }        public override double Perimeter()        {            double perimeter;            perimeter = 2 * Pi * r;            return perimeter;        }    }        class Rectangle : Shape    {        double length;        public double Length        {            get { return length; }            set { length = value; }        }        double width;        public double Width        {            get { return width; }            set { width = value; }        }        public Rectangle(string myname, double len,double wid)            : base(myname)        {            length = len;            width = wid;        }        public override void Introduction()        {            Console.WriteLine("我是矩形:{0}",Name);        }        public override double Area()        {            double area = 0;            area = 2 * (length + width);            return area;        }        public override double Perimeter()        {            double area = 0;            area = length * width;            return area;        }    }            class Square : Shape    {        double a;        public double A        {            get { return a; }            set { a = value; }        }        public Square(string myname, double a1)            : base(myname)        {            a = a1;        }        public override void Introduction()        {            Console.WriteLine("我是正方形:{0}",Name);        }        public override double Area()        {            double area = 0;            area = 4 * a;            return area;        }        public override double Perimeter()        {            double area = 0;            area = a * a;            return area;        }    }

 

4.1、接口(与使用抽象类类似)接口是对能力和方法的抽象。		[public] interface 接口名		{			// 接口成员		}		-> 接口成员			-> 仅仅抽象能力,所以只有方法、属性、索引、事件声明			-> 接口中的成员就相当于抽象类中的抽象成员		-> 接口的定义和实现接口			-> 定义接口方法不用写访问修饰符,默认public			-> 子类继承自接口,实现接口中的方法时,写一个正常方法 (没有override)4.2、接口的多继承性(有同名方法的处理)(1)显式实现接口:	通过显式实现接口的方式为特定的接口重写特定的方法,调用方法时根据变量所属的接口类型来选择相应的方法。(2)调用接口:返回类型 接口名.方法名()显式实现的方法只能由接口调用	接口类的对象优先调用显式实现接口的方法,缺少的情况,再调用非显式实现的方法。	非接口类对象,只能调用非显式实现的方法,不能调用显式实现接口的方法。	示例:    class Duck4 : Duck,IJiaoable1, IJiaoable2    {        public void Jiao()        {            Console.WriteLine("普通实现接口");        }        void IJiaoable1.Jiao()        {            Console.WriteLine("显式实现接口IDuck1");        }        void IJiaoable2.Jiao()        {            Console.WriteLine("显式实现接口IDuck2");        }    }	显式实现接口,Shift+Alt+F10生成,不加访问修饰符的(跟接口中一样)5、接口实现多态:鸭子的实例-联合使用继承和接口实现多态	不同鸭子游泳的方法不一样,所有鸭子都会游泳(继承)	不同鸭子叫的方法不一样,有的还不会叫(接口)
View Code
class Program    {        static void Main(string[] args)        {            Duck[] d = { new RealDuck(), new RubberDuck(),new WoodDuck()};            for (int i = 0; i < d.Length; i++)            {                d[i].Swim();                IJiaoable dk = d[i] as IJiaoable;                if (dk != null)                 {                    dk.Jiao();                }                                  }            Console.ReadKey();        }    }    abstract class Duck    {       public abstract void Swim();    }    interface IJiaoable    {        void Jiao();    }    class RealDuck : Duck, IJiaoable    {        public override void Swim()        {            Console.WriteLine("我是真的鸭子,我会游泳!我游啊游~~~");        }        public void Jiao()        {            Console.WriteLine("我是真的鸭子,嘎嘎嘎!");        }    }    class RubberDuck : Duck, IJiaoable    {        public override void Swim()        {            Console.WriteLine("我是橡皮鸭子,我会游泳!我游啊游~~~");        }        public void Jiao()        {            Console.WriteLine("我是橡皮鸭子,唧唧~~唧唧~~");        }    }    class WoodDuck : Duck  //没有叫的方法,于是不实现IJiaoable接口    {        public override void Swim()        {            Console.WriteLine("我是木头鸭子,我会游泳!我游啊游~~~");        }}
6.多接口中有同名方法的调用  根据对象的接口类型,优先调用显式实现的该接口方法。  没有针对该接口的显式实现方法可调用时,调用非显式实现的方法。    显式实现接口,Shift+Alt+F10生成,不加访问修饰符的(跟接口中一样)    演示:普通实现接口和显示实现接口的调用   执行结果:	Duck1,普通实现接口	Duck1,普通实现接口	Duck2,显式实现接口IJiaoableA	Duck2,普通实现接口	Duck3,普通实现接口	Duck3,显式实现接口IJiaoableB	Duck4,显式实现接口IJiaoableA	Duck4,显式实现接口IJiaoableB		 代码清单:
View Code
namespace 显式实现接口演示{    class Program    {        static void Main(string[] args)        {                Duck[] dk = { new Duck1(), new Duck2(),new Duck3(),new Duck4() };                for (int i = 0; i < 4; i++)                {                    IJiaoableA dka = dk[i] as IJiaoableA;                    if (dka != null)                        dka.Jiao();                    IJiaoableB dkb = dk[i] as IJiaoableB;                    if (dkb != null)                        dkb.Jiao();                    Console.WriteLine();                }                Console.ReadKey();        }    }        public abstract class Duck    {    }    interface IJiaoableA    {        void Jiao();    }    interface IJiaoableB    {        void Jiao();    }    //普通实现接口:不针对两个接口分别写方法    class Duck1 : Duck, IJiaoableA, IJiaoableB    {        public void Jiao()        {            Console.WriteLine("Duck1,普通实现接口");        }    }    //普通实现接口+显式实现接口“IDuck1”    class Duck2 : Duck,IJiaoableA, IJiaoableB    {        public void Jiao()        {            Console.WriteLine("Duck2,普通实现接口");        }        void IJiaoableA.Jiao()        {            Console.WriteLine("Duck2,显式实现接口IJiaoableA");        }    }    //普通实现接口+显式实现接口“IDuck2”    class Duck3 : Duck,IJiaoableA, IJiaoableB    {        public void Jiao()        {            Console.WriteLine("Duck3,普通实现接口");        }        void IJiaoableB.Jiao()        {            Console.WriteLine("Duck3,显式实现接口IJiaoableB");        }    }    //普通实现接口+显式实现接口“IDuck1”+显式实现接口“IDuck2”    class Duck4 : Duck,IJiaoableA, IJiaoableB    {        public void Jiao()        {            Console.WriteLine("Duck4,普通实现接口");        }        void IJiaoableA.Jiao()        {            Console.WriteLine("Duck4,显式实现接口IJiaoableA");        }        void IJiaoableB.Jiao()        {            Console.WriteLine("Duck4,显式实现接口IJiaoableB");        }    }}

 

7、多态的应用原则
多态实现方式:接口实现多态(对外)、抽象实现多态、父类实现多态(对内)	开发过程:    定义接口—定义抽象—父类—子类,最终使用的是子类,给用户的是接口。	              开发以抽象为主,能够抽象,尽量不要使用具体。	接口的使用原则:单一功能,组合使用。	抽象类是对一类事物的抽象,接口是对能力和方法的抽象。8、简单工厂设计模式(使项目模块化,可以将不同模块分给不同的项目小组去完成和维护)   思路:在Main方法中使用父类变量接收工厂方法的子类对象,实现了“统一调用,不同实现”的多态性。   步骤:写一个父类(抽象、具体、接口),定义统一的执行标准   写若干个子类,分别重写父类方法或实现接口的方法   写一个Factory类,根据需求new出子类,赋给父类变量返回   Mian方法中完成需求输入,调用Factory类方法,得到对象调用特定子类的方法。      演示:多态实现不同移动设备各自的读写操作   运行结果:   	请选择您的设备类型:	输入编号或简码: 1.U盘(u/U), 2.Mp3(m/M), 3.移动硬盘(h/H)	1	U盘读数据中	U盘写数据中	请选择您的设备类型:	输入编号或简码: 1.U盘(u/U), 2.Mp3(m/M), 3.移动硬盘(h/H)	2	Mp3读数据中	Mp3写数据中	Mp3播放音乐中	请选择您的设备类型:	输入编号或简码: 1.U盘(u/U), 2.Mp3(m/M), 3.移动硬盘(h/H)	3	移动硬盘写数据中	移动硬盘读数据中 代码清单:
View Code
namespace IMoveMemableDemo {    class Program    {        static void Main(string[] args)        {            while (true)            {                //请用户插入移动设备                Console.WriteLine("请选择您的设备类型:\n输入编号或简码: 1.U盘(u/U), 2.Mp3(m/M), 3.移动硬盘(h/H)");                //根据用户输入调用“工厂模式”方法返回对象                IMoveMemable device = Factory.GetDevice(Console.ReadLine());                //使用设备 应用多态                if (device != null)                {                    device.Read();                    device.Write();                    Mp3 mp3 = device as Mp3;                    if (mp3!=null)                        mp3.PlayMusic();                }                else                {                    Console.WriteLine("您输入的设备类型不存在!");                }                Console.WriteLine();                Console.WriteLine();            }        }    }        public class Factory    {        public static IMoveMemable GetDevice(string name)        {            IMoveMemable device = null;            switch (name)            {                case "1":                case "u":                case "U": device = new UDisk(); break;                case "2":                case "m":                case "M": device = new Mp3(); break;                case "3":                case "h":                case "H": device = new MHardDisk(); break;                default:                    break;            }            return device;        }    }         public interface IMoveMemable    {        void Write();        void Read();    }    public class UDisk : IMoveMemable    {        public void Write()        {            Console.WriteLine("U盘写数据中");        }        public void Read()        {            Console.WriteLine("U盘读数据中");        }    }    public class Mp3 : IMoveMemable    {        public void Write()        {            Console.WriteLine("Mp3写数据中");        }        public void Read()        {            Console.WriteLine("Mp3读数据中");        }        public void PlayMusic()        {            Console.WriteLine("Mp3播放音乐中");        }    }    public class MHardDisk : IMoveMemable    {        public void Write()        {            Console.WriteLine("移动硬盘读数据中");        }        public void Read()        {            Console.WriteLine("移动硬盘写数据中");        }    }    }

 

 

转载于:https://www.cnblogs.com/Extreme/archive/2013/05/05/3060968.html

你可能感兴趣的文章
酷派8150(移动版)直板4英寸单核30万像素智能手机参数
查看>>
为你喜欢的网站建立一个“快捷方式”【url】
查看>>
一键DDOS防火墙安装程序
查看>>
python3 开发微信自动回复
查看>>
记一次安装多版本php的四个雷区,你踩着了吗
查看>>
How To Debug PHP Code And Useful PHP Debugging ...
查看>>
Strongswan+freeradius+daloradius+ad认证实现ikev2接入服务四
查看>>
Menu菜单
查看>>
文件对象方法tell()、seek()
查看>>
我的Git忽略文件
查看>>
Java基础学习总结(8)——super关键字
查看>>
我的友情链接
查看>>
青春路上,岁月如烟
查看>>
lmis的一些表
查看>>
库房分析数据
查看>>
BZOJ4849[Neerc2016]Mole Tunnels——模拟费用流+树形DP
查看>>
Linux学习笔记——网络属性管理
查看>>
21分钟Mysql入门教程
查看>>
ActiveMQ学习总结(2)——ActiveMQ入门实例教程
查看>>
RabbitMQ学习总结(2)——安装、配置与监控
查看>>