//抽象类具体例子
namespace Example027
{
class Program
{
static void Main(string[] args)
{
//报错
//Vehicle v = new Vehicle();
Vehicle v = new RaceCar();
v.Run(); //事实上v.Stop()可以使用
}
}
//有抽象方法必须得有抽象类
abstract class Student
{
//抽象方法没有方法体 且 必须继承给子类(不能是private)
abstract public void Study();
}
}
- 抽象类专为基类而生
namespace Example027
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Car is running...");
}
}
abstract class Vehicle
{
public void Stop()
{
Console.WriteLine("Stopped!");
}
public void Fill()
{
Console.WriteLine("Pay and fill...");
}
public abstract void Run()
{
//不会直接调用这个方法,所以这个方法会用抽象类表达
//Console.WriteLine("Vehicle is running...");
}
}
class Car:Vehicle
{
public override void Run()
{
Console.WriteLine("Car is running...");
}
}
class Truck:Vehicle
{
public override void Run()
{
Console.WriteLine("Truck is running...")
}
}
}
- 接口
//接口
interface VehicleBase
{
//接口里得方法必须是纯抽象类(就是没有方法体),以及必须是public,所以这两个都可以去掉
//abstract public void Stop();
void Stop();
void Fill();
void Run();
}
接口与单元测试
- 接口的产生:自底向上(重构),自顶向下(设计)
- C#中接口的实现(隐式,显式,多接口)
//接口的实际运用
namespace InterfaceExample
{
class Program
{
static void Main(string[] args)
{
//求总数和平均值,如果没有接口,则需要写4个方法
int[] nums1 = new int[]{1,2,3,4,5};
ArrayList nums2 = new ArrayList{1,2,3,4,5};
Console.WriteLine(Sum(nums1));
Console.WriteLine(Avg(nums1));
Console.WriteLine(Sum(nums2));
Console.WriteLine(Sum(nums2));
}
//这里的IEnumerable相当于下面的IPhone,调用一个实例(抽象出来的),就可以完成相同操作。
static int Sum(IEnumerable nums)
{
int sum=0;
foreach(var n in nums)
sum += (int)n;
return sum;
}
static double Avg(IEnumerable nums)
{
int sum=0;
double count = 0;
foreach(var n in nums)
{
sum += (int)n;
count++;
}
return sum/count;
}
}
}
接口的具体例子
将具体手机又抽象出一个类
namespace MyLib.MyNamespace2
{
internal class Program
{
static void Main(string[] args)
{
var user = new PhoneUser(new NokiaPhone());
user.UsePhone();
}
//接口
interface IPhone
{
void Dail();
void PickUp();
void Send();
void Receive();
}
//依赖关系(松耦合关系)
class PhoneUser
{
private IPhone _phone;
//一个接口实例
public PhoneUser(IPhone phone) !!!!!!最重要的一步
{
_phone = phone;
}
public void UsePhone()
{
_phone.Dail();
_phone.PickUp();
_phone.Send();
_phone.Receive();
}
}
class NokiaPhone : IPhone
{
public void Dail()
{
Console.WriteLine("Nokia calling...");
}
public void PickUp()
{
Console.WriteLine("Hello! This is Tim!");
}
public void Receive()
{
Console.WriteLine("Nokia message ring...");
}
public void Send()
{
Console.WriteLine("Hello!");
}
}
class EricssonPhone : IPhone
{
public void Dail()
{
Console.WriteLine("Ericsson calling...");
}
public void PickUp()
{
Console.WriteLine("Hello! This is Tim!");
}
public void Receive()
{
Console.WriteLine("Ericsson message ring...");
}
public void Send()
{
Console.WriteLine("Good Evening!");
}
}
}
}
- 接口继承接口具体例子(一个接口可以有多个基接口、一个类只能有一个接口)
解释:tank不属于IVehicle里面,但是又想只改变实例化对象
namespace MyLib.MyNamespace2
{
public class Program
{
static void Main(string[] args)
{
var driver = new Driver(new HeavyTank());
driver.Drive();
}
}
class Driver
{
private IVehicle _vehicle;
public Driver(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void Drive()
{
_vehicle.Run();
}
}
interface IVehicle
{
void Run();
}
class Car : IVehicle
{
public void Run()
{
Console.WriteLine("Car is running...");
}
}
class Truck : IVehicle
{
public void Run()
{
Console.WriteLine("Truck is running...");
}
}
interface IWeapon
{
void Fire();
}
//一个接口对多个接口的继承
interface ITank:IVehicle,IWeapon
{
/*
void Fire();
void Run();
*/
}
class LightTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!");
}
public void Run()
{
Console.WriteLine("ka ka ka......");
}
}
class MediumTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!!");
}
public void Run()
{
Console.WriteLine("ka! ka! ka!......");
}
}
class HeavyTank : ITank
{
public void Fire()
{
Console.WriteLine("Boom!!!");
}
public void Run()
{
Console.WriteLine("ka!! ka!! ka!!......");
}
}
}
抽象类与接口练习
总结:如果是静态类的集合可以使用接口,如果内部有一起用的属性,那么可以使用抽象类
internal class Program
{
// 使用接口输出老师和学生的姓名,工号,性别
static void Main()
{
Teacher teacher = new Teacher() { name = "a",NO = 1,sex=gender.woman.ToString()};
Student student = new Student() { name = "b",NO = 2,sex=gender.man.ToString()};
teacher.OutInformation();
student.OutInformation();
Console.ReadKey();
}
public abstract class IInformation
{
public string name;
public int NO;
public string sex;
abstract public void OutInformation();
}
enum gender { man, woman };
class Teacher : IInformation
{
public override void OutInformation()
{
Console.WriteLine($"我是一个Teacher,我叫{name},工号是{NO},性别是{sex}");
}
}
class Student : IInformation
{
public override void OutInformation()
{
Console.WriteLine($"我是一个Student,我叫{name},工号是{NO},性别是{sex}");
}
}
}