[.net 面向对象编程基础] (15) 抽象类html
前面咱们已经使用到了虚方法(使用 Virtual修饰符)和抽象类及抽象方法(使用abstract修饰符)咱们在多态一节中说到要实现类成员的重写必须定义为一个虚方法或抽象方法。这节单独把抽象类提出来,是由于抽象是.net实现面向对象编程重要的重要思想,定义抽象类就象一个模板一个提纲,它能够理解为中央的指导思想,咱们经过派生类去具体实现它。因而可知,抽象类自己没有任何做用,也不能被实例化,由于他自己就不具备具体的事物。好比上节的动物类的例 子,咱们实例化一个动物类并无意义,咱们须要实例的类是具体的动物,好比Dog、Cat、Sheep这些。编程
而咱们使用面向对象编程,就要在具体的应用过程当中,学会抽象出事物的共同点,造成一个基类,其它类去继承他,实现他。为咱们提升编程、学习设计模式颇有益处。设计模式
1.什么是抽象类ide
若是一个类不与具体的事物相联系,而只是表达一种抽象的概念,仅仅是做为其派生类的一个基类,这样的类就是抽象类,在抽象类中声明方法时,若是加上abstract时就是抽象方法函数
1.抽象类的声明学习
抽象类使用abstract 关键词进行声明。this
2.抽象类的特色:spa
A.抽象类不能被实例化.net
B.抽象类是一种特殊的类,具备类的特性,其成员能够是抽象的,也能够不是抽象的。设计
C.抽象方法必须定义在抽象类中,而不能定义在非抽象类中
D.抽象类能够继承一个抽象类,其派生类仍然是一个抽象类
E.抽象类不能被密封(不能使用sealed(sealed指该类不可被继承))
3.抽象方法的特色:
A.抽象方法是隐式的虚方法
B.抽象方法只容许声明在抽象类中
C.抽象方法不能提供实际的实现,因此没有方法体;抽象方法的实现是在非抽象的派生类中以override重写实现的
D.抽象方法声明中不可使用static或者virtual修饰符
E.abstract关键字不能修饰静态方法或静态属性
6.抽象类的构造函数
A.不要再抽象类中定义public或protected internal访问权限的构造函数
B.应在抽象类中定义protected或private访问权限的构造函数
C.若是在抽象类中定义一个protected构造函数,则在实例化派生类时,基类能够执行初始化任务
7.抽象方法和虚方法的区别
虚方法(使用Virtual修饰符)有实现部分,而且派生类对其重写是可选的;抽象方法没有实现部分,而且强制非抽象派生类对其重写
8.抽象类和接口的区别
其实这个区别,原本是要在下一节,接口中讲的,在这里提早说一下,有点印象也好。
A.它们的派生类只能继承一个基类,即只能继承一个抽象类,可是能够继承多个接口。
B.抽象类中能够定义成员的实现,但接口中不能够。
C.抽象类中包含字段、构造函数、析构函数、静态成员或常量等,接口中不能够。
D.抽象类中的成员能够私有的(只要不是抽象的)、受保护的、内部的或受保护的内部成员,但接口中的成员必须是公共的。
PS:抽象类和接口这两种类型用于彻底不一样的目的。抽象类主要用做对象系列的基类,共享某些主要特性,例如共同的目的和结构。接口则主要用于类,这些类在基础水平上有所不一样,但仍然能够完成某些相同的任务。
7. 举例
咱们举一个例子来讲明一下抽象类的使用,仍是咱们前面的例子,基类动物(Animal),咱们定义成一个抽象类,有几个派生类狗、猫、羊,假如咱们猫还有波斯猫,狗还有牧羊犬,那么咱们还可让它们再次继承,由于猫和狗自己也是动物,咱们能够不定义为抽象类,让他们支持实例化。下面看一下UML图:
关于UML图我会在后面抽时间写的,里面的成员+表示公有,-表示私有,字段、属性、方法使用分割线
下面是具体实现代码:
1 /// <summary> 2 /// 动物类(父类 抽象类) 3 /// </summary> 4 abstract class Animal 5 { 6 /// <summary> 7 /// 名字 8 /// 说明:类和子类可访问 9 /// </summary> 10 protected string name; 11 12 13 /// <summary> 14 /// 构造函数 15 /// </summary> 16 /// <param name="name"></param> 17 public Animal(string name) 18 { 19 this.name = name; 20 } 21 22 private int shoutNum = 3; 23 public int ShoutNum 24 { 25 get { return shoutNum; } 26 set { shoutNum = value; } 27 } 28 29 /// <summary> 30 /// 名字(虚属性) 31 /// </summary> 32 public virtual string MyName 33 { 34 get { return this.name; } 35 36 } 37 38 /// <summary> 39 /// 叫声,这个方法去掉虚方法,把循环写在这里 40 /// </summary> 41 public void Shout() 42 { 43 string result = ""; 44 for (int i = 0; i < ShoutNum; i++) 45 result += getShoutSound()+"!"; 46 47 Console.WriteLine(MyName); 48 Console.WriteLine(result); 49 } 50 51 /// <summary> 52 /// 建立一个叫声的虚方法,子类重写 53 /// </summary> 54 /// <returns></returns> 55 public virtual string getShoutSound() 56 { 57 return ""; 58 } 59 60 61 } 62 63 /// <summary> 64 /// 狗(子类) 65 /// </summary> 66 class Dog : Animal 67 { 68 string myName; 69 public Dog(string name) 70 : base(name) 71 { 72 myName = name; 73 } 74 75 /// <summary> 76 /// 名字(重写父类属性) 77 /// </summary> 78 public override string MyName 79 { 80 get { return "我是:狗狗,我叫:" + this.name; } 81 } 82 83 /// <summary> 84 /// 叫(重写父类方法) 85 /// </summary> 86 public override string getShoutSound() 87 { 88 return "汪!"; 89 } 90 } 91 92 /// <summary> 93 /// 狗(子类) 94 /// </summary> 95 class ShepherdDog : Dog 96 { 97 string myName; 98 public ShepherdDog(string name): base(name) 99 { 100 myName = name; 101 } 102 103 /// <summary> 104 /// 名字(重写父类属性) 105 /// </summary> 106 public override string MyName 107 { 108 get { return "我是:牧羊犬,我叫:" + this.name; } 109 } 110 111 /// <summary> 112 /// 叫(重写父类方法) 113 /// </summary> 114 public override string getShoutSound() 115 { 116 return "汪~呜!"; 117 } 118 } 119 120 /// <summary> 121 /// 猫(子类) 122 /// </summary> 123 class Cat : Animal 124 { 125 string myName; 126 public Cat(string name) 127 : base(name) 128 { 129 myName = name; 130 } 131 /// <summary> 132 /// 名字(重写父类属性) 133 /// </summary> 134 public override string MyName 135 { 136 get { return "我是:猫咪,我叫:" + this.name; } 137 138 } 139 140 /// <summary> 141 /// 叫(重写父类方法) 142 /// </summary> 143 public override string getShoutSound() 144 { 145 return "喵!"; 146 } 147 } 148 149 /// <summary> 150 /// 猫(子类) 151 /// </summary> 152 class PersianCat : Cat 153 { 154 string myName; 155 public PersianCat(string name): base(name) 156 { 157 myName = name; 158 } 159 /// <summary> 160 /// 名字(重写父类属性) 161 /// </summary> 162 public override string MyName 163 { 164 get { return "我是:波斯猫,我叫:" + this.name; } 165 166 } 167 168 /// <summary> 169 /// 叫(重写父类方法) 170 /// </summary> 171 public override string getShoutSound() 172 { 173 return "喵~呜!"; 174 } 175 } 176 177 178 /// <summary> 179 /// 羊(子类) 180 /// </summary> 181 class Sheep : Animal 182 { 183 string myName; 184 public Sheep(string name) 185 : base(name) 186 { 187 myName = name; 188 } 189 /// <summary> 190 /// 名字(重写父类属性) 191 /// </summary> 192 public override string MyName 193 { 194 get { return "我是:羊羊,我叫:" + this.name; } 195 196 } 197 /// <summary> 198 /// 叫(重写父类方法) 199 /// </summary> 200 public override string getShoutSound() 201 { 202 return "咩!"; 203 } 204 }
调用及结果以下:
//调用 Animal persianCat = new PersianCat("好猫"); persianCat.Shout(); Console.ReadLine();
//结果以下: //我是:波斯猫,我叫:好猫 //喵~呜!!喵~呜!!喵~呜!!
10要点:
抽象类是指:一个类不与具体的事物相联系,而只是表达一种抽象的概念,仅仅是做为其派生类的一个基类。
抽象类是一种特殊类,使用abstract声明
抽象类不可被实例化
抽象类能够继承一个抽象类
抽象方法只能存在于抽象类中,能够和虚方法同样,在派生类中重写。
抽象类的存在就是被继承用的,所以不容许被密封(即不能使用sealed修饰)
最后,抽象,是面向对象程序设计的重要思想。。
==============================================================================================
返回目录
<若是对你有帮助,记得点一下推荐哦,有不明白的地方或写的不对的地方,请多交流>
==============================================================================================