繼承
我們可能會在一些類別中,寫一些重複的成員,我們可以將這些重複的成員,單獨的封裝到一個類別中,作為這些類別的父類。
Student, Teacher, Driver 子類 派生類
Person 父類 基類
1
2
3
4
5
public class Person { ... } //父類 基類
public class Student: Person { ... } //子類 派生類
public class Teacher : Person { ... }
public class Driver : Person { ... }
Q:子類繼承了父類,那麼子類從父類那邊繼承過來了什麼?
首先,子類繼承了父類的屬性和方法,但是子類並沒有繼承父類的私有字段。
Q:子類有沒有繼承父類的構造函數?
子類沒有繼承父類的構造函數,
但是,子類會默認的調用父類的無參數的構造函式,創建父類物件,讓子類可以使用父類中的成員,
所以,如果在父類中重寫了一個有參數的構造函式之後,那麼無參數的構造函式就會被幹掉了,子類就調用不到了,所以子類會報錯。
Q:為什麼會報錯?
因為建立物件的時候,new 會做三件事:
- 在Heap(堆積)中開闢空間。
- 在開闢的空間中,創建物件。
- 調用物件的構造函式。
建立子類物件的時候,會先建立父類的物件
子類報錯 解決方法:
- 在父類中重新寫一個無參數的構造函數。(一般不這麼做)
- 在子類中的有參數的構造函式中,調用父類的構造函式,使用關鍵字
:base()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//子類 派生類
public class Student : Person
{
public Student(string name, int age, char gender, int score)
: base(name, age, gender) //調用父類的構造函式,使用關鍵字 ":base()"
{
//不用寫,因為有調用Person的有參構造函式
//this.Name = name;
//this.Age = age;
//this.Gender = gender;
this.Score = score;
}
private int _score;
public int Score
{
get { return _score; }
set { _score = value; }
}
//...
}
//父類 基類
public class Person
{
//public Person() { }
public Person(string name, int age, char gender)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
}
//....
}
練習:
1
2
記者(reporter):我是記者,我的愛好是偷拍,我年齡34 ,是一個男狗仔。
程式員(programmer):我叫小帥,我23歲 ,我是男生,工作3年。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
Reporter reporter = new Reporter("老李", 40, '男', "偷拍");
reporter.SayHello();
Programmer programmer = new Programmer("小帥", 26, '男', 3);
programmer.SayHello();
Console.ReadKey();
public class Person
{
public Person(string name, int age, char gender)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
private char _gender;
public char Gender
{
get { return _gender; }
set { _gender = value; }
}
}
public class Reporter : Person
{
public Reporter(string name, int age, char gender, string hobby)
: base(name, age, gender)
{
this.Hobby = hobby;
}
private string _hobby; //喜好
public string Hobby
{
get { return _hobby; }
set { _hobby = value; }
}
public void SayHello()
{
Console.WriteLine($"Hello, 我叫{this.Name},今年{this.Age}歲,是{this.Gender}生,喜好{this.Hobby}");
}
}
public class Programmer : Person
{
public Programmer(string name, int age, char gender, int workYear)
: base(name, age, gender)
{
this.WorkYear = workYear;
}
private int _workYear;
public int WorkYear
{
get { return _workYear; }
set { _workYear = value; }
}
public void SayHello()
{
Console.WriteLine($"Hello, 我叫{this.Name},今年{this.Age}歲,是{this.Gender}生,工作{this.WorkYear}年");
}
}
object 是所有類別的基類
在C#中,所有的類別都直接或間接的繼承了object類,當我們定義一個類別的時候,如果沒有繼承一個類別,那麼這個類就是繼承了 object類。