如何理解C#中的override和new,看了很多博客和文章,從中收獲了不少關於繼承和多態的知識。但是理解層面還不夠深入,不入本質。
但是,對象以及繼承和多態,往往都是和現實世界類比而成的。它們源於現實世界,而高於之。我們何嘗不從現實世界入手,對其實現機制進行類比。用我們比較熟悉的方式去理解呢?
見如下代碼:
[csharp]
01.namespace ClassLibrary1
02.{
03. public class Teacher
04. {
05. public virtual void Paper()
06. {
07. Console.Write("老師出試卷");
08. }
09. }
10. public class S1 : Teacher
11. {
12. public override void Paper()
13. {
14. Console.WriteLine("S1做試卷");
15. }
16. }
17. public class S2 : S1
18. {
19. public override void Paper()
20. {
21. Console.WriteLine("S2重寫了S1的試卷");
22. }
23. }
24. public class S3 : S2
25. {
26. public new void Paper()
27. {
28. Console.WriteLine("S3並沒有重寫S2的試卷,而是自己重新new了試卷");
29. }
30. }
31.}
32.
33.namespace ConsoleApplication1
34.{
35. class Program
36. {
37. static void Main(string[] args)
38. {
39.
40. Teacher t = new Teacher();
41. t.Paper(); //老師出試卷
42. S1 s1 = new S1();
43. s1.Paper(); //S1做試卷
44. S2 s2 = new S2();
45. s2.Paper(); //S2重寫了S1的試卷
46. S3 s3 = new S3();
47. s3.Paper(); //S3並沒有重寫S2的試卷,而是自己重新new了試卷
48.
49. t = s3;
50. t.Paper();//!!S2重寫了S1的試卷
51.
52. t = s2;
53. t.Paper();//S2重寫了S1的試卷
54.
55. t = s1;
56. t.Paper();//S1做試卷
57.
58.
59. }
60. }
61.}
namespace ClassLibrary1
{
public class Teacher
{
public virtual void Paper()
{
Console.Write("老師出試卷");
}
}
public class S1 : Teacher
{
public override void Paper()
{
Console.WriteLine("S1做試卷");
}
}
public class S2 : S1
{
public override void Paper()
{
Console.WriteLine("S2重寫了S1的試卷");
}
}
public class S3 : S2
{
public new void Paper()
{
Console.WriteLine("S3並沒有重寫S2的試卷,而是自己重新new了試卷");
}
}
}
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Teacher t = new Teacher();
t.Paper(); //老師出試卷
S1 s1 = new S1();
s1.Paper(); //S1做試卷
S2 s2 = new S2();
s2.Paper(); //S2重寫了S1的試卷
S3 s3 = new S3();
s3.Paper(); //S3並沒有重寫S2的試卷,而是自己重新new了試卷
t = s3;
t.Paper();//!!S2重寫了S1的試卷
t = s2;
t.Paper();//S2重寫了S1的試卷
t = s1;
t.Paper();//S1做試卷
}
}
}
分析:為什麼t=s3,t.Paper()顯示結果是S2重寫了S1的試卷呢?因為這個引用t是Teacher類的,所以先從Teacher類找到Paper()這個方法,然後發現被重寫,所以又找到S1的Paper(),然後發現其又被重寫,所以,繼續往下走,找到了S2的Paper()。到此處,發現Paper()沒有被重新,所以停止。所以使用override會找到被重寫的最遠的一個方法。通俗講:老師出了出卷,同學A做了,然後同學B在A的基礎上又做了修改...同學n在n-1的基礎上又做了修改。所以最後的試卷肯定是第n個童鞋的結果哦。但是new方法只是重新又寫了自己的試卷而已。只有通過S3 s3=new S3(),s3.Paper().才能看到自己做的結果。即通過自己的引用處理自己的對象。如何理解C#中的override和new,看了很多博客和文章,從中收獲了不少關於繼承和多態的知識。但是理解層面還不夠深入,不入本質。
但是,對象以及繼承和多態,往往都是和現實世界類比而成的。它們源於現實世界,而高於之。我們何嘗不從現實世界入手,對其實現機制進行類比。用我們比較熟悉的方式去理解呢?
見如下代碼:
[csharp]
01.namespace ClassLibrary1
02.{
03. public class Teacher
04. {
05. public virtual void Paper()
06. {
07. Console.Write("老師出試卷");
08. }
09. }
10. public class S1 : Teacher
11. {
12. public override void Paper()
13. {
14. Console.WriteLine("S1做試卷");
15. }
16. }
17. public class S2 : S1
18. {
19. public override void Paper()
20. {
21. Console.WriteLine("S2重寫了S1的試卷");
22. }
23. }
24. public class S3 : S2
25. {
26. public new void Paper()
27. {
28. Console.WriteLine("S3並沒有重寫S2的試卷,而是自己重新new了試卷");
29. }
30. }
31.}
32.
33.namespace ConsoleApplication1
34.{
35. class Program
36. {
37. static void Main(string[] args)
38. {
39.
40. Teacher t = new Teacher();
41. t.Paper(); //老師出試卷
42. S1 s1 = new S1();
43. s1.Paper(); //S1做試卷
44. S2 s2 = new S2();
45. s2.Paper(); //S2重寫了S1的試卷
46. S3 s3 = new S3();
47. s3.Paper(); //S3並沒有重寫S2的試卷,而是自己重新new了試卷
48.
49. t = s3;
50. t.Paper();//!!S2重寫了S1的試卷
51.
52. t = s2;
53. t.Paper();//S2重寫了S1的試卷
54.
55. t = s1;
56. t.Paper();//S1做試卷
57.
58.
59. }
60. }
61.}
namespace ClassLibrary1
{
public class Teacher
{
public virtual void Paper()
{
Console.Write("老師出試卷");
}
}
public class S1 : Teacher
{
public override void Paper()
{
Console.WriteLine("S1做試卷");
}
}
public class S2 : S1
{
public override void Paper()
{
Console.WriteLine("S2重寫了S1的試卷");
}
}
public class S3 : S2
{
public new void Paper()
{
Console.WriteLine("S3並沒有重寫S2的試卷,而是自己重新new了試卷");
}
}
}
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Teacher t = new Teacher();
t.Paper(); //老師出試卷
S1 s1 = new S1();
s1.Paper(); //S1做試卷
S2 s2 = new S2();
s2.Paper(); //S2重寫了S1的試卷
S3 s3 = new S3();
s3.Paper(); //S3並沒有重寫S2的試卷,而是自己重新new了試卷
t = s3;
t.Paper();//!!S2重寫了S1的試卷
t = s2;
t.Paper();//S2重寫了S1的試卷
t = s1;
t.Paper();//S1做試卷
}
}
}
分析:為什麼t=s3,t.Paper()顯示結果是S2重寫了S1的試卷呢?因為這個引用t是Teacher類的,所以先從Teacher類找到Paper()這個方法,然後發現被重寫,所以又找到S1的Paper(),然後發現其又被重寫,所以,繼續往下走,找到了S2的Paper()。到此處,發現Paper()沒有被重新,所以停止。所以使用override會找到被重寫的最遠的一個方法。通俗講:老師出了出卷,同學A做了,然後同學B在A的基礎上又做了修改...同學n在n-1的基礎上又做了修改。所以最後的試卷肯定是第n個童鞋的結果哦。但是new方法只是重新又寫了自己的試卷而已。只有通過S3 s3=new S3(),s3.Paper().才能看到自己做的結果。即通過自己的引用處理自己的對象。