C#编程,关于基类和派生类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#编程,关于基类和派生类相关的知识,希望对你有一定的参考价值。

定义一个车(vehicle)基类,具有MaxSpeed、Weight等属性,Run、Stop等方法,Run方法包含速度参数和一个超速事件。定义一个机动车接口,包括发动机启动、发动机运行(包括运行速度参数)和发动机停止方法。由车派生出自行车(bicycle)类。自行车(bicycle)类有横梁高度和两轮距离等属性,处理超速事件时提示“减少用力”,从车基类和机动车接口汽车派生车汽车类,汽车有座位数(SeatNum)等属性,处理超速事件为提示“减少动力”,有自行车类和机动车接口派生出摩托车类,具体处理自行发挥。 编写主程序处理一系列车子(多态),处理过程自行发挥,一定要有处理所有车子超速事件(通过重量判断车子是汽车、摩托车还是自动车)。

楼上的漏了事件吧。
唔........看咱写的版本吧

using System;

namespace ConsoleApplication1

public class Vehicle

public Vehicle(int maxSpeed, int weight)

_MaxSpeed = maxSpeed;
_Weight = weight;
OnOverSpeed += new OverSpeedHandler(Vehicle_OnOverSpeed);


protected virtual void Vehicle_OnOverSpeed(object sender, VehicleRunEventArgs e)

//通过重量来判断类型感觉很不好...这里在子类中重载了超速方法
Console.WriteLine("警告,1当前速度:0,已超速", e.Speed, this.GetType().Name);
//如果要按题目做,去掉子类中的重载,在这里加重量判断输出信息就行了

public int MaxSpeed get return _MaxSpeed;
protected int _MaxSpeed;
public int CurrentSpeed get return _CurrentSpeed;
protected int _CurrentSpeed;
public int Weight get return _Weight;
protected int _Weight;
public virtual void Run(int speed)

_CurrentSpeed = speed;
Console.WriteLine("1当前速度:0", _CurrentSpeed,this.GetType().Name);
if (_CurrentSpeed > MaxSpeed)

if (OnOverSpeed != null)

OnOverSpeed(this, new VehicleRunEventArgs(_CurrentSpeed));



public virtual void Stop()

_CurrentSpeed = 0;
Console.WriteLine("0已停止", this.GetType().Name);


public event OverSpeedHandler OnOverSpeed;

public delegate void OverSpeedHandler(object sender, VehicleRunEventArgs e);
public class VehicleRunEventArgs : EventArgs

public int Speed get; set;
public VehicleRunEventArgs()
Speed = 0;
public VehicleRunEventArgs(int speed)
Speed = speed;


interface MotorVehicle

void EngineStart();
void EngineRun(int speed);
void EngineStop();


public class Bicycle : Vehicle

public int CrossbarHeight get return CrossbarHeight;
private int _CrossbarHeight;
public int WheelInterval get return _WheelInterval;
private int _WheelInterval;
public Bicycle(int crossbarHeight, int wheelInterval)
: base(20, 20)

_CrossbarHeight = crossbarHeight;
_WheelInterval = wheelInterval;


protected override void Vehicle_OnOverSpeed(object sender, VehicleRunEventArgs e)

Console.WriteLine("警告,1当前速度:0,已超速,请立即减少用力", e.Speed, this.GetType().Name);



public class Car : Vehicle, MotorVehicle

public int SeatNum get; set;
public Car(int seatNum)
: base(120, 1000)

SeatNum = seatNum;


protected override void Vehicle_OnOverSpeed(object sender, VehicleRunEventArgs e)

Console.WriteLine("警告,1当前速度:0,已超速,请立即减少动力", e.Speed, this.GetType().Name);

public override void Run(int speed)

EngineRun(speed);

private bool EngineStarted get; set;
public void EngineStart()

if (!EngineStarted)

EngineStarted = true;
Console.WriteLine("0引擎启动成功", this.GetType().Name);

else

Console.WriteLine("0引擎已启动,无须重复启动", this.GetType().Name);


public void EngineRun(int speed)

if (EngineStarted)

base.Run(speed);

else

Console.WriteLine("0引擎未发动!", this.GetType().Name);


public void EngineStop()

if (EngineStarted)

EngineStarted = false;
Console.WriteLine("0引擎已关闭成功", this.GetType().Name);

else

Console.WriteLine("0引擎已关闭,无须重复关闭!", this.GetType().Name);




public class MotorBicycle : Bicycle, MotorVehicle

public MotorBicycle(int crossbarHeight, int wheelInterval)
: base(crossbarHeight, wheelInterval)

_MaxSpeed = 60;
_Weight = 80;


protected override void Vehicle_OnOverSpeed(object sender, VehicleRunEventArgs e)

Console.WriteLine("警告,1当前速度:0,已超速,请立即减少动力", e.Speed, this.GetType().Name);

public override void Run(int speed)

EngineRun(speed);

private bool EngineStarted get; set;
public void EngineStart()

if (!EngineStarted)

EngineStarted = true;
Console.WriteLine("0引擎启动成功", this.GetType().Name);

else

Console.WriteLine("0引擎已启动,无须重复启动", this.GetType().Name);


public void EngineRun(int speed)

if (EngineStarted)

base.Run(speed);

else

Console.WriteLine("0引擎未发动!", this.GetType().Name);


public void EngineStop()

if (EngineStarted)

EngineStarted = false;
Console.WriteLine("0引擎已关闭成功", this.GetType().Name);

else

Console.WriteLine("0引擎已关闭,无须重复关闭!", this.GetType().Name);





static void Main(string[] args)

Console.WriteLine("开始测试");
Vehicle MyVehicle = new Car(4);
Vehicle MyVehicle2 = new Bicycle(60, 60);
Vehicle MyVehicle3 = new MotorBicycle(80, 80);
List<Vehicle> Vehicles = new List<Vehicle>(3);
Vehicles.Add(MyVehicle);
Vehicles.Add(MyVehicle2);
Vehicles.Add(MyVehicle3);
foreach (Vehicle vehicle in Vehicles)

vehicle.Run(20);

Car MyCar = MyVehicle as Car;
MyCar.EngineStart();
MyCar.EngineStart();
MyCar.EngineRun(40);
MotorBicycle MyCar2 = MyVehicle3 as MotorBicycle;
MyCar2.EngineStart();
MyCar2.EngineStart();
MyCar2.EngineRun(50);
foreach (Vehicle vehicle in Vehicles)

vehicle.Run(80);

foreach (Vehicle vehicle in Vehicles)

vehicle.Stop();

foreach (Vehicle vehicle in Vehicles)

vehicle.Run(200);

MyCar.Stop();
MyCar.EngineStop();
MyCar.EngineStop();
MyVehicle2.Stop();
MyCar2.Stop();
MyCar2.EngineStop();
Console.ReadLine();

测试结果

开始测试
Car引擎未发动!
Bicycle当前速度:20
MotorBicycle引擎未发动!
Car引擎启动成功
Car引擎已启动,无须重复启动
Car当前速度:40
MotorBicycle引擎启动成功
MotorBicycle引擎已启动,无须重复启动
MotorBicycle当前速度:50
Car当前速度:80
Bicycle当前速度:80
警告,Bicycle当前速度:80,已超速,请立即减少用力
MotorBicycle当前速度:80
警告,MotorBicycle当前速度:80,已超速,请立即减少动力
Car已停止
Bicycle已停止
MotorBicycle已停止
Car当前速度:200
警告,Car当前速度:200,已超速,请立即减少动力
Bicycle当前速度:200
警告,Bicycle当前速度:200,已超速,请立即减少用力
MotorBicycle当前速度:200
警告,MotorBicycle当前速度:200,已超速,请立即减少动力
Car已停止
Car引擎已关闭成功
Car引擎已关闭,无须重复关闭!
Bicycle已停止
MotorBicycle已停止
MotorBicycle引擎已关闭成功
参考技术A class vehicle

private int maxspeed;
public int MaxSpeed

set;
get;

private int weight;
public int Weight

set;
get;

private void Run()

private int speed;
chaosu( speed );

public virtual string chaosu(int speed )

if(speed>=maxspeed)

respone.write("<script>alert('警告:超速行驶')</script>");



这是基类,就照着这个写吧,这是最基本的。virtual函数注意子类继承要重写
参考技术B 很麻烦

派生类和基类之间的指针到指针的转换?

【中文标题】派生类和基类之间的指针到指针的转换?【英文标题】:Conversion of pointer-to-pointer between derived and base classes? 【发布时间】:2010-03-28 09:25:32 【问题描述】:

关于以下 C++ 程序:

class Base  ;

class Child : public Base  ;

int main()
   
    // Normal: using child as base is allowed
    Child *c = new Child();
    Base *b = c;

    // Double pointers: apparently can't use Child** as Base**
    Child **cc = &c;
    Base **bb = cc;

    return 0;

GCC 在最后一个赋值语句中产生以下错误:

error: invalid conversion from ‘Child**’ to ‘Base**’

我的问题分为两部分:

    为什么没有从 Child** 到 Base** 的隐式转换? 我可以使用 C 样式转换或 reinterpret_cast 使这个示例工作。使用这些类型转换意味着抛弃所有类型安全。有什么我可以添加到类定义中以使这些指针隐式转换,或者至少以允许我使用static_cast 的方式来表达转换?

【问题讨论】:

这个问题在许多编程语言中的变化是关于 SO 的最常见问题之一。但即使是同一种语言,每个人的措辞也略有不同,因此很难找到重复的内容。 “修复”这个例子以避免阴暗的转换将取决于您首先使用指针指向指针的原因。 【参考方案1】:

如果允许,你可以这样写:

*bb = new Base;

c 最终会指向Base 的一个实例。不好。

【讨论】:

小修正 - 他可以说**bb = new Base(); 只是*bb 是不允许的。 @Phil: new 返回一个指针,类型为*Basebb 的类型为 **Base。因此*bb 是正确的取消引用级别。 原理与comp.lan.g.c关于char**char const**不等价的FAQ基本相同:c-faq.com/ansi/constmismatch.html @Dav:抱歉,我假设您将Base **bb = cc 替换为Base **bb = new Base()。不知道我从哪里得到这个想法,因为如果我这么认为,你的Base *b = new Base() 将是完全合法的。我的错! (bow) 简单明了,并为其他问题节省了今天的逻辑令人费解的配额。 :)【参考方案2】:

指针是虚拟地址。通常你要对你用它做的事情负责。使用 msvc 2019。我可以将一个转换为基础,但不能转换为两个:

example 1:

int p;
int *p1 = &p;
int **p2 = &p1; //OK

example 2:

struct xx ;
struct yy : public xx ;

yy p;
yy *p1 = &p;
xx **p2 = &p1; //Just a strange error

example 3:

struct xx ;
struct yy : public xx ;

yy p;
xx *p1 = &p; 
xx **p2 = &p1; //OK

【讨论】:

以上是关于C#编程,关于基类和派生类的主要内容,如果未能解决你的问题,请参考以下文章

关于基类和派生类之间的关系

基类和派生类

派生类和基类之间的指针到指针的转换?

生成一个派生类对象时,调用基类和派生类构造函数按啥次序

基类和派生类

派生类和基类的转换