美文网首页
面向对象(二刷)

面向对象(二刷)

作者: 山猪打不过家猪 | 来源:发表于2022-10-05 14:42 被阅读0次

    1. 继承

    1.1 继承中的关键字
    image.png
    • Program.cs
    using System;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Dog d1 = new Dog() { Name = "肥狗", Age = 99, Color = "Yellow"};
                //Cat c1 = new Cat() { Name = "肥猫", Age = 10, Color = "White",Favorite= "牛奶" };
                Cat c1 = new Cat("花猫", 40, "白色", "辣椒");
                d1.Introduce();
                d1.DogSay();
                c1.Introduce();
                c1.CatSay();
            }
        }
    }
    
    • 父类Animal.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApp1
    {
        class Animal
        {
            /// <summary>
            /// 无参数构造函数,这样就可以使用构造器来传参
            /// </summary>
            public Animal() { }
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="name"></param>
            /// <param name="age"></param>
            /// <param name="color"></param>
            public Animal(string name,int age, string color)
            {
                this.Name = name;
                this.Age = age;
                this.Color = color;
            }
            public string Name { get; set; }
            public int Age { get; set; }
            public string Color { get; set; }
    
            public void Introduce()
            {
                string info = string.Format("我的名字是{0},我的年龄是{1},我的颜色是{2}", Name, Age, Color);
                Console.WriteLine(info);
    
            }
            public void Dance()
            {
                Console.WriteLine("开始表演激光雨");
            }
            /// <summary>
            /// 只能子类访问
            /// </summary>
            protected void SayFrom()
            {
                Console.WriteLine("我在来自父类Aimal");
            }
    
            private void SayFather()
            {
                Console.WriteLine("我是父亲,只能自己用");
    
            }
        }
    }
    
    
    • Dog.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApp1
    {
        class Dog:Animal
        {
    
            public Dog() { }
            public Dog(string name,int age,string color):base(name,age,color)
            {
            }
            public void DogSay()
            {
                Console.WriteLine("汪汪汪");
            }
        }
    }
    
    
    • Cat.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApp1
    {
        class Cat:Animal
        {
    
            public Cat() { }
            public Cat(string name, int age, string color,string favorite):base(name,age,color)
            {
                this.Favorite = favorite;
            }
            public string Favorite { get; set; }
            public void CatSay()
            {
                string say = string.Format("喵喵喵{0}", this.Favorite);
                Console.WriteLine(say);
                base.SayFrom();
                
            }
        }
    }
    
    

    注意:如果子类想使用构造器传参,那么父类必须有一个空的构造函数,且子类也需要和父类一致

    2. 多态

    2.1 概念
    image.png
    使用继承实现多态
    image.png
    可以看出调用的时候是依据父类调用的,所以在开发过程中,可以不需要关心其他子类如何实现的,只用关心自己写的这个类的Have方法
    2.2 抽象方法

    不使用抽象方法的话,每次都需要判断

    //将子类对象添加到父类集合中
    List<Animal> animalList = new List<Animal>();
    animalList.Add(d1);
    animalList.Add(c1);
    foreach (Animal item in animalList)
    {
        item.Introduce();
        if (item is Cat)
        {
            ((Cat)item).CatSay();//需要将Animal类型转换为Cat类型才可以
        }
        else if (item is Dog)
        {
            ((Dog)item).DogSay();
        }
        else
        {
            item.Dance();
        }
    
    
    使用抽象方法

    给父类添加抽象方法时候,需要将父类改成抽象类
    abstract class Animal,子类使用的时候可以不讲子类改成抽象类
    但是一个抽象类中,可以不使用抽象方法
    给父类添加一个抽象方法

    public abstract void Have();
    

    子类重写抽象方法

    public override void Have()
    {
        Console.WriteLine("子类猫,重写了父类方法");
    }
    

    -总结


    image.png
    2.3 虚方法
    与抽象方法的区别

    1)抽象方法仅仅是一个声明abstract,是个空方法,无内容
    2)抽象方法必须在子类中override
    3)虚方法在父类中是可以实现的方法,子类可以选择重写或者重写,使用virtual

    与抽象方法的相同点

    1)父类都要改成abstract
    2)子类改写的时候都用override

    image.png
    虚方法使用

    父类Animal.cs

    public virtual void Have(){
        Console.Writeline("我们吃饭了");
    }
    

    子类Cat.cs中重写

    public override void Have(){
        Console.Writeline("猫猫吃饭了");
    }
    

    使用虚方法重写系统ToString()方法

    public override string ToString()
    {
        string a = string.Format("{0}狗的ToString方法", Name);
        return a;
    }
    
    2.4 密封类与方法重写
    密封类

    当一个类被sealed修饰后,他将不会被继承,不能作为父类,一定程度限制二次开发,这也是抽象方法和虚方法不能放在密封类的原因

    方法重写(覆盖了父类的重名方法)
    public new void Introduce(){
        Console.Writeline("这是猫猫的自我介绍");
    }
    

    方法重写遇到一个bug就是如果将子类通过里氏转换转为父类,将执行父类的方法,而不是子类New的新方法

    3. 接口与多态

    3.1 接口的创建和使用
    • 创建一个接口Interface1.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace InterfaceDemo
    {
        interface Interface1
        {
            void Print(string content);
            void Copy(string content);
            bool Fax(string content);
        }
    }
    
    • 使用接口HPprinter.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace InterfaceDemo
    {
        class HPprinter : Interface1
        {
            public void Copy(string content)
            {
                Console.WriteLine("正在打印:"+content);
            }
    
            public bool Fax(string content)
            {
                Console.WriteLine("正在传真:" + content);
                return true;
            }
    
            public void Print(string content)
            {
                Console.WriteLine("正在复印:" + content);
            }
        }
    }
    
    
    • 使用Program.cs
    using System;
    using System.Collections.Generic;
    
    namespace InterfaceDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                //基于接口创建对象
                Interface1 inter1 = new HPprinter();
                inter1.Print("Fxx成绩单");
                inter1.Copy("Fxx信息");
            }
        }
    }
        
    

    注意:接口的实例化和类实例化有区别Interface1 inter1 = new HPprinter();

    3.2 接口实现多态
    接口多态的概念
    image.png
    接口多态的使用

    实现了传入不同的接口,调用了不同的方法

    • 创建过程:
      1)首先明确需要什么接口,这里需要一个打印机的接口,且打印机都必须具有复印,传真,打印的功能。这样可以限定之后所有创建的打印机都有完善的功能,可以多但是不能少功能。
      2)写完了一个通用的接口后,就需要写具体实现的接口,比如惠普打印机,佳能打印机,不同打印机打印的方法和技术各部相同,但是都必须完成打印这个功能
      3)可以先创建一个使用打印机方法,传入各个品牌打印机的接口,调用打印的各个功能
      4)使用,实例化需要使用的各个品牌的打印机,将佳能传入使用打印机方法,就可以实现所有打印机的功能
      Program.cs
    using System;
    using System.Collections.Generic;
    
    namespace InterfaceDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                UsePrinter(new HPprinter());
                UsePrinter(new CannoPrinter());
            }
            /// <summary>
            /// 使用打印机类
            /// </summary>
            /// <param name="objInterface"></param>
            static void UsePrinter(Interface1 objInterface)
            {
                objInterface.Print("Fxx成绩单");
                objInterface.Copy("Fxx信息");
            }
        }
    }
    
    • 接口类Interface1.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace InterfaceDemo
    {
        interface Interface1
        {
            void Print(string content);
            void Copy(string content);
            bool Fax(string content);
    
        }
    
        class HPprinter : Interface1
        {
            public void Copy(string content)
            {
                Console.WriteLine("正在打印:" + content);
            }
    
            public bool Fax(string content)
            {
                Console.WriteLine("正在传真:" + content);
                return true;
            }
    
            public void Print(string content)
            {
                Console.WriteLine("正在复印:" + content);
            }
        }
    
        class CannoPrinter : Interface1
        {
            public void Copy(string content)
            {
                Console.WriteLine("佳能正在打印:" + content);
            }
    
            public bool Fax(string content)
            {
                Console.WriteLine("佳能正在传真:" + content);
                return true;
            }
    
            public void Print(string content)
            {
                Console.WriteLine("佳能正在复印:" + content);
            }
        }
    }
    
    
    3.3 和抽象类的区别
    image.png

    相关文章

      网友评论

          本文标题:面向对象(二刷)

          本文链接:https://www.haomeiwen.com/subject/jtpmartx.html