• C#面向对象五(继承、抽象类和抽象方法、多态、虚方法、is、as、new覆盖关键字)


    1.继承的特点:

      继承顺序的不可逆性:继承是从上往下依此继承,而不能逆序进行。

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

    2.继承的好处:

      代码复用,避免重复。

      一处更新,处处更新。

    3.继承的步骤和使用要点:

      抽取公共部分,放到一个特定的类中(父类)。

      其他类(子类)只需要继承父类,即可拥有父类特征(属性和方法)。

      根据子类的需要添加属于自己的特征和方法。

    4.继承的实现(和接口的实现形式类似)

      在子类后面使用冒号“:”继承父类,如  class Dog : Animal

    5.概念解释

      子类继承父类,父类派生子类。

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

      子类继承父类成员,也可以有自己独立的成员。

    6.继承的条件

      继承需要符合的关系:is-a 的关系  Cat is an Animal。

    7.继承中的构造函数

      this:可以使用this关键字访问父类成员(在构造函数中)。

      base:调用父类的构造函数、调用父类的属性和方法。

    1 public Dog(string name,string color,string kind,string favorite):base(name,color,kind)
    2 {
    3     this.Favorite=favorite;  
    4 }
    继承中使用base关键字
     1 class Animal
     2     {
     3         //父类构造函数
     4         public Animal() { }
     5         public Animal(string name, string color, string kind)
     6         {
     7             this.Color = color;
     8             this.Name = name;
     9             this.Kind = kind;
    10         }
    11        
    12         public string Name { get; set; }//名字
    13         public string Color { get; set; }//颜色
    14         public string Kind { get; set; }//种类
    15         public string Favorite { get; set; }//喜好
    16     }
    17 
    18 class Dog : Animal
    19     {     
    20         public Dog(string name, string color, string kind, string favorite)
    21             : base(name, color, kind)
    22         {
    23             this.Favorite = favorite;
    24         }          
    25     }
    继承中base关键字(2)

    8.protected关键字

      protected访问修饰符允许子类访问,而不允许其他非子类访问。

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

    9子类调用父类构造函数总结

      隐式调用:如果其他子类的构造函数没有使用base指明调用父类哪个构造函数时,子类会默认调用父类的无参构造函数:base()。这时父类要提供无参的构造函数。

      显式调用:如果父类没有无参的构造函数,子类构造函数必须指明调用父类哪个构造函数。

    10.继承的特性

      继承的传递性:传递机制  A——>B   B——>C    C具有A的特性

      继承的单根性:一个类只能有一个父类

      例如机器视觉技术与软件学科又属于光学学科,能否同时继承两种人?  答案:不能

    11.抽象类和抽象方法 abstract override

      抽象方法就是在父类中未实现的方法,在子类中必须实现父类中的所有的抽象方法。

      一个抽象类内可以没有抽象方法。

      一个抽象方法所在的类必须是抽象类。

     1 abstract class Animal
     2 {
     3    public string Name {get;set;}
     4    public Animal(){}
     5    //用abstract修饰抽象方法
     6    public abstract void Have();
     7 }
     8 
     9 class Dog:Animal
    10 {
    11    //用override重写父类未实现的方法
    12    public override void Have()
    13    {
    14        Console.WriteLine("狗吃骨头");
    15    }
    16 }
    17 
    18 class Cat:Anima
    19 {
    20     public override void Have()
    21     {
    22         Console.WriteLine("猫吃鱼");
    23     }
    24 }    
    抽象方法和重写
     1 abstract class Animal
     2     {
     3         public string Name { get; set; }//名字
     4         public string Color { get; set; }//颜色
     5         public string Kind { get; set; }//种类
     6         public string Favorite { get; set; }//喜好
     7         //父类构造函数
     8         public Animal() { }
     9         public Animal(string name, string color, string kind)
    10         {
    11             this.Color = color;
    12             this.Name = name;
    13             this.Kind = kind;
    14         }
    15         //抽象方法
    16         public abstract void Have();
    17     }
    18 
    19 class Dog : Animal
    20     {
    21         public Dog(string name, string color, string kind, string favorite)
    22             : base(name, color, kind)
    23         {
    24             this.Favorite = favorite;
    25         }
    26         public override void Have()
    27         {
    28             Console.WriteLine("我们要吃香喷喷的排骨啦!");
    29         }
    30     }
    31 
    32 class Cat : Animal
    33     {
    34         public Cat(string name, string color, string kind, string favorite)
    35             : base(name, color, kind)
    36         {
    37             this.Favorite = favorite;
    38         }
    39         public override void Have()
    40         {
    41             Console.WriteLine("我们要吃香喷喷的烤鱼啦!");
    42         }
    43     }
    44 
    45 static void Main(string[] args)
    46         {
    47             //创建一只狗和一只猫
    48             Cat objCat = new Cat("球球儿", "黄色", "小花猫", "小鱼");
    49             Dog objDog = new Dog("棒棒", "黑色", "小黑狗", "排骨");
    50             //将子类对象添加的父类集合
    51             List<Animal> list = new List<Animal>();
    52             list.Add(objCat);
    53             list.Add(objDog);
    54             //取出子类对象
    55             foreach (Animal obj in list)
    56             {
    57                 obj.Have();//***********这就是多态***********
    58             }
    59             Console.ReadLine();
    60         }
    抽象方法和重写(2)

    12.抽象类的概念与使用要点

      12.1使用关键字abstract修饰的类,称为抽象类

      12.2抽象类只是用来列举一个类所具有的行为,不能单独通过创建对象来使用,也就是说抽样类不能被new

      12.3抽象类中可以有抽象方法,也可以没有任何抽象方法

      12.4抽象类不能是静态的(static)或密封的(sealed),密封类不能被继承

    13.抽象方法的概念与使用要点

      13.1在抽象类中使用abstract修饰的方法,称为抽象方法

      13.2抽象方法必须在抽象类中定义,不能在普通类中使用

      13.3抽象方法只是一个方法的声明,不能有任何方法体

      13.4抽象方法仅仅是表示一个应该具有的行为,具体实现由其子类实现

      13.5抽象方法在子类中被实现(重写)必须使用关键字override

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

     14.多态

      概念:不同对象,接受相同信息,产生不同行为,称为多态。

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

      例如:子类重写了父类的抽象方法,父类集合中的对象直接调用抽象方法,实现子类中重写的抽象方法,可以称之为多态。

    15.使用继承实现多态

      15.1父类中必须有抽象方法或虚方法

      15.2子类必须覆写(override)父类中的抽象方法或虚方法

      15.3子类对象必须转换成父类类型去使用

      多态的应用大大提高了程序的可扩展性

     1 abstract class Animal
     2     {
     3         public string Name { get; set; }//名字
     4         public string Color { get; set; }//颜色
     5         public string Kind { get; set; }//种类
     6         public string Favorite { get; set; }//喜好
     7         //父类构造函数
     8         public Animal() { }
     9         public Animal(string name, string color, string kind)
    10         {
    11             this.Color = color;
    12             this.Name = name;
    13             this.Kind = kind;
    14         }
    15         //抽象方法
    16         public abstract void Have();
    17     }
    18 
    19 class Dog : Animal
    20     {
    21         public Dog(string name, string color, string kind, string favorite)
    22             : base(name, color, kind)
    23         {
    24             this.Favorite = favorite;
    25         }
    26         //吃饭
    27         public override void Have()
    28         {
    29             Console.WriteLine("我们要吃香喷喷的排骨啦!");
    30         }
    31     }
    32 
    33 class Cat : Animal
    34     {
    35         public Cat(string name, string color, string kind, string favorite)
    36             : base(name, color, kind)
    37         {
    38             this.Favorite = favorite;
    39         }
    40         //吃饭
    41         public override void Have()
    42         {
    43             Console.WriteLine("我们要吃香喷喷的烤鱼啦!");
    44         }
    45     }
    46 
    47 static void Main(string[] args)
    48         {
    49             //创建一只狗和一只猫
    50             Cat objCat = new Cat("球球儿", "白色", "小花猫", "小鱼");
    51             Dog objDog = new Dog("棒棒", "黑色", "小黑狗", "排骨");
    52             //调用方法,传递子类对象
    53             Test(objCat);
    54             Test(objDog);
    55             Console.ReadLine();
    56         }
    继承多态的典型应用

     16.里氏替换原则

      16.1子类的对象能够替换父类

      16.2父类对象不能够替换子类

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

      解释:父类的范围广,父类包含子类,狗类属于动物类,但动物类不能仅属于狗类

    17.is和as操作符

      is操作符检查是否与指定类型兼容。如果转换失败程序中断

    1 foreach (Animal obj in list)
    2 {
    3    if(obj is Cat)
    4         Console.WriteLine("我是只猫");
    5    else if (obj is Dog)
    6         Console.WriteLine("我是条狗");
    7 }        
    is操作符

      as操作符用于在兼容的引用类型之间执行转换,转换失败返回null

      Cat cat = obj as Cat;

    18.引入虚方法(虚方法和抽象方法的区别)

      18.1抽象方法的特点:抽象方法仅仅是声明,没有任何实现内容;抽象方法一般必须在子类中被重写以后才有使用价值。

      18.2如果父类中提供一个方法,要求由自己的方法体,子类根据自己的需要再决定是否需要重写此方法,该如何实现?————>>>>>>虚方法!  原来的abstract换成virtual。

      18.3如果子类重写了虚方法,调用的就是子类的;如果子类未重写虚方法,调用的就是父类的。

     1 //注意有虚方法的父类并不要添加abstract关键字
     2     class Animal
     3     {
     4         public string Name { get; set; }//名字
     5         public string Color { get; set; }//颜色
     6         public string Kind { get; set; }//种类
     7         public string Favorite { get; set; }//喜好
     8         public Animal() { }
     9         public Animal(string name, string color, string kind)
    10         {
    11             this.Color = color;
    12             this.Name = name;
    13             this.Kind = kind;
    14         }
    15         //虚方法
    16         public virtual void Have()
    17         {
    18             Console.WriteLine("我们要吃饭啦!");
    19         }
    20     }
    21 
    22 //Dog类重写了虚方法
    23     class Dog : Animal
    24     {
    25         public Dog(string name, string color, string kind, string favorite)
    26             : base(name, color, kind)
    27         {
    28             this.Favorite = favorite;
    29         }
    30         //吃饭
    31         public override void Have()
    32         {
    33             Console.WriteLine("我们要吃香喷喷的排骨啦!");
    34         }
    35     }
    36 
    37 //Cat类未重写虚方法
    38     class Cat : Animal
    39     {      
    40         public Cat(string name, string color, string kind, string favorite)
    41             : base(name, color, kind)
    42         {
    43             this.Favorite = favorite;
    44         }
    45     }
    46 
    47 static void Main(string[] args)
    48         {
    49             //创建一只狗和一只猫
    50             Cat objCat = new Cat("球球儿", "黄色", "小花猫", "小鱼");
    51             Dog objDog = new Dog("棒棒", "黑色", "小黑狗", "排骨");
    52             //将子类对象添加的父类集合
    53             List<Animal> list = new List<Animal>();
    54             list.Add(objCat);
    55             list.Add(objDog);
    56             //取出子类对象
    57             foreach (Animal obj in list)
    58             {
    59                 obj.Have();
    60             }
    61             Console.ReadLine();
    62         }
    63 
    64 //最终结果显示
    65 //我们要吃饭啦!
    66 //我们要吃香喷喷的排骨啦!
    虚方法

    19.虚方法与抽象方法比较

    虚方法 抽象方法
    用virtual修饰 用abstract修饰
    要有方法体,哪怕是一个分号 不允许有方法体
    可以被子类override   必须被子类override
    除了密封类都可以写 必须在抽象类中

    20.object类自带的虚方法  

      Eauals()虚方法

        对于字符串和值类型,能够自动比较是否相等

        对于对象比较,必须重写override后才有意义

      ToString()虚方法

        对于值类型,返回变量值的字符串表示

        对于对象,默认返回该对象的完全限定类型名(完全限定类型名:引用空间+类名),可根据需要重写

    21.密封类sealed

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

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

    22.方法覆盖new

      子类中的方法定义时使用new关键字覆盖父类中的同名方法

      使用子类覆盖父类的方法后,子类对象调用该方法调用的是子类中new的方法

      如果其他子类没有覆盖new父类的同名方法,其他子类对象调用此方法时仍然是父类中的方法

      在控件开发中经常使用new关键字来覆盖父类的同名方法

     1 //Dog覆盖了Introduce(),Cat未处理
     2 abstract class Animal
     3     {
     4         public string Name { get; set; }//名字
     5         public string Color { get; set; }//颜色
     6         public string Kind { get; set; }//种类
     7         public string Favorite { get; set; }//喜好
     8         //父类构造函数
     9         public Animal() { }
    10         public Animal(string name, string color, string kind)
    11         {
    12             this.Color = color;
    13             this.Name = name;
    14             this.Kind = kind;
    15         }       
    16         //自我介绍
    17         public void Introduce()
    18         {
    19             string info = string.Format("这是父类的方法,我是漂亮的{0},我的名字叫{1},身穿{2}的衣服,我爱吃{3}!",
    20                  Kind, Name, Color, Favorite);
    21             Console.WriteLine(info);
    22         }       
    23     }
    24 
    25 class Dog : Animal
    26     {
    27         public Dog(string name, string color, string kind, string favorite)
    28             : base(name, color, kind)
    29         {
    30             this.Favorite = favorite;
    31         }
    32         public new void Introduce()
    33         {
    34             string info = string.Format("这是Dog类中的方法Hi! I am {0},My Name is {1}!",
    35                 Kind, Name);
    36             Console.WriteLine(info);          
    37         }
    38     }
    39 
    40 class Cat : Animal
    41     {
    42         public Cat(string name, string color, string kind, string favorite)
    43             : base(name, color, kind)
    44         {
    45             this.Favorite = favorite;
    46         }
    47     }
    48 
    49 static void Main(string[] args)
    50         {
    51             //创建一只狗和一只猫
    52             Cat objCat = new Cat("球球儿", "黄色", "小花猫", "小鱼");
    53             objCat.Introduce();
    54             Dog objDog = new Dog("棒棒", "黑色", "小黑狗", "排骨");
    55             objDog.Introduce();
    56             Console.ReadLine();
    57         }
    58 
    59 //结果显示
    60 //这是父类的方法,我是漂亮的小花猫,我的名字叫球球儿,身穿黄色的衣服,我爱吃小鱼!
    61 //这是Dog类中的方法,Hi! I am 小黑狗,My Name is 棒棒!
    使用new覆盖掉父类中的方法

    23.面向对象三大特性简单总结

      23.1封装  隐藏内部实现,稳定外部接口——>系统稳定性

      23.2继承  子类继承父类成员,实现代码复用——>开发和维护效率

      23.3多态  不同子类,对同一消息,做出不同反应——>系统扩展性

      23.1 封装是把一个对象的属性和行为打包,继承就是动物都会呼吸,多态就是人用肺呼吸,鱼用鳃呼吸。封装的是字段、属性、方法。封装的好处:数据安全、内部修改保持稳定、提高重用性、分工合作、职责分明、方便构建大型复杂的系统。封装是面向过程到面向对象的最大的一个改变。

      23.2 继承:去掉重复代码,可以实现多态,是侵入性很强的类关系,里氏替换原则

      23.3 多态:相同的变量,相同的操作,但是不同的实现。方法重载、接口&实现、抽象类&实现、继承&实现。

      23.4 抽象abstract:一方面子类都得有某个行为,另一方面子类中的各个行为又各不相同,可以在抽象abstract类里面定义一个抽象方法,在抽象方法里仅仅定义方法声明没有方法的具体实现,所有继承抽象类的子类必须override重写此抽象方法。抽象类没法直接实例化,只能new子类;面向抽象,只能用抽象里面的东西,如果有个性化操作(某个子类特有的),那就别抽象了,因为没有意义。

      23.5接口:接口中方法不能具体实现,这点和抽象类类似,且不能写访问修饰符,全部默认public,接口可以包含属性、事件、索引器,不能包含字段、委托、类。实现接口需要显式实现接口的所有方法(子类中方法前不需要加override)。接口不能直接实例化,只能new实现该接口的子类。

      23.6  如何选择接口和抽象类?

        抽象类:父类+约束,父类的特性可以在抽象类中完成通用方法的实现。 【 :相当于 is a】

        接口:纯粹的约束,只能约束,接口中所有的方法仅仅是声明、都不能实现。【:相当于 can do】

        一个子类只能继承一个父类,但可以实现多个接口,这点上来讲接口实现更灵活。【单继承多实现】  抽象类毕竟还是一个类,只是某些内容不确定,例如手机基类,在抽象类中可以定义名称、用户等属性和Call()、Photo()等可以实现的共有方法以及抽象的什么操作系统的手机方法,而接口则是定义行为,形容一系列事物可以大致做什么。【子类都一样的,放在父类;子类都有但是相关之间不同,抽象一下;有的有有的没有,接口】【工作中接口用的更多,因为接口更简单灵活,除非有些共有的东西需要继承】

        举例:门:属性有材质、猫眼、门铃          方法有开门()、关门()、报警()    抽象类:材质、开门()、关门()          接口:猫眼(运钞车也有猫眼,所以运钞车可以继承此接口)    接口:门铃    接口:报警(能报警的东西很多,例如说监控器、健康手表,所以这类东西都可以继承此接口)

      23.7 虚方法virtual与抽象方法abstract【重写new  覆写override  重载overload】

        虚方法可以在父类中默认实现,抽象方法不能在父类中实现,虚方法可以在子类中覆写也可以不覆写,抽象方法必须在子类中覆写。virtual、abstract、override可以一直覆写,不想被覆写,方法名前加sealed(密封:断子绝孙)  base.()  调用直接父类的方法     this.()指定当前这个类型的实例的方法,this只能放在实例方法中,在子类构造函数中的this.属性,该属性是父类中的属性,除非在子类中重写new此属性,如果重写this指的是此类中的属性。

  • 相关阅读:
    Web中的图标(Sprites雪碧图、Icon Font字体图标)
    那些不推荐使用的html标签
    Vim学习
    web前端性能优化建议
    开发基础
    数据库事务
    java集合详解
    java基础总结大纲(一)
    java设计模式之单例模式(饿汉)
    java设计模式之单例模式(内部静态类)
  • 原文地址:https://www.cnblogs.com/yangmengke2018/p/10871563.html
Copyright © 2020-2023  润新知