C#面向对象的概念 ----继承,里氏转换和几种集合(1)

我们知道面向对象的三个特征,封装,继承和多态。我们前面已经学习了如何封装在类中封装方法。现在我们系统学习什么是继承。

我们下面写几个类:student teacher driver几个类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 草稿1
 8 {
 9     public class Student
10     {
11         private string _name;
12         public string Name
13         {
14             get { return _name; }
15             set { _name = value; }
16         }
17 
18         private int _age;
19         public int Age
20         {
21             get { return _age; }
22             set { _age = value; }
23         }
24 
25         private char _gender;
26         public char Gender
27         {
28             get { return _gender; }
29             set { _gender = value; }
30         }
31 
32         private int _id;
33         public int Id
34         {
35             get { return _id; }
36             set { _id = value; }
37         }
38 
39         public void CHLSS()
40         {
41             Console.WriteLine("吃喝拉撒睡");
42         }
43         public void Study()
44         {
45             Console.WriteLine("学生会学习");
46         }
47     }
48 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 草稿1
 8 {
 9     public class Teacher
10     {
11         private string _name;
12         public string Name
13         {
14             get { return _name; }
15             set { _name = value; }
16         }
17 
18         private int _age;
19         public int Age
20         {
21             get { return _age; }
22             set { _age = value; }
23         }
24 
25         private char _gender;
26         public char Gender
27         {
28             get { return _gender; }
29             set { _gender = value; }
30         }
31 
32         private double _salary;
33         public double Salary
34         {
35             get { return _salary; }
36             set { _salary = value; }
37         }
38 
39         public void CHLSS()
40         {
41             Console.WriteLine("吃喝拉撒睡");
42         }
43         public void Teach()
44         {
45 
46             Console.WriteLine("老师会讲课");
47         }
48     }
49 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 草稿1
 8 {
 9     public class Driver
10     {
11         private string _name;
12         public string Name
13         {
14             get { return _name; }
15             set { _name = value; }
16         }
17 
18         private int _age;
19         public int Age
20         {
21             get { return _age; }
22             set { _age = value; }
23         }
24 
25         private char _gender;
26         public char Gender
27         {
28             get { return _gender; }
29             set { _gender = value; }
30         }
31 
32         private int _driveTime;
33         public int DriveTime
34         {
35             get { return _driveTime; }
36             set { _driveTime = value; }
37         }
38 
39         public void CHLSS()
40         {
41             Console.WriteLine("吃喝拉撒睡");
42         }
43 
44         public void Drive()
45         {
46             Console.WriteLine("司机会开车");
47         }
48 
49     }
50 }

我们会发现这几个类中成员有重复的,方法有重复的,这时我们把这几个类中重复成员单独拿出来,封装一个类,作为这几个类的

父类。所以我们改造如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 草稿1
 8 {
 9     public class Person
10     {
11         private string _name;
12         public string Name
13         {
14             get { return _name; }
15             set { _name = value; }
16         }
17 
18         private int _age;
19         public int Age
20         {
21             get { return _age; }
22             set { _age = value; }
23         }
24 
25         private char _gender;
26         public char Gender
27         {
28             get { return _gender; }
29             set { _gender = value; }
30         }
31 
32         public void CHLSS()
33         {
34             Console.WriteLine("吃喝拉撒睡");
35         }
36     }
37 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 草稿1
 8 {
 9     public class Driver:Person
10     {
11         private int _driveTime;
12         public int DriveTime
13         {
14             get { return _driveTime; }
15             set { _driveTime = value; }
16         }
17         public void Drive()
18         {
19             Console.WriteLine("司机会开车");
20         }
21 
22     }
23 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 草稿1
 8 {
 9     public class Teacher:Person
10     {
11         private double _salary;
12         public double Salary
13         {
14             get { return _salary; }
15             set { _salary = value; }
16         }
17 
18         public void Teach()
19         {
20 
21             Console.WriteLine("老师会讲课");
22         }
23     }
24 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 草稿1
 8 {
 9     public class Student:Person
10     {
11         private int _id;
12         public int Id
13         {
14             get { return _id; }
15             set { _id = value; }
16         }
17         public void Study()
18         {
19             Console.WriteLine("学生会学习");
20         }
21     }
22 }

我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类。

首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。

引出:子类有没有继承父类的构造函数?

子类并没有继承父类的构造函数。但是,子类会默认调用父类无参数的构造函数。创建父类对象,让子类可以使用父类中的成员。

所以,如果父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,所以子类会报错。

解决办法:1.再父类中重新写一个无参数的构造函数。

          2.在子类中显示的调用父类的构造函数,使用关键字:base()

继承的特性

1.继承的单根性:一个子类只能有一个父类。

2.继承的传递性:

New关键字

1)创建对象

2)隐藏从父类那里继承过来的同名成员。隐藏后果就是子类调用不到父类成员。

 


里氏转换

1)子类可以赋值给父类。如果有一个地方需要一个父类作为参数,我们可以给一个子类代替。

2)如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。

子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。

类型转换判断的两个关键字

(1)is:表示类型转换,如果能够转换成功,则返回一个true,否则返回一个false。

(2)as:表示类型转换,如果能够转换则返回对应的对象,否则返回一个null。

下面我们做一个综合练习:为了方便观察代码,我们将各种类写到了program类中

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 namespace 草稿1
  8 {
  9     class Program
 10     {
 11         static void Main(string[] args)
 12         {
 13             //创建10个对象,通过一个循环,去调用他们各自打招呼的方法
 14             Person[] pers = new Person[10];
 15             Random r = new Random();
 16             for (int i = 0; i < pers.Length; i++)
 17             {
 18                 int rNumber = r.Next(1,7);
 19                 switch (rNumber)
 20                 {
 21                     case 1:pers[i] = new Student();
 22                         break;
 23                     case 2:
 24                         pers[i] = new Teacher();
 25                         break;
 26                     case 3:
 27                         pers[i] = new ShuaiGuo();
 28                         break;
 29                     case 4:
 30                         pers[i] = new MeiLv();
 31                         break;
 32                     case 5:
 33                         pers[i] = new YeShou();
 34                         break;
 35                     case 6:
 36                         pers[i] = new Person();
 37                         break;
 38                         
 39                 }
 40             }
 41 
 42             for (int i = 0; i < pers.Length; i++)
 43             {
 44                 if (pers[i] is Student)
 45                 {
 46                     ((Student)pers[i]).StudentSayHi();
 47                 }
 48                 else if (pers[i] is Teacher)
 49                 {
 50                     ((Teacher)pers[i]).TeacherSayHi();
 51                 }
 52                 else if (pers[i] is MeiLv)
 53                 {
 54                     ((MeiLv)pers[i]).MeiLvSayHi();
 55                 }
 56                 else if (pers[i] is ShuaiGuo)
 57                 {
 58                     ((ShuaiGuo)pers[i]).ShuaiGuoSayHi();
 59                 }
 60                 else if (pers[i] is YeShou)
 61                 {
 62                     ((YeShou)pers[i]).YeShouSayHi();
 63                 }
 64                 else 
 65                 {
 66                     pers[i].PersonSayHi();
 67                 }
 68             }
 69             Console.ReadKey();
 70         }
 71     }
 72 
 73     public class Person
 74     {
 75         public void PersonSayHi()
 76         {
 77             Console.WriteLine("我是人类");
 78         }
 79     }
 80 
 81     public class Student:Person
 82     {
 83         public void StudentSayHi()
 84         {
 85             Console.WriteLine("我是学生");
 86         }
 87     }
 88 
 89     public class Teacher : Person
 90     {
 91         public void TeacherSayHi()
 92         {
 93             Console.WriteLine("我是老师");
 94         }
 95     }
 96 
 97     public class MeiLv : Person
 98     {
 99         public void MeiLvSayHi()
100         {
101             Console.WriteLine("我是美铝");
102         }
103     }
104 
105     public class ShuaiGuo : Person
106     {
107         public void ShuaiGuoSayHi()
108         {
109             Console.WriteLine("我是帅锅");
110         }
111     }
112 
113     public class YeShou : Person
114     {
115         public void YeShouSayHi()
116         {
117             Console.WriteLine("我是野兽");
118         }
119     }
120 }

 

关键字protected:

受保护的:可以在当前类的内部以及该类的子类中访问。

 

 


 

两个集合ArrayList和HashTable

ArrayList集合我数组对比:

数组:长度不可变,类型单一

集合:长度任意改变,类型多元化。

 

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace 草稿1
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             ArrayList list = new ArrayList();
15 
16             list.Add(1);
17             list.Add(3.14);
18             list.Add(true);
19             list.Add("张三");
20             list.Add();
21             list.Add(5000m);
22 
23             for (int i = 0; i < list.Count; i++)
24             {
25                 Console.WriteLine(list[i]);
26             }
27             Console.ReadKey();
28         }
29     }
30 }

 

ArrayList集合的几个方法:

list.addRange():添加集合元素。

list.Clear():清空所有元素。

list.Remove():删除单个元素,写谁就删谁。

list.RemoveAt():根据下标删除元素。

list.RemoveRange():根据下标删除一定范围的元素

list.Sort():升序排列

list.Reverse():反转

list.Insert():在指定的位置插入一个元素。

list.InsertRange():在指定位置插入一定范围的元素。

list.Contains():判断是否包含某个指定的元素。

ArrayList集合长度问题

每次集合中实际包含的元素个数(count)超过了可以包含的元素的个数(capcity)的时候,集合就会像内存中申请多开辟一倍的

空间,来保证集合的长度一直够用。

 

HashTable键值对集合

在键值对集合当中,我们是根据键去找值的。

键值对对象[键]=值;

注意:键值对集合当中,键必须是唯一的,而值是可以重复的。

 

下面我们讨论一下我们如何能够遍历HashTable集合的所有元素,我们一提到便利元素,肯定会想到使用for循环,但是HashTable集合中

键的类型是object,所以可能不是值类型,而且foreach循环的运行效率要比for循环的高,所以我们不能使用for循环,这时我们可以使用foreach。

 

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace 草稿1
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             Hashtable ht = new Hashtable();
15             ht.Add(1,"张三");
16             ht.Add(2,true);
17             ht.Add(3,);
18             ht.Add(false,"错误的");
19 
20             foreach (var item in ht.Keys)
21             {
22                 Console.WriteLine(ht[item]);
23             }
24             Console.ReadKey();
25         }
26     }
27 }

 

我们除了使用foreach循环添加数据,也可以使用赋值的方法添加数据。这种方式也可以把相同键值的值覆盖掉。

键值对对象[键]=value;

键值对集合常用方法:

ht.ContainsKey();判断是否包含键。

ht.Add():添加键值对元素。

ht.Clear();清空所有元素。

ht.Remove():移除键所对应的元素。

 


 

学习几个重要的类

Path类:

Path.Get FileName():获得文件名。

Path.GetFileNameWithoutExtension():获得文件名但是不包括扩展名。

Path.GetExtension():获得文件的扩展名。

Path.GetDirectoryName():获得文件所在的文件夹的名称。

Path.GetFullPath():获得文件所在的全路径。

Path.Combine():链接两个字符串作为路径。

File类:

File.Create():创建一个文件。

File.Delete():删除一个文件。

File.Copy():复制一个文件。

C#面向对象的概念 ----继承,里氏转换和几种集合(1)

上一篇:C# 二分法的解读


下一篇:win10 指纹无法登记