欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#面向对象之继承

程序员文章站 2022-04-15 08:17:28
一、继承 什么是继承?继承是两个或多个类之间存在的依赖关系,其中被继承的类称为父类或基类,继承的类称为子类或派生类。在继承关系中,父类是对子类的共性提取,子类是对父类的扩展。 上面设计的文字类和图片类中存在代码冗余,为了去除冗余,我通过提取共性的方式引入了第三个类,并让其他两个类继承它,代码如下: ......

一、继承

  什么是继承?继承是两个或多个类之间存在的依赖关系,其中被继承的类称为父类或基类,继承的类称为子类或派生类。在继承关系中,父类是对子类的共性提取,子类是对父类的扩展。

 1 /// <summary>
 2 /// 文字
 3 /// </summary>
 4 public class word
 5 {
 6     /// <summary>
 7     /// 内容
 8     /// </summary>
 9     public string content { get; set; }
10     /// <summary>
11     /// 大小(单位b)
12     /// </summary>
13     public int size { get; set; }
14 
15     public word() { }
16     public word(string content, int size)
17     {
18         this.content = content;
19         this.size = size;
20     }
21 }
22 /// <summary>
23 /// 图片
24 /// </summary>
25 public class picture
26 {
27     /// <summary>
28     /// 内容
29     /// </summary>
30     public string content { get; set; }
31     /// <summary>
32     /// 大小(单位b)
33     /// </summary>
34     public int size { get; set; }
35     /// <summary>
36     /// 地址
37     /// </summary>
38     public string path { get; set; }
39 
40     public picture() { }
41     public picture(string content, int size, string path)
42     {
43         this.content = content;
44         this.size = size;
45         this.path = path;
46     }
47 
48     /// <summary>
49     /// 图片存储到文件中,并为path赋值
50     /// </summary>
51     public void storetofile()
52     {
53 
54     }
55 }

上面设计的文字类和图片类中存在代码冗余,为了去除冗余,我通过提取共性的方式引入了第三个类,并让其他两个类继承它,代码如下:

 1 /// <summary>
 2 /// 信息
 3 /// </summary>
 4 public class information
 5 {
 6     /// <summary>
 7     /// 内容
 8     /// </summary>
 9     public string content { get; set; }
10     /// <summary>
11     /// 大小(单位b)
12     /// </summary>
13     public int size { get; set; }
14 
15     public information() { }
16     public information(string content, int size)
17     {
18         this.content = content;
19         this.size = size;
20     }
21 }
22 /// <summary>
23 /// 文字
24 /// </summary>
25 public class word : information
26 {
27     public word() { }
28     public word(string content, int size)
29     {
30         this.content = content;
31         this.size = size;
32     }
33 }
34 /// <summary>
35 /// 图片
36 /// </summary>
37 public class picture : information
38 {
39     /// <summary>
40     /// 地址
41     /// </summary>
42     public string path { get; set; }
43 
44     public picture() { }
45     public picture(string content, int size, string path)
46     {
47         this.content = content;
48         this.size = size;
49         this.path = path;
50     }
51 
52     /// <summary>
53     /// 图片存储到文件中,并为path赋值
54     /// </summary>
55     public void storetofile()
56     {
57 
58     }
59 }
60 /// <summary>
61 /// 实现对象
62 /// </summary>
63 public class realizeobject
64 {
65     public realize()
66     {
67         //word类和picture类继承information类后,information类的content和size属性就像word类和picture类的属性一样
68         word word = new word("book", 4);
69         picture picture = new picture("", 0, @"c:\users\images\");
70         information info = new information("this is info", 12);
71     }
72 }

通过继承连接文字/图片类和它们提取共性的信息类,实现了代码的复用性,后期如果加上音频类和视频类也可以通过继承复用信息类的代码,而不用重复编写content和size属性。

 

继承的规则:

1、子类可以继承除了父类构造函数之外的所有非私有成员。

2、子类的任意构造函数调用之前会先调用父类的默认构造函数。

3、子类的可访问性不能高于父类,因为这样会强制父类的可访问性同子类的可访问性(比如word用public修饰,information用internal修饰)。

4、c#不允许类的多重继承,即一个类只能有一个直接父类(继承引号符后面只能写一个类)。

 

二、c#关键字:base

  继承的规则一说明子类无法使用父类的构造函数,所以我在文字类和图片类中创建了自己的构造函数。继承的规则二说明子类只能隐式地调用父类的默认构造函数,而无法调用父类的非默认构造函数,即无法复用父类的非默认构造函数,所以可以通过base关键字使子类的构造函数自定义调用父类的非默认构造函数。下面修改文字类和图片类使其复用父类的非默认构造函数:

 1 /// <summary>
 2 /// 文字
 3 /// </summary>
 4 public class word : information
 5 {
 6     public word() { }
 7     public word(string content, int size) : base(content, size);
 8 }
 9 /// <summary>
10 /// 图片
11 /// </summary>
12 public class picture : information
13 {
14     /// <summary>
15     /// 地址
16     /// </summary>
17     public string path { get; set; }
18 
19     public picture() { }
20     public picture(string content, int size, string path)
21         : base(content, size)
22     {
23         this.path = path;
24     }
25 
26     /// <summary>
27     /// 图片存储到文件中,并为path赋值
28     /// </summary>
29     public void storetofile()
30     {
31 
32     }
33 }

base关键字除了可以复用父类非默认构造函数之外,还可以复用父类的其他非私有成员(见c#多态)。

总结:base关键字的使用方式同this关键字一样,区别在于this关键字指向本类,base关键字指向父类。

 

三、c#关键字:sealed

  sealed关键字可以防止被继承或者被重写。

1 /// <summary>
2 /// 视频类(不能被其他类继承)
3 /// </summary>
4 public sealed class video : information { }

  注:sealed在防止被继承时多用于工具类。

  sealed防止被重写(见c#多态)。

 

四、c#关键字:protected

  protected是专门用于继承中的访问修饰符,修饰在父类的成员上使其成员可被本类及其子类访问。

  注:protected多用于修饰父类的方法。

  访问修饰符直白对比:对全世界开放,使用public;只对本国开放,使用internal;只对家族开放,使用protected;只有自己知道,使用private。

 

五、类型之间的关系:包含

  c#五大类型(类、接口、委托、枚举、结构)之间的相互嵌套即包含关系。既可以包含已定义类型也可以直接在被包含类型内定义类型。

  包含的作用同继承一样也是提高代码的复用性。

 1 /// <summary>
 2 /// 洗衣机类
 3 /// </summary>
 4 public class washingmachine
 5 {
 6 
 7 }
 8 /// <summary>
 9 /// 房间类
10 /// </summary>
11 public class house
12 {
13     /// <summary>
14     /// 房间类包含已定义的洗衣机类
15     /// </summary>
16     public washingmachine washingmachine { get; set; }
17 
18     /// <summary>
19     /// 直接在房间类中定义空调类
20     /// </summary>
21     public class airconditioner
22     {
23 
24     }
25 
26     /// <summary>
27     /// 直接在房间类中定义性别枚举
28     /// </summary>
29     public enum sex { man, woman }
30 }