C# 继承
继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。
当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可。这个已有的类被称为的基类,这个新的类被称为派生类。
继承的思想实现了 属于(IS-A) 关系。例如,哺乳动物 属于(IS-A) 动物,狗 属于(IS-A) 哺乳动物,因此狗 属于(IS-A) 动物。
一、基类和派生类
一个类可以派生自多个类或接口,这意味着它可以从多个基类或接口继承数据和函数。
C# 中创建派生类的语法如下:
1 2 3 4 5 6 7 8 9 |
<acess-specifier> class <base_class> { ... } class <derived_class> : <base_class> { ... } |
假设,有一个基类 Shape
,它的派生类是 Rectangle
:
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 |
<span class="hljs-keyword">using</span> System; <span class="hljs-keyword">namespace</span> <span class="hljs-title">InheritanceApplication</span> { <span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span> { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setWidth</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> w</span>) </span>{ width = w; } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setHeight</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> h</span>) </span>{ height = h; } <span class="hljs-keyword">protected</span> <span class="hljs-keyword">int</span> width; <span class="hljs-keyword">protected</span> <span class="hljs-keyword">int</span> height; } <span class="hljs-comment">// 派生类</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span>: <span class="hljs-title">Shape</span> { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getArea</span>() </span>{ <span class="hljs-keyword">return</span> (width * height); } } <span class="hljs-keyword">class</span> <span class="hljs-title">RectangleTester</span> { <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>) </span>{ Rectangle Rect = <span class="hljs-keyword">new</span> Rectangle(); Rect.setWidth(<span class="hljs-number">5</span>); Rect.setHeight(<span class="hljs-number">7</span>); <span class="hljs-comment">// 打印对象的面积</span> Console.WriteLine(<span class="hljs-string">"总面积: {0}"</span>, Rect.getArea()); Console.ReadKey(); } } } |
当上面的代码被编译和执行时,它会产生下列结果:
1 2 |
总面积: <span class="hljs-number">35</span> |
二、基类的初始化
派生类继承了基类的成员变量和成员方法。因此父类对象应在子类对象创建之前被创建。您可以在成员初始化列表中进行父类的初始化。
下面的程序演示了这点:
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 |
<span class="hljs-keyword">using</span> System; <span class="hljs-keyword">namespace</span> <span class="hljs-title">RectangleApplication</span> { <span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> { <span class="hljs-comment">// 成员变量</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">double</span> length; <span class="hljs-keyword">protected</span> <span class="hljs-keyword">double</span> width; <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Rectangle</span>(<span class="hljs-params"><span class="hljs-keyword">double</span> l, <span class="hljs-keyword">double</span> w</span>) </span>{ length = l; width = w; } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">GetArea</span>() </span>{ <span class="hljs-keyword">return</span> length * width; } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>() </span>{ Console.WriteLine(<span class="hljs-string">"长度: {0}"</span>, length); Console.WriteLine(<span class="hljs-string">"宽度: {0}"</span>, width); Console.WriteLine(<span class="hljs-string">"面积: {0}"</span>, GetArea()); } }<span class="hljs-comment">//end class Rectangle </span> <span class="hljs-keyword">class</span> <span class="hljs-title">Tabletop</span> : <span class="hljs-title">Rectangle</span> { <span class="hljs-keyword">private</span> <span class="hljs-keyword">double</span> cost; <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Tabletop</span>(<span class="hljs-params"><span class="hljs-keyword">double</span> l, <span class="hljs-keyword">double</span> w</span>) : <span class="hljs-title">base</span>(<span class="hljs-params">l, w</span>) </span>{ } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">GetCost</span>() </span>{ <span class="hljs-keyword">double</span> cost; cost = GetArea() * <span class="hljs-number">70</span>; <span class="hljs-keyword">return</span> cost; } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>() </span>{ <span class="hljs-keyword">base</span>.Display(); Console.WriteLine(<span class="hljs-string">"成本: {0}"</span>, GetCost()); } } <span class="hljs-keyword">class</span> <span class="hljs-title">ExecuteRectangle</span> { <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>) </span>{ Tabletop t = <span class="hljs-keyword">new</span> Tabletop(<span class="hljs-number">4.5</span>, <span class="hljs-number">7.5</span>); t.Display(); Console.ReadLine(); } } } |
当上面的代码被编译和执行时,它会产生下列结果:
1 2 3 4 5 |
长度: <span class="hljs-number">4.5</span> 宽度: <span class="hljs-number">7.5</span> 面积: <span class="hljs-number">33.75</span> 成本: <span class="hljs-number">2362.5</span> |
三、C# 多重继承
多重继承指的是一个类别可以同时从多于一个父类继承行为与特征的功能。与单一继承相对,单一继承指一个类别只可以继承自一个父类。
C# 不支持多重继承。但是,您可以使用接口来实现多重继承。下面的程序演示了这点:
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 |
using System; namespace InheritanceApplication { class Shape { public void setWidth(int w) { width = w; } public void setHeight(int h) { height = h; } protected int width; protected int height; } // 基类 PaintCost public interface PaintCost { int getCost(int area); } // 派生类 class Rectangle : Shape, PaintCost { public int getArea() { return (width * height); } public int getCost(int area) { return area * 70; } } class RectangleTester { static void Main(string[] args) { Rectangle Rect = new Rectangle(); int area; Rect.setWidth(5); Rect.setHeight(7); area = Rect.getArea(); // 打印对象的面积 Console.WriteLine("总面积: {0}", Rect.getArea()); Console.WriteLine("油漆总成本: ${0}" , Rect.getCost(area)); Console.ReadKey(); } } } |
当上面的代码被编译和执行时,它会产生下列结果:
1 2 |
总面积: <span class="hljs-number">35</span> 油漆总成本: $<span class="hljs-number">2450</span> |