zoukankan      html  css  js  c++  java
  • 面向对象三大特性之继承

    什么是继承?

        继承是将两个类中相同的属性及方法抽取出来,放到一个新的类中(父类),而这两个子类依然拥有这些属性和方法。抽象点的

        说,每辆车子都能跑(拥有跑的方法),都有轮胎(有轮胎这个属性)。

    使用继承编程的好处?

        使用继承编程可以大大的减少代码冗余,增加代码复用。

    如何使用继承?

        以第一问为例做延伸:假若我们现在需要两个类,一个货车类,一个轿车类。代码如下

    /// <summary>
     2     /// 货车类
     3     /// </summary>
     4     class Truck
     5     {
     6         //时速
     7         public int Speed { get; set; }
     8         //颜色
     9         public string Colour { get; set; }
    10         //购买价格
    11         public double Price { get; set; }
    12         
    13         /// <summary>
    14         /// 货运方法
    15         /// </summary>
    16         public void Cargo()
    17         {
    18             Console.WriteLine("运输货物");
    19         }
    20     }
    21 
    22     /// <summary>
    23     /// 轿车类
    24     /// </summary>
    25     class Sedan
    26     {
    27         //时速
    28         public int Speed { get; set; }
    29         //颜色
    30         public string Colour { get; set; }
    31         //购买价格
    32         public double Price { get; set; }
    33         
    34         /// <summary>
    35         /// 载客方法
    36         /// </summary>
    37         public void CarryPassengers()
    38         {
    39             Console.WriteLine("载客");
    40         }
    41     }
    示例 : 未使用继承

        通过这段代码不难发现,货车类和轿车类拥有三个相同的属性,一个不同的方法。根据继承的特性,需要把相同的属性或方法抽

        取出来。代码如下

    /// <summary>
     2     /// 车辆类 父类
     3     /// </summary>
     4     class Vehicle
     5     {
     6         //时速
     7         public int Speed { get; set; }
     8         //颜色
     9         public string Colour { get; set; }
    10         //购买价格
    11         public double Price { get; set; }
    12     }
    13 
    14     /// <summary>
    15     /// 货车类 继承车辆类
    16     /// </summary>
    17     class Truck : Vehicle
    18     {
    19         /// <summary>
    20         /// 货运方法
    21         /// </summary>
    22         public void Cargo()
    23         {
    24             Console.WriteLine("运输货物");
    25         }
    26     }
    27 
    28     /// <summary>
    29     /// 轿车类 继承车辆类
    30     /// </summary>
    31     class Sedan : Vehicle
    32     {
    33         /// <summary>
    34         /// 载客方法
    35         /// </summary>
    36         public void CarryPassengers()
    37         {
    38             Console.WriteLine("载客");
    39         }
    40     }
    示例 : 使用继承

         

        那么问题又来了,继承的特性-代码复用体现在哪里呢?下面我们简单地了解一下。

        在第一段代码中,有两个类,如果我们想在创建对象时使用带参构造函数来初始化属性的话,要在两个类中都写上相同的一段代

        码。(构造函数详解)

     1     /// <summary>
     2     /// 货车类
     3     /// </summary>
     4     class Truck
     5     {
     6         //时速
     7         public int Speed { get; set; }
     8         //颜色
     9         public string Colour { get; set; }
    10         //购买价格
    11         public double Price { get; set; }
    12         public Truck(int speed, string colour, double price)
    13         {
    14             this.Speed = speed;
    15             this.Colour = colour;
    16             this.Price = price;
    17         }
    18         ...
    19     }
    20 
    21     /// <summary>
    22     /// 轿车类
    23     /// </summary>
    24     class Sedan
    25     {
    26         //时速
    27         public int Speed { get; set; }
    28         //颜色
    29         public string Colour { get; set; }
    30         //购买价格
    31         public double Price { get; set; }
    32         public Truck(int speed, string colour, double price)
    33         {
    34             ...
    35         }
    36         ...
    37     }
    示例 : 冗余的代码

        显而易见,上面的重复代码很多。下面我们使用继承来简化一下上面的代码。

     1     /// <summary>
     2     /// 车辆类 父类
     3     /// </summary>
     4     class Vehicle
     5     {
     6         //时速
     7         public int Speed { get; set; }
     8         //颜色
     9         public string Colour { get; set; }
    10         //购买价格
    11         public double Price { get; set; }
    12 
    13         /// <summary>
    14         /// 带参构造函数
    15         /// </summary>
    16         /// <param name="speed"></param>
    17         /// <param name="colour"></param>
    18         /// <param name="price"></param>
    19         public Vehicle(int speed, string colour, double price)
    20         {
    21             this.Speed = speed;
    22             this.Colour = colour;
    23             this.Price = price;
    24         }
    25     }
    26 
    27     /// <summary>
    28     /// 货车类 继承车辆类
    29     /// </summary>
    30     class Truck : Vehicle
    31     {
    32         /// <summary>
    33         /// 子类使用父类构造函数
    34         /// </summary>
    35         public Truck(int speed, string colour, double price) :
    36             base (speed,colour,price)
    37         {
    38 
    39         }
    40         ...
    41     }
    42 
    43     /// <summary>
    44     /// 轿车类 继承车辆类
    45     /// </summary>
    46     class Sedan : Vehicle
    47     {
    48         /// <summary>
    49         /// 子类使用父类构造函数
    50         /// </summary>
    51         public Sedan(int speed, string colour, double price) :
    52             base (speed,colour,price)
    53         {
    54 
    55         }
    56         ...
    57     }
    示例 : 简化的代码

        使用了继承之后,即使再多的派生类需要带参构造函数,也不怕了,只要一行代码即可完成。

        Base关键字:

          base关键字表示父类,可以用于访问父类的成员。例:base.父类成员。

          除了上面通过base显示的调用父类带参构造函数外,创建子类对象时还会隐式的调用父类的无参构造函数。(创建子类对象时

        会先调用父类的无参构造函数。)

    进一步了解和使用继承

        继承的特性:

            1.传递性:继承可以无限的向下派生,但是需要符合一个条件:子类可以出现在父类出现的地方并替换父类,即子类

               拥有父类的全部特征和能够实现父类的全部方法。

            2.单根性:一个子类只能继承自一个父类。不存在一个子类同时继承自两个或多个父类的情况。

        is a关键字:

            这个关键字用来判断对象是否属于给定的类型。返回值为bool类型。

            例:

                if (Vehicle is Truck)

                {
                    ...
                }

        sealed关键字:

            用这个关键字修饰的类是不能被继承的,即密封类。常用的string类就是密封类。本文只做了解,后更示例。

    至此,关于继承已经讲得差不多了,下面是本文用到的所有代码,希望可以帮到看到此处的你。

      1     class Program
      2     {
      3         static void Main(string[] args)
      4         {
      5             Demo demo = new Demo();
      6             demo.Test();
      7 
      8             Console.Read();
      9         }
     10     }
     11 
     12     class Demo
     13     {
     14         List<Vehicle> vehicles = new List<Vehicle>();
     15         
     16         public void Test()
     17         {
     18             vehicles.Add(new Truck(50, "蓝色", 150000));
     19             vehicles.Add(new Sedan(80, "黑色", 210000));
     20             foreach (Vehicle item in vehicles)
     21             {
     22                 if (item is Truck)
     23                 {
     24                     Console.WriteLine("我是货车,时速{0},我是{1}的,价格{2}元。", item.Speed, item.Colour, item.Price);
     25                     ((Truck)item).Cargo();
     26                 }
     27                 if (item is Sedan)
     28                 {
     29                     Console.WriteLine("我是轿车,时速{0},我是{1}的,价格{2}元。",item.Speed,item.Colour,item.Price);
     30                     ((Sedan)item).CarryPassengers();
     31                 }
     32             }
     33         }
     34     }
     35 
     36     /// <summary>
     37     /// 车辆类 父类
     38     /// </summary>
     39     class Vehicle
     40     {
     41         //时速
     42         public int Speed { get; set; }
     43         //颜色
     44         public string Colour { get; set; }
     45         //购买价格
     46         public double Price { get; set; }
     47 
     48         /// <summary>
     49         /// 带参构造函数
     50         /// </summary>
     51         /// <param name="speed"></param>
     52         /// <param name="colour"></param>
     53         /// <param name="price"></param>
     54         public Vehicle(int speed, string colour, double price)
     55         {
     56             this.Speed = speed;
     57             this.Colour = colour;
     58             this.Price = price;
     59         }
     60     }
     61 
     62     /// <summary>
     63     /// 货车类 继承车辆类
     64     /// </summary>
     65     class Truck : Vehicle
     66     {
     67         /// <summary>
     68         /// 子类使用父类构造函数
     69         /// </summary>
     70         public Truck(int speed, string colour, double price) :
     71             base (speed,colour,price)
     72         {
     73 
     74         }
     75 
     76         /// <summary>
     77         /// 货运方法
     78         /// </summary>
     79         public void Cargo()
     80         {
     81             Console.WriteLine("我能运输货物");
     82         }
     83     }
     84 
     85     /// <summary>
     86     /// 轿车类 继承车辆类
     87     /// </summary>
     88     class Sedan : Vehicle
     89     {
     90         /// <summary>
     91         /// 子类使用父类构造函数
     92         /// </summary>
     93         public Sedan(int speed, string colour, double price) :
     94             base (speed,colour,price)
     95         {
     96 
     97         }
     98         /// <summary>
     99         /// 载客方法
    100         /// </summary>
    101         public void CarryPassengers()
    102         {
    103             Console.WriteLine("我可以载客");
    104         }
    105     }
    完整代码

        

     结尾语:学到知识不与人分享,犹如衣锦夜行,毫无意义。


    2017-02-23  22:02:34补充

        as关键字:

            as关键字可以进行对象之间的类型转换,可以替代强制类型转换。和强制类型转换不同的是,使用as关键字类进行类型

            转换如果转换失败会返回null,不会产生异常;而强制类型转换在转换失败时会产生异常。

            语法:

                父类   as   子类

        重载构造函数:

            如果子类重载的构造函数没有使用base关键字来指明调用父类的哪个构造函数,则父类必须提供一个默认的构造函数。

    欢迎提出意见或建议!!!
  • 相关阅读:
    用java实现输出英文小说飘中出现次数最多的前N个单词(附:使用文件读写)
    程序员修炼之道第一章读后感
    c++实现线性表中的顺序表(数据结构课程作业)
    java第二次课件课后动手动脑习题整理总结(2019年9月23号)
    课堂练习判断字符串是否为回文序列
    大二上学期九月周总结报告三
    以java实现的一个简单登录界面(带验证码)
    关于二进制的原码 、反码、补码的简要解释说明
    几种方式使用
    spring配置数据源的6种方式
  • 原文地址:https://www.cnblogs.com/gaofei-1/p/6429915.html
Copyright © 2011-2022 走看看