创造一辆“汽车”类使用加速方法,并将窗体上的加速和减速按钮与创建的类关联
本文关键字:加速 窗体 创建 关联 按钮 方法 一辆 汽车 创造 | 更新日期: 2023-09-27 18:15:41
用c#。Net类,我们已经引入了一个使用类和表单的新概念。这是一门在线课程,基本上老师会给我们一些指导,但是有些不清楚,至少对我来说是这样。不幸的是,他对学生问题的回答非常模糊,简单地说,就是让我们自己想办法,所以我才来这里。下面是老师给我们的。
=========================================================================
UML: Model: String, CurrentSpeed: Decimal, TopSpeed: Decimal, and Accelerate(更改速度:Decimal)
Accelerate将changspeed(可为正、负或0)添加到CurrentSpeed。CurrentSpeed不能超过TopSpeed或小于0例如,如果CurrentSpeed为10,dChangeSpeed为-20,CurrentSpeed变为0
一般要求:
- 最高速度组合框填满数字60,70,80 ....200(运行时)
- 改变速度组合框填满数字1,2,3 ....200(运行时)
- 用户必须从组合框中选择(不能输入自己的号码)
按钮动作要求:
Accelerate对于同一型号,通过改变速度增加当前速度对于新模型,将当前速度设置为更改速度(当前速度不能超过最高速度)
减速对于同一型号,通过改变速度降低当前速度对于新模型,将当前速度设置为0(当前速度不能低于0)
精确地遵循UML图。在课堂上完成的工作(计算等),而不是在表格上。
=========================================================================
好的,所以我的问题是,我应该在课堂上使用减速方法,以及加速方法吗?我假设每个按钮(减速,加速)都需要在类中有自己的方法。但是我觉得我把这个问题弄得太复杂了,这是我问老师的一个问题的答案。我想我完全难住了如何引用类,特别是加速与形式。
到目前为止,这是我想到的,我知道这大多是错误的,然而,这是一个初学者的课程,从我被告知和教师的支持是不存在的,除了依赖于一个关于类的章节。
public class Car
{
// Backing Fields (Instance Variables)
private string _model;
private int _currentSpeed;
private int _topSpeed;
public int SpeedResult;
// Set Parameters
public Car()
{
this.Model = "";
this.CurrentSpeed = 0;
this.TopSpeed = 0;
}
// Constructor
public Car(string Model, int CurrentSpeed, int TopSpeed)
{
_model = Model;
_currentSpeed = CurrentSpeed;
_topSpeed = TopSpeed;
}
// Model Property
public string Model
{
get { return _model; }
set { _model = value; }
}
// Current Speed Property
public int CurrentSpeed
{
get { return _currentSpeed; }
set { _currentSpeed = value; }
}
// Top Speed Property
public int TopSpeed
{
get { return _topSpeed; }
set { _topSpeed = value; }
}
// Methods
public int Accelerate()
{
SpeedResult = (TopSpeed + CurrentSpeed);
return SpeedResult;
}
//
public void clear()
{
Model = "";
CurrentSpeed = 0;
TopSpeed = 0;
}
}
形式:
public partial class carSpeedForm : Form
{
private Car _myCar;
private int SpeedResult;
public carSpeedForm()
{
_myCar = new Car();
InitializeComponent();
}
private void carSpeedForm_Load(object sender, EventArgs e)
{
// Loads Amount ComboBox with values from 60 to 200 in increments of 10
for (int i = 60; i <= 200; i += 10)
topSpeedComboBox.Items.Add(i);
// Loads Amount ComboBox with values from 1 to 200 in increments of 1
for (int i = 1; i <= 200; i += 1)
changeSpeedComboBox.Items.Add(i);
}
private void GetCarData()
{
try
{
_myCar.Model = carModelTextBox.Text;
_myCar.TopSpeed = int.Parse(topSpeedComboBox.Text);
_myCar.CurrentSpeed = int.Parse(changeSpeedComboBox.Text);
}
catch
{
MessageBox.Show(string.Concat("Please enter a valid model and speed(s) for vehicle.","'r'n"));
}
}
private void accelButton_Click(object sender, EventArgs e)
{
GetCarData();
speedResultLabel.Text = SpeedResult.ToString("n1");
carResultLabel.Text = String.Format("Your car is a new car.");
}
private void decelButton_Click(object sender, EventArgs e)
{
GetCarData();
speedResultLabel.Text = SpeedResult.ToString("n1");
carResultLabel.Text = String.Format("Your car is a new car.");
}
private void clearButton_Click(object sender, EventArgs e)
{
//Clear textbox, combobox, labels
carModelTextBox.Clear();
carModelTextBox.Focus();
topSpeedComboBox.SelectedIndex = -1;
changeSpeedComboBox.SelectedIndex = -1;
speedResultLabel.Text = "";
carResultLabel.Text = "";
}
private void exitButton_Click(object sender, EventArgs e)
{
//Close application
this.Close();
}
}
你的代码不仅不是"大部分是错的",我甚至认为它大部分是对的。不清楚您究竟在问什么,或者"如何引用类"是什么意思。老师告诉你"to figure out"是对的,我们不能帮你做作业。如果你有工作代码,你想让人们审查,把它发布到代码审查网站。
但是,根据我的经验,有一些代码气味会在将来导致问题:
// Backing Fields (Instance Variables)
不要注释编程术语;它们没有贡献任何东西,而且很快就会与代码不同步。只注释不能用编程语言表达的东西。
private string _model;
// Model Property
public string Model
{
get { return _model; }
set { _model = value; }
}
这大概是定义属性最冗长的方式了。定义单独的后备字段只会鼓励人们使用后备字段而不是属性。此外,将其设置为public
使该类的任何消费者都能够随时更改该属性。有时候你需要这些东西,但除非你绝对需要,否则你不应该允许他们。此外,像"Model"这样模糊的名称很难理解,特别是当其他类使用它们时。更好的定义应该是:
public string ModelName { get; private set; }
:
public int SpeedResult;
这是什么?它不在您的UML中,并且从不用于任何事情。而且,它是public
所以任何东西都可以把它变成任何东西;没用的,把它扔掉。
// Set Parameters
public Car()
{
this.Model = "";
this.CurrentSpeed = 0;
this.TopSpeed = 0;
}
然后在表单构造函数中:
_myCar = new Car();
这比无用更糟糕;您正在创建不包含数据的实例,并且每个字段都是公共的,因此任何东西都可以将您的数据更改为任何东西。c#允许你强制实例只包含有效的数据。使用它们,并且只在知道其数据时创建实例。你应该只有一个这样的Car
构造函数:
public Car(string modelName, float topSpeed)
{
if (string.IsNullOrWhiteSpace(modelName)) throw new ArgumentNullException("modelName");
ModelName = modelName;
TopSpeed = topSpeed;
}
我假设CurrentSpeed
是可变的,所以你可能不应该在构造函数中定义它;它是我警告过你的public
属性之一的候选。
public int Accelerate()
{
SpeedResult = (TopSpeed + CurrentSpeed);
return SpeedResult;
}
为什么要把TopSpeed
加到CurrentSpeed
?这可以使SpeedResult
大于TopSpeed
。为什么你的速度是int
s?您的描述称它们为"十进制",但c# decimal
类型用于定点值。float
是更好的选择。
你的问题是"Accelerate添加changspeed…"到CurrentSpeed…CurrentSpeed不能超过TopSpeed或小于0"。
public void Accelerate(float changeSpeed)
{
var predictedSpeed = CurrentSpeed + changeSpeed;
if (predictedSpeed > TopSpeed)
CurrentSpeed = TopSpeed;
else if (predictedSpeed < 0)
CurrentSpeed = 0;
else
CurrentSpeed = predictedSpeed;
}
:
public void clear()
{
Model = "";
CurrentSpeed = 0;
TopSpeed = 0;
}
再一次,你允许任何东西破坏你的数据。不要那样做;如果您需要创建一个新车,那么创建一个new Car
。如果不想显示汽车,就不要创建汽车。
你的carSpeedForm
也有问题,但我看到米高梅正在解决这些问题。
看了你写的描述,看起来你基本上掌握了这个概念。从您的表单中,我假设您将选择一种汽车类型?如果是这种情况,您基本上希望在Car类中定义所有模型(Car)行为。例如,正如您已经做过的那样,您希望为选定的汽车数据和Accelerate和减速方法定义访问器。这样,在视图(carSpeedForm)中,当相应的按钮被按下时,就可以调用透视图方法。例如,如果用户按下表单上的Accelerate按钮,您将调用Car实例的Accelerate方法。希望这对你有所帮助。你说的没错。
应该使用按钮和输入控件将数据存储在your_myCar实例中。例如
public partial class CarForm : Form
{
private Car theCar;
private bool modelChanged;
public CarForm()
{
theCar = new Car();
InitializeComponent();
loadChangeSpeed_cb();
loadTopSpeed_cb();
modelChanged = false;
}
private void loadChangeSpeed_cb()
{
for (decimal i = 1; i <= 200; i++)
{
changeSpeed_cb.Items.Add(i);
}
}
private void loadTopSpeed_cb()
{
for(decimal i = 60; i <= 200; i+=10)
{
topSpeed_cb.Items.Add(i);
}
}
private void accel_b_Click(object sender, EventArgs e)
{
if(modelChanged)
{
theCar.CurrentSpeed = theCar.ChangeSpeed;
modelChanged = false;
}
else
{
var si = changeSpeed_cb.SelectedItem;
if (si == null)
{
return;
}
theCar.Accelerate((decimal)si);
}
}
private void decel_b_Click(object sender, EventArgs e)
{
if(modelChanged)
{
theCar.CurrentSpeed = 0;
modelChanged = false;
return;
}
else
{
var si = changeSpeed_cb.SelectedItem;
if (si == null)
{
return;
}
theCar.Accelerate(-(decimal)si);
}
}
private void topSpeed_cb_SelectedIndexChanged(object sender, EventArgs e)
{
var si = topSpeed_cb.SelectedItem;
if(si == null)
{
return;
}
theCar.TopSpeed = (decimal)si;
}
private void changeSpeed_cb_SelectedIndexChanged(object sender, EventArgs e)
{
var si = changeSpeed_cb.SelectedItem;
if (si == null)
{
return;
}
theCar.ChangeSpeed = (decimal)changeSpeed_cb.SelectedItem;
}