zoukankan      html  css  js  c++  java
  • 3、C#面向对象:封装、继承、多态、String、集合、文件(下)

    面向对象多态

    一、装箱和拆箱

    装箱:将值类型转换为引用类型。object o = 1;值类型给引用类型赋值

    拆箱:将引用类型转换为值类型。int n = (int)o; 强制转换为值类型

    满足条件:两种类型是否存在继承关系。

    int n = Convert.ToInt32("12"); 未发生装箱或拆箱 。int存储在栈,string存储在堆

    装箱或拆箱会影响程序运行事件。

    二、面向对象多态

    对象在调用同一个方法的时候表现出来多种状态。

    1、虚方法

    将父类的方法标记为虚方法使用关键字virtual,可以被子类重新写一

    protected void Page_Load(object sender, EventArgs e)
    {
        person[] p = new person[2];
        chinese p1 = new chinese();
        jpan p2 = new jpan();
        p[0] = p1;
        p[1] = p2;
        Response.Write(p[0].SayHi()); //调用的方法时取决于自己是什么对象
        Response.Write(p[1].SayHi());
    }
    
    public class person
    {
        public virtual string SayHi() //父类方法使用virtual表示该方法是虚方法
        {
            return "人类";
        }
    }
    
    public class chinese : person
    {
        public override string SayHi() //子类方法使用override表示该方法是重写虚方法
        {
            return "中国人";
        }
    }
    
    public class jpan : person
    {
        public override string SayHi() // override
        {
            return "日本人";
        }
    }

    2、抽象类

    当父类中的方法不知道如何去实现的时候,可以考略将父类写成抽象类,将方法写成抽象方法。

    使用abstract定义的类为抽象类,使用abstract定义的方法为抽象方法,抽象函数是没有方法体的。

    抽象类无法实例化父类,直接实例化子类调用。

    父类方法中有意义时使用虚方法,父类方法中方法无意义时使用抽象类。

    protected void Page_Load(object sender, EventArgs e)
    {
        //抽象类不能被实例化 只能实例化子类对象
        xingzhuang y = new yuan(5);
        double mianji = y.mianji();
        double zhouchang = y.zhouchang();
        Response.Write("半径为5的原型面积为:" + mianji + ",周长:" + zhouchang);
        xingzhuang ju = new juxing(10, 20);
        double mianji1 = ju.mianji();
        double zhouchang1 = ju.zhouchang();
        Response.Write("高为10的宽为20的矩形面积为:" + mianji1 + ",周长:" + zhouchang1);
    }
    
    public abstract class xingzhuang //被标记为abstract的类称为抽象类
    {
        public string Name { get; set; } //抽象类中可以包含实例成员,并且实力成员可以不被子类实现。
        public abstract double mianji(); //抽象方法必须标记为abstract,并且不能有任何实现,必须在抽象类中。
        public abstract double zhouchang(); //抽象成员的访问修饰符不能是private
    }
    
    public class yuan : xingzhuang
    {
        public double R { get; set; }
        public yuan(double r)
        {
            this.R = r;
        }
        public override double mianji() //子类继承抽象类后必须把父类中所有抽象成员重写
        {
            return Math.PI * this.R * this.R;
        }
        public override double zhouchang() //子类继承抽象类后必须把父类中所有抽象成员重写
        {
            return 2 * Math.PI * this.R;
        }
    }
    
    public class juxing : xingzhuang
    {
        public double width { get; set; }
        public double height { get; set; }
        public juxing(double height, double width)
        {
            this.height = height;
            this.width = width;
        }
    
        public override double mianji() //子类继承抽象类后必须把父类中所有抽象成员重写
        {
            return this.height * this.width;
        }
        public override double zhouchang() //子类继承抽象类后必须把父类中所有抽象成员重写
        {
            return (this.height + this.width) * 2;
        }
    }

    三、简单工厂设计模式

    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
    
                Console.WriteLine("请输入要进入的磁盘");
    
                string path = Console.ReadLine();
    
                Console.WriteLine("请输入要进入的文件");
    
                string fileName = Console.ReadLine();
    
    
                FileFather f = getFile(fileName, path + fileName);
    
                f.OpenFile(); //打开一个文件取决于输入一个什么文件
    
                Console.ReadKey();
    
            }
        }
    
        public static FileFather getFile(string fileName, string fullName) //简单工厂形式返回父类
        {
    
            string ext = Path.GetExtension(fileName);
    
            FileFather f;
    
            switch (ext)
            {
    
                case ".txt":
    
                    f = new txtPath(fullName);
    
                    break;
    
                case ".jpg":
    
                    f = new jpgPath(fullName);
    
                    break;
    
                default:
    
                    f = null;
    
                    break;
            }
            return f;
        }
    }
    
    
    public abstract class FileFather //抽象父类
    {
    
        public string fileName { get; set; } //文件全路径
    
        public FileFather(string fileName) //构造函数 自己不能用
        {
            this.fileName = fileName;
        }
        public abstract void OpenFile(); //抽象方法
    }
    
    public class txtPath : FileFather
    {
    
        public txtPath(string fileName) //继承父类构造函数
            : base(fileName)
        {
    
        }
    
        public override void OpenFile() //子类重写
        {
            ProcessStartInfo psi = new ProcessStartInfo(fileName);//使用进程打开指定文件
            Process pro = new Process();
            pro.StartInfo = psi;
            pro.Start();
        }
    }
    
    public class jpgPath : FileFather
    {
        public jpgPath(string fileName)
            : base(fileName)
        {
    
        }
    
        public override void OpenFile()
        {
            ProcessStartInfo psi = new ProcessStartInfo(fileName);
            Process pro = new Process();
            pro.StartInfo = psi;
            pro.Start();
        }
    }

    四、值传递和引用传递

    值类型:int double char decimal bool enum struct 存储于栈

    引用类型:string 数组 自定义类 集合 object 接口 存储于堆

    值传递:int n1 = 10; n2 = n1; n2 = 20; 值类型在赋值的时候,传递的是这个值的本身,复制了一份。 p1 = 10 ; p2 = 20;

    引用传递:p1.name = "3"; p2.name = p1.name; p2.name="4"; 引用类型在赋值的时候,传递的是这个值的引用,引用同一份,p1 p2 指向同一块内存。

    五、序列化和反序列化

    序列化:将对象转换为二进制

    反序列化:将二进制转换为对象

    作用:传输数据。

    1、将这个类标记为可以被序列化 [Serializable]。

    2、使用BinaryFormatter开始序列化对象。

    protected void Page_Load(object sender, EventArgs e)
    {
    
        //将P传输给对方电脑
        person p = new person();
        p.name = "张三";
        p.age = 18;
        p.gender = '';
        using (FileStream sw = new FileStream(@"d:11.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))//序列化到目标文件
        {
            //开始序列化对象
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(sw, p); //要被序列化的对象 sw.Write 自动完成
        }
        person per = new person();
        //接收对方发过来的二进制 反序列化对象
        using (FileStream sr = new FileStream(@"d:11.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
        {
            BinaryFormatter bf1 = new BinaryFormatter();
            per = (person)bf1.Deserialize(sr);
        }
        Response.Write(per.name + per.age + per.gender);
    }
    
    [Serializable] //将这个类标记为可被序列化
    public class person
    {
        public string name { get; set; }
        public int age { get; set; }
        public char gender { get; set; }
    }

    六、部分类partial

    局部类型允许我们将一个类、接口或结构分成好几个部分,分别实现在几个不同的.cs文件中

    public partial class person
    {
    }
    public partial class person
    {
    }

    1)类型特别大,不宜放在一个文件中实现。

    2)需要多人合作编写一个类。

    七、密封类sealed

    密封类用sealed修饰,不能被继承。因此,它也不能是抽象类。

    重写ToString()

    子类重写父类的虚方法

    public override string ToString(){ return "sd";}

    八、接口interface

    接口是一种规范,是一个引用类型,因为继承只能继承一个,所以通过接口可以实现多重继承。

    只要一个类继承了一个接口,这个类就必须实现接口的所有成员。

    接口不能实例化,不能被new。

    在声明接口成员的时候,不准为接口成员编写具体的可执行代码.

    接口与接口之间可以继承,可以多继承,接口不能继承类。

    接口成员不能有static、abstract、override、virtual修饰符,使用new修饰符不会报错,但会给出警告说不需要关键字new。

    一个类继承了接口又继承了类,语法上必须先继承类,再继承接口

    public interface IFly
    {
        //成员不允许添加访问修饰符,默认就是public
        string name { get; set; } //接口可以有方法、属性、所引器。
        void Fly(); //不可以有方法体
    }
    
    public class father
    {
    
    }
    
    public class person : father, IFly //先写类 后写接口
    {
        public string name { get; set; }
        public void Fly()
        {
        }
    }

    显示接口

    //用来解决方法重名问题
    class Program
    {
        static void Main(string[] args)
        {
            Ifly fly = new Birad();
            fly.Fly(); //接口的
            Briad bid = new Briad();
            bid.Fly(); //自己的
        }
    }
    
    public class Birad : Ifly //鸟类继承接口ifly
    {
        public string Fly() //类自己的方法
        {
            return "fly";
        }
    
        public string Ifly.Fly()
        { //接口的方法
            return "ifly11111";
        }
    }
    
    public interface Ifly //定义接口 fly方法
    {
        string Fly();
    }

    九、异常与异常处理

    try
    {
        int number = 10; //可能出错的代码块
    }
    
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);//错误信息
        throw new Exception("错误"); //抛出异常
    }

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

      可以提取出一个父类,需要写出明方法时。
    2、什么时候用抽象类实现多态?

      可以提取出一个父类,但是不知道具体怎么实现时。
    3、什么时候用接口来实现多态?

      无法提取出一个父类,但是都有一个共同的行为,或者需要多重继承时。

  • 相关阅读:
    数值数据类型
    如何提高数据迁移和复制的速度
    dns解析
    cdn加速
    集群
    JavaScript初学者应注意的七个细节
    CXF 5参考资料
    深入理解Spring MVC 思想
    【深入理解Java内存模型】
    牛人论
  • 原文地址:https://www.cnblogs.com/baidawei/p/4702526.html
Copyright © 2011-2022 走看看