如何设计一个可以容纳其他类实例的类。我会试着解释一下。
每个新客户的Customer
类实例。客户购买汽车,然后对每辆汽车进行特定操作。
例如,
Customer c = new Customer();
// customer buys cars
c.buyMercedes();
c.buyBMW();
// operations done on the car
c.changeMercedesColor();
c.changeBMWtyres();
我可以这样做:
Customer c = new Customer();
c.buy(Mercedes);
c.buy(BMW);
c.car("Mercedes").changeColor();
c.car("BMW").changetyres();
没有特定于任何汽车的操作。我想也许有一种方法可以在调用Car
方法时实例化buy()
类。为此设计课程的正确方法是什么?如果我有不同的方式,请告诉我。
答案 0 :(得分:2)
最简单的方法是为不同类型的汽车创建基类。您的所有特定车型(梅赛德斯,宝马)都将源于此。通过使用公共基类或接口,您的Customer类可以在特定的汽车上运行,而无需具体了解它们。
public abstract class CarBase
{
private string _color;
public virtual void ChangeTires()
{
// do the default change tires
}
public virtual void ChangeColor(string _color)
{
_color = color;
}
}
然后您可以创建特定类型的汽车:
public class Mercedes : CarBase
{
public override void ChangeColor(string color)
{
}
}
因为CarBase中的每个方法都是虚拟的,所以每个特定的实现都可以在需要时提供它自己的实现,否则它只依赖于'默认'ChangeTires()。
例如,也许梅赛德斯,改变颜色意味着你必须得到特殊轮胎。
public class Mercedes : CarBase
{
public override void ChangeColor(string color)
{
if (color == red)
AddRacingTires();
}
}
然后,您可以为客户提供添加新车辆的方法。
public class Customer
{
public Dictionary<string, CarBase> OwnedCars { get; set; }
public void BuyCar(string manufacture)
{
if (manufacture== "Mercedes")
OwnedCars[manufactor] = new Mercedes();
if (manufacture== "BMW")
OwnedCars[manufactor] = new BMW();
}
}
然后您可以执行以下操作:
Customer c = new Customer();
c.BuyCar("Mercedes");
c.OwnedCars["Mercedes"].ChangeTires();
有更好的方法来管理汽车。您可能想要查看工厂来创建汽车:http://www.dofactory.com/Patterns/PatternFactory.aspx
你可能也不想要制作词典(我想你会用VIN或其他东西来引用它们)。你也不想要像“Mercedes”这样的魔术字符串,因为你可能会在某处错误输入它。但这是最有效的基本设计模式。
答案 1 :(得分:1)
你想要作曲。您可以拥有Car
的通用列表,并从那里访问它们。
如果没有特定于任何特定汽车的操作,那么您只需将“Make”和/或“Model”作为汽车的属性。
答案 2 :(得分:1)
第二种形式毫无疑问优于第一种形式。
由于汽车可以独立于其所有者而存在,因此您应该能够在没有客户的情况下实例化汽车。也许您可以向客户添加操作以添加新车并获得现有车辆。您可能也希望通过VIN而不是制造汽车。任何一个客户都可能拥有多辆宝马。
changeColor和changeTyres方法应该存在于Car对象而不是客户对象上。
Car bmw = carFactory.create("BMW");
customer.add(bmw);
Car bmwAgain = customer.get(bmw.Vin);
bmwAgain.changeColor("black");
答案 3 :(得分:1)
由于您没有特定于任何汽车的操作,因此您无需从汽车派生。假设您有一个Car
类具有Brand
属性,这是一个枚举。然后你可以像这样设计你的Customer类:
Customer c = new Customer();
c.buy(Brands.Mercedes);
c.buy(Brands.BMW);
buy
方法会创建Car
的新实例,设置它的Brand
属性并将其添加到cars
,Customer
的实例变量输入List<Car>
。
如果您确定一个客户只能拥有一个品牌的汽车(没有两个Mercededes的客户?周末可能是SLK而在城市找到停车位的A?),那么您可以定义您的这样的界面:
c.getCar(Brands.Mercedes).changeColor();
c.getCar(Brands.BMW).changeTyres();
否则,我会公开汽车的枚举并使用LINQ:
var mercedeses = c.Cars.Where(car => car.Brand == Brands.Mercedes);
foreach (var car in mercedeces) {
car.changeTyres();
}
答案 4 :(得分:0)
继承工厂是您所需要的。
答案 5 :(得分:0)
好的,这听起来有点像家庭作业但是:
如果你有购买的物品都是汽车,那么就有共同点,比如“服务”,“mot”,“灯”,“轮胎”,“排气”,“油漆”作为你那时的物品“改变“
你可以拥有一个BaseCar的基类,然后你可以从中获得你的BWM / Merc等。
对于每个客户,您将有一个班级,您可以在其中定义要作为基础车购买的物品,但您可以向他们发送“新梅赛德斯()”并获得他们购买的实际汽车的新实例。 / p>