当前位置:首页 > Windows程序 > 正文

C#面向对象核心之二:继承

2021-03-28 Windows程序

面向对象的三大特性之一的封装,解决了将对同一对象所能操作的所有信息放在一起,实现统一对外调用,,实现了同一对象的复用,降低了耦合。

但在实际应用中,有好多对象具有相同或者相似的属性,比如有一个对象 果树(FruitTree),它有成员属性叶子(Leaf),会开花(Flower),有树干(Stem),有树根(Root),它还会生长(Growth方法)。

有另一个对象苹果树(AppleTree)它也是果树,具有果树所有特性,那么我们在编程的时候,定义了一个苹果树对象,假如再有一个桔子树(OrangeTree)、桃树(PeachTree)呢,我们不能一直复制这个对象改名字实现吧?这里就要用到面向对象的第二个特性:继承。

1.什么是继承

上面的果树(FruitTree) 和桔树(OrangeTree)之间是一个“ is-a ”的关系,即我们可以说 “桔树是果树”。在面向对象编程中,我们把这种关系称为 “继承”,即桔树继承自果树。或者说,桔树类是果树类的派生类;也可以说果树是父类,桔树是子类。同样的苹果树也可以继承果树,那么苹果树也可以说是果树的子类。在这里我们发现一个类可以有多个派生类,也就是一个类可以被多个类继承.

继承相关的概念:

(1) 当一个类A能够获取另一个类B中所有非私有的数据和操作的定义作为自己的部分或全部成分时,就称这两个类之间具有继承关系。

(2) 被继承的类B称为父类或基类,继承了父类的类A称为子类或派生类.

2.继承的特点

上面的例子,假如苹果树继承自果树,那么苹果树除了具有果树所有的属性(叶子,根、花)和方法(生长)之外,苹果树还有自己特有的一些属性,比如有自己的果实苹果(Apple); 同样桃树有自己的果实桃子(Peach),因此继承的子类可以有自己独有的成员(属性或方法等)。

特点一:派生类除了继承父类的特性外,还可以有自己独有特性

上面说到的父类果树(FruitTree)除了有叶子、根、花这些公有的成员之外,也可以有自己的私有成员,比如种类(落叶果树、常绿果树),而“种类”这个成员,并不是它的子类苹果树(AppleTree)和桔树(OrangeTree)所具有的,因此是私有成员,子类继承父类后,并不能拥有父类的私有成员。

特点二:子类不能拥有父类的私有成员

还是上面的例子,假如果树有一个公有方法生长(Growth),它有两个子类桃树和苹果树,那么子类也同时拥有生长这个方法,但是桃树和苹果树的生长过程是不同的,我们可以修改这个方法以适应不同种类果树的生长。

特点三:子类可以以自己的方式实现父类的功能(即方法重写)

3.继承的实现

通过上面的例子,我们已经对继承很熟悉了,抛开概念。简单的说,继承一词本就来源于生活,有财产继承,精神继承。面向对象编程只不过就是把这些概念抽象化而已,通俗来说就是“苹果树是一颗果树”   

代码实现上面的例子   

1 /// <summary> 2 /// 果树类 3 /// </summary> 4 class FruitTree 5 { 6 /// <summary> 7 /// 名称 8 /// 说明:修饰符 protected 保护访问。只限于本类和子类访问,实例不能访问。 9 /// </summary> 10 protected string name; 11 /// <summary> 12 /// 构造函数 13 /// </summary> 14 public FruitTree() 15 { 16 this.name = "无名"; 17 } 18 /// <summary> 19 /// 构造函数二 20 /// </summary> 21 /// <param></param> 22 public FruitTree(string name) 23 { 24 this.name = name; 25 } 26 object _leaf; 27 object _root; 28 object _flower; 29 string _type; 30 /// <summary> 31 /// 叶子(公有属性) 32 /// </summary> 33 public object leaf 34 { 35 get { return _leaf; } 36 set { _leaf = value; } 37 } 38 /// <summary> 39 /// 根(公有属性) 40 /// </summary> 41 public object root 42 { 43 get { return _root; } 44 set { _root = value; } 45 } 46 /// <summary> 47 /// 花(公有属性) 48 /// </summary> 49 public object flower 50 { 51 get { return _flower; } 52 set { _flower = value; } 53 } 54 /// <summary> 55 /// 类别(不定义修饰符,默认为私有) 56 /// </summary> 57 string type 58 { 59 get { return _type; } 60 set { _type = value; } 61 } 62 63 } 64 65 /// <summary> 66 /// 苹果树类 67 /// 继承自:果树类 68 /// </summary> 69 class AppleTree:FruitTree 70 { 71 string _myName; 72 /// <summary> 73 /// 构造函数 74 /// 说明:子类调用父类同样的构造函数,需要使用 :base() 75 /// </summary> 76 public AppleTree():base() 77 { 78 } 79 /// <summary> 80 /// 构造函数二 81 /// 说明:子类调用父类同样的构造函数,需要使用 :base(name) 82 /// </summary> 83 /// <param></param> 84 public AppleTree(string name):base(name) 85 { 86 _myName = name; 87 } 88 89 /// <summary> 90 /// 返回果实的名字 91 /// </summary> 92 /// <returns></returns> 93 public string MyFruitName() 94 { 95 return "我是:" + _myName + ";我的果实叫:苹果"; 96 } 97 } 98 /// <summary> 99 /// 桔树类 100 /// 继承自:果树类 101 /// </summary> 102 class OrangeTree : FruitTree 103 { 104 string _myName; 105 /// <summary> 106 /// 构造函数 107 /// 说明:子类调用父类同样的构造函数,需要使用 :base() 108 /// </summary> 109 public OrangeTree(): base() 110 { 111 } 112 /// <summary> 113 /// 构造函数二 114 /// 说明:子类调用父类同样的构造函数,需要使用 :base(name) 115 /// </summary> 116 /// <param></param> 117 public OrangeTree(string name): base(name) 118 { 119 _myName = name; 120 } 121 122 /// <summary> 123 /// 返回果实的名字 124 /// </summary> 125 /// <returns></returns> 126 public string MyFruitName() 127 { 128 return "我是:"+_myName+";我的果实叫:桔子"; 129 } 130 }

调用子类:

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/69140.html