一、抽象类
前面使用 virtual 修饰方法时(表明预计子类会有重写),父类方法中也需要有内容
例如
public virtual void shout()
{
//需要些动物叫的动作
}
但是,实际运行过程中,每个动物都有自己的叫声,需要重构。也就是说,动物叫是永远运行不到的。这时候就引入 abstract 关键字。
当使用abstract 关键字修饰父类方法时,无需再方法体中写内容,也就是一个抽象方法,并没有实际内容。
当子类进行继承时候,会提醒子类进行重写此方法!
注意:当类中有抽象的方法,则该类必须用abstract定义
例如
//注意:当类中有抽象的方法,则该类必须用abstract定义
abstract class Animal
{
//定义抽象方法
abstract void Shout();
}
Class Dog : Animal
{
//实现抽象方法Shout(),**此时重写必须得有,不然编译报错,起到提醒作用**
public override void Shout()
{
//汪汪
}
}
二、接口( I 开头,如 Ifly )
当一个类中所有方法都是抽象的,则可以把该类定义为接口
定义成接口的好处为:继承时虽然只能继承一个父类,但是可以继承多个接口
例如动物类定义为接口:
interface Animal
{
void Breathe();
void Run();
}
此时定义方法更为简便,abstract都不用谢了
接口的实际应用:
当有许多动物,有的会飞有的不会,有的会游泳有的不会。
可以将飞定义为接口,里面有飞的各种属性方法,例如翅膀颜色、羽毛种类、飞行速度高度等等。游泳也是一样。
此时定义鸟时就可以继承动物以及飞的接口,如:
Class Bird : Animal ,Ifly
{
//在这里就需要定义(重写) Ifly 中的所有方法、属性
}
当有一个需求:需要判断哪个动物会飞时,就可以用接口进行判断
//用List装各种动物
List<Animal> animalList = new List<Animal>();
animalList.Add( bird );
animalList.Add( dog );
animalList.Add( fish );
animalList.Add( cat );
//For循环来判断谁会飞
for( int i = 0; i < animalList.Count; i++ ) {
if( animalList[ i ] is Ifly ) {
MessageBox.Show( animalList[ i ].Name.ToString() + " can fly" );
}
else if( animalList[ i ] is Iswim ) {
MessageBox.Show( animalList[ i ].Name.ToString() + " can swim" );
}
else {
MessageBox.Show( animalList[ i ].Name.ToString() + " can do noting" );
}
}
注意:接口中定义的方法默认会用 public 修饰,不需要加。
三、try catch
注意:不要滥用!
3.1抓取异常的信息,例:
try
{
//有可能报错的内容
}
//catch 的 () 中加上有可能异常的类型 + 引数,就可以接受异常信息。
catch ( DivideByZeroException e)
{
Console.WriteLine( "已处理异常信息:" + e.Message );
}
一般用法:
try
{
//有可能报错的内容
}
//catch 的 () 中加上有可能异常的类型 + 引数,就可以接受异常信息。
catch ( DivideByZeroException e)
{
Console.WriteLine( "已处理异常信息:" + e.Message );
}
catch ( IOException e)
{
Console.WriteLine( "已处理异常信息:" + e.Message );
}
catch (SystemException e)
{
Console.WriteLine( "已处理异常信息:" + e.Message );
}
catch (Exception e)
{
Console.WriteLine( "已处理异常信息:" + e.Message );
}
上面的 DivideByZeroException 和 IOException 是同一级别的, SystemException 是它们的父类异常,写catch 必须写在 DivideByZeroException 和 IOException 后面。同样的 Exception 必须写在 SystemException后面 。
详细层级关系见 P147
3.2 finally
若有 finally ,则表示不管 try catch 进入的是哪里,finally 都会执行,一般用来进行资源释放
如当有异常时,在catch通常会return,此时catch后代码便不会执行,就需要用 finally 来释放资源(如关闭文件传输等)
四、对标准方法重写
如
try {
HappenUnknowException();
}
//此处的 UnknowException 为自己定义的异常类型,并不是系统标准的,但是 我又要用和系统的一样 error.Message
catch( UnknowException error) {
MessageBox.Show( error.Message );
}
void HappenUnknowException()
{
//throw 关键字用来抛出异常
throw new UnknowException("123");
}
解决:
方法1、
class UnknowException : SystemException
{
//直接给传值给父类的构造函数
public UnknowException( string exception ): base( exception )
{
}
}
方法2、
class UnknowException : SystemException
{
public UnknowException( string exception )
//: base( exception )
{
Message = exception;
}
public new string Message
{
get;
set;
}
}
五、命名空间
当两个类需要同样的名字,解决办法:在解决方案管理器中 右键项目 →添加→ 新建文件夹 在新建的文件夹中新建同名类。同名类的命名空间可以用"."的形式表示为“下一层级”形式
如:Practice.CAT2 ,另一个类的命名空间可以写Practice.CAT1,调用时直接在前面写上对应的命名空间就可以了。
namespace Practice.CAT2
{
//public function and value
partial class Cat : Animal
{
public override string Shout()
{
return Name + " Miao";
}
}
//pravite functiong and value
partial class Cat
{
}
}