在C#中实现多态的方法:虚方法,抽象类和接口。
1.虚方法实现多态:在父类中写一个虚的(virtual)的方法,然后再在子类中重写(override)这个父类中的虚方法。;
注意:虚方法实现多态中,父类中的virtual方法是有具体实现的。并且父类也是可以被实例化的。
2.抽象类实现多态:将父类和父类中的方法写为一个抽象的(abstract) ,然后再在子类中重写(override)父类中的抽象方法。
注意:在抽象类中的抽象方法是不能有任何实现的。并且抽象类也是不能进行实例化的。
【抽象类的一些特点:】1.抽象成员必须标记为abstract,并且不能有任何实现。
2.抽象成员必须在抽象类中。
3.抽象类是不能被实例化的。
4.子类继承抽象类后,必须把父类中的全部抽象方法进行重写。(除非子类也是抽象类,则可以不重写。)
5.抽象成员前面的访问修饰符不为pirvate.
6.在抽象类中可以有实例成员。并且抽象类中的实例成员可以不被实现。
7.抽象类中是可以写构造函数的,但是没有意义,因为抽象类是不能被实例化的,也就是不能new,也就不能调用构造函数。
8.如果父类中的抽象方法有参数,那么在继承抽象父类的子类中在重写父类的方法的时候也必须传入对应的参数。
9.如果父类中的抽象方法有返回值,那么在继承抽象父类的子类中在重写父类的抽象方法的时候也必须有相应的返回值。
【什么时候使用抽象类?什么时候使用虚方法:】
1.当父类的方法有实现,并且父类需要被实例化的,那么就需要用虚方法实现多态。
2.如果父类中的方法么有默认实现。并且父类不需要被实例化,那么就可以考虑使用抽象类来实现多态。
简而言之:如果父类需要被实例化,那么就考虑使用虚方法来实现多态;如果父类不需要被实例化,那么就可以考虑使用抽象类来实现多态。
//抽象类实现多态的实例:模拟移动硬盘、MP3、U盘插入电脑读取数据的过程:
1.首先抽象出一个移动存储设备的抽象父类。在这个中定义了读写数据等抽象方法。
2.定义一个电脑类,根据当前“插入”(传入的实例参数)电脑类的对象来调用这个对象的读写的方法。(此时有两个方法实现:1.在电脑类中调用其他对象方法的时候传入一个对象的参数。2.在电脑类中定义一个移动设备父类的属性。根据这个属性的值来调用相应的对象的读写的一些方法。)
【这个例子实现的是在一个类中,根据另一个父类类型的属性的值,来调用另一父类子类中的一些实际的方法。】
//父类
///
/// 移动存储设备
///
public abstract class MoveStorageDevice
{
///
/// 抽象的移动存储设备读的方法
///
public abstract void Read();
///
/// 移动存储设备写的方法
///
public abstract void Write();
///
/// 移动存储设别恢复数据的方法
///
public abstract void DataRecvoery();
}
///
/// 硬盘类
///
public class Disk : MoveStorageDevice
{
public override void Read()
{
Console.WriteLine("移动硬盘读取数据...");
}
public override void Write()
{
Console.WriteLine("移动硬盘写入数据....");
}
public override void DataRecvoery()
{
Console.WriteLine("移动硬盘恢复数据");
}
}
///
/// MP3类
///
public class MP3 : MoveStorageDevice
{
public override void Read()
{
Console.WriteLine("MP3读取数据...");
}
public override void Write()
{
Console.WriteLine("MP3写入数据...");
}
public void PlayMusic()
{
Console.WriteLine("MP3还会播放Music");
}
public override void DataRecvoery()
{
Console.WriteLine("MP3恢复数据");
}
}
///
/// U盘类
///
public class UDisk : MoveStorageDevice
{
public override void Read()
{
Console.WriteLine("U盘读取数据");
}
public override void Write()
{
Console.WriteLine("U盘写入数据");
}
public override void DataRecvoery()
{
Console.WriteLine("U盘恢复数据");
}
}
///
/// 手机类
///
public class MobilePhone : MoveStorageDevice
{
public override void Read()
{
Console.WriteLine("手机读取数据");
}
public override void Write()
{
Console.WriteLine("手机写入数据");
}
public override void DataRecvoery()
{
Console.WriteLine("手机恢复数据");
}
}
//电脑类:可以根据插入的是哪个设备来具体的调用这个设备的读写的方法 (这个类中调其他几个有继承关系的类的对象的一些方法,传入的属性的类型是父类的类型。)
public class Computer
{
///
/// 移动存储设备的属性
///
public MoveStorageDevice MSD { get; set; }
//调用插入设备读的方法
///
/// 调用插入设备的 读的方法
///
public void CPTRead()
{
MSD.Read();
}
//调用插入设备写的方法
///
/// 调用插入设备的 写的方法
///
public void CPTWrite()
{
MSD.Write();
}
///
/// 调用插入设备恢复设计的方法
///
///
public void CPTRecoveryData()
{
MSD.DataRecvoery();
}
}
static void Main(string[] args)
{
///在主函数实例化电脑类,根据其属性传入相应的父类类型的对象。
Disk disk = new Disk();
MP3 mp3 = new MP3();
UDisk udisk = new UDisk();
MobilePhone mb = new MobilePhone();
//创建电脑类
Computer cmp = new Computer();
cmp.MSD = mb;//udisk;//mp3;//disk;
cmp.CPTRead();
cmp.CPTWrite();
cmp.CPTRecoveryData();
Console.ReadKey();
}