目录
1.抽象类的概念和定义
抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
在C#中,抽象类可以包含:抽象方法、抽象属性、具体方法和具体属性。
1.1 定义
访问修饰符 abstract class 类名
{
访问修饰符 abstract 返回值类型 方法名(参数列表); //定义抽象方法
其他类成员;
}
抽象类的定义类似于普通类,只不过在访问修饰符后加入abstract。
1.2 抽象方法
// 抽象方法
public abstract double GetName();
// 抽象属性
public abstract string Name { get; }
抽象类中需要加入抽象方法,而抽象方法只需要声明,也就是抽象方法的内容是不用写的,只需要一个空方法。有点类似于C++在头文件中定义方法时,可以只是一个声明,不提供方法体,而在.C文件中才实现该函数。
1.3 重写抽象方法
访问修饰符 class 派生类的类名 : 基类的类名
{
访问修饰符 override 返回值类型 方法名(参数列表)
{
方法体;
}
其他类成员;
}
在子类继承自基类后,需要重写抽象方法,否则编译器会报错。只需要在方法的访问修饰符后加入override即可。
1.4 抽象类和具体类的区别
(1)抽象类不能实例化,具体类能实例化
(2)抽象类中不一定要有抽象方法,具体类中不能有抽象方法。
(3)抽象类可以和具体类一样,有具体方法。
(4)抽象类可以继承抽象类,子类如果不是抽象类,则必须重写抽象类中的全部抽象方法。
(5)在抽象类中,不能用private修饰抽象方法,因为抽象方法要被子类重写。
(6)在以下情况,一个类将成为抽象类:
<1>当一个类的一个或多个方法是抽象方法。
<2>当类是一个抽象类的子类,但是不能为任何抽象方法提供任何实现细节或方法实体。
<3>当一个类实现一个接口,但是不能为任何抽象方法提供任何实现细节或方法实体。
1.5 多态
根据抽象类,可以总结多态为一下几点:
(1)使用基类类型的引用指向子类的对象,但是该引用只能调用父类定义的方法和变量。
(2)如果派生类重写了基类的方法,那么派生类调用该方法时会调用派生类自己的方法(动态链接、动态调用)。
(3)一个类型引用只能引用类型自身含有的方法和变量。
2. 实现的案例
2.1 例子
// pet抽象类
public abstract class Pet //基类,抽象类,定义宠物类
{
public String Name { get; set; } //宠物名字
public String Gender { get; set; } //宠物性别
public int Health { get; set; } //宠物健康值
public abstract void ToHospital(); //看病方法
public abstract void Eat();
}
// Dog具体类
class Dog : Pet //派生类,定义小狗类
{
public override void ToHospital() //重写看病方法
{
Console.WriteLine("打针、吃药");
}
public override void Eat() //重写看病方法
{
Console.WriteLine("吃狗粮!");
}
}
// Cat具体类
public class Cat : Pet //派生类,定义猫咪类
{
public override void ToHospital() //重写看病方法
{
Console.WriteLine("输液、疗养");
}
public override void Eat() //重写看病方法
{
Console.WriteLine("吃猫粮!");
}
}
// Doctor
class Doctor //定义医生类
{
public void Cure(Pet pet) //治疗方法
{
if (pet.Health < 50)
{
pet.ToHospital();
pet.Health = 60;
}
}
}
// 主函数
class Program
{
static void Main(string[] args)
{
Pet pet;
Dog dog;
pet = new Dog();
dog = pet as Dog;
if (dog != null)
{
dog.Eat();
}
else
{
Console.WriteLine("转换失败了!!!");
}
}
}
pet = new Dog();使用基类对象指向派生类对象,派生类对象转换为基类对象,是安全的转换,也就是向上转换类型,一般是隐式转换。
对于基类中定义的方法,如果派生类中重写了该方法,那么基类类型的引用将会调用派生类中的这个方法,这就是多态。
使用基类对象指向派生类对象,那么该基类对象可以指向任意一个派生类对象,可以随意切换,非常方便。
2.2 向下转换
派生类对象 = (派生类名)基类对象;
但是,当将基类对象转换为派生类对象,向下转换时,是很不安全的。为此默认情况下,进行向下转型时,往往会发生编译错误。然而,有时候确实需要强制转换,这时候就需要异常处理。
3. 异常处理
3.1 try-catch
try
{
Pet pet = new Cat();
Dog d = (Dog)pet;
}
catch
{
Console.WriteLine(“类型转换出错!");
}
Cat和Dog都是pet的派生类,当然不能互相转换,类型转换出错。
3.2 使用as和is
//使用 as
Dog dog = pet as Dog
if(dog==null)
Console.WriteLine(“转换不成功!”);
//使用 is
pet = new Cat();
if (pet is Dog)
{
dog = (Dog)pet;
dog.Eat();
}
else
{
Console.WriteLine("不是Dog的实例");
}
使用is和as,再进行强制转换,这样能够更加安全地进行转换,转换错误后程序能继续运行下去,不用抛出异常。