我已经用C#(以及其他一些语言)进行了一段时间的编程,但最近我决定开始编写自定义类以更好地理解面向对象编程。为此,我开始使用Vehicle的基类和一些派生类来处理继承。
我在这里尝试做的是在Vehicle的基础calss中设置一些默认值和逻辑,同时让派生类实现一些确定差异的信息。例如,当我在基类中设置_wheelsNumber,_motorType和_horsePower变量和逻辑时,我会让每个类(Car,Truck,Semi,Moped等)设置其_wheelsNumber并触发逻辑流来计算其余的属性。
但是,我不确定我是否以正确的方式构建了我的课程以实现这些目的。我不清楚我是否用我的construcor和我的get / set访问器远程做正确的事情(因为我不希望用户选择汽车有多少轮子的东西,我没有声明的set访问器)。我认为我注意到的一件事是,用户必须询问程序在电机类型之前和马力之前的车轮数量。我认为这是因为它们不是在构造函数中计算的,但我不确定。
任何清晰度都会受到高度赞赏。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VehicleClasses
{
abstract public class Vehicle
{
protected const int smallMotor = 1;
protected const int mediumMotor = 3;
protected const int largeMotor = 5;
protected const int largerMotor = 7;
protected const int hugeMotor = 9;
protected const int wrongMotor = 9001;
public Vehicle()
{
_horsePower = (_motorType * _motorType) * 8;
}
protected int _wheelsNumber;
public int wheelsNumber
{
get
{
return _wheelsNumber;
}
}
protected int _motorType;
public int motorType
{
get
{
if (_wheelsNumber < 4)
{
_motorType = smallMotor;
}
else if (_wheelsNumber >= 4 && wheelsNumber <= 6)
{
_motorType = mediumMotor;
}
else if (_wheelsNumber > 6 && wheelsNumber < 10)
{
_motorType = largeMotor;
}
else if (_wheelsNumber >= 10 && wheelsNumber < 18)
{
_motorType = largerMotor;
}
else if (_wheelsNumber >= 18)
{
_motorType = hugeMotor;
}
else
{
_motorType = wrongMotor;
}
return _motorType;
}
}
protected int _horsePower;
public int horsePower
{
get
{
return _horsePower;
}
}
}
}
答案 0 :(得分:0)
这是继承的常见误用。子类应该扩展行为,而不仅仅是修改状态值。
在您的示例中,只有一个自由变量,即轮数。其他一切都是基于此的衍生特质。更改车辆的构造函数以将车轮数量作为参数,然后(如果需要)您可以向类中添加公共静态方法,例如“CreateMotorcycle()”,用于创建具有正确车轮数的车辆。
就像我之前提到的,当你想扩展行为时,继承很有用。例如,假设您有一个“Employee”基类。为了简单起见,让我们说每个员工都有一个大三和一个大四。
每当员工想要休假时,他们都要问他们的老人,但不是每个员工都可以批准。请求必须在链上传递,直到它到达“Manager”,这是一个派生实例。
翻转它,让我们说最高级的员工是所有者。当他希望公司做某事时,他并不是自己做的。他将命令发送到链条上。每个层都可以修改需要完成的任务。例如,所有者说它需要在365天内完成,每个经理说它有一半的时间被告知,并且工人完成了任务。
这些示例中的每个“类”(工作人员/经理/所有者)在调用相同方法时的行为都不同。但是让它们都实现相同的基类可以很容易地将它们链接在一起!这是"Chain of Responsibility"和"Decorator"模式的变体。