我想在OOP中模拟以下情况:
我希望Freight类成为一个抽象类,因为我希望我的程序根据一件货物的危险程度收取一些额外的费用。
实际上我遇到的问题是我希望Freight类是一个对象数组。我的意思是它可以存放一块行李和货物。我的问题是我在哪里可以调用addItem方法?我应该把它放入行李箱和货物类吗?或者我应该将一个名为addItem的通用抽象方法放入Freight类中?像这样的东西(我为此目的使用Java):
abstract class Freight{
//other things here
protected Freight[] fr=Freight[10];
protected int numItems;
abstract addItem();
}
class PieceOfLuggage extends Freight{
//other things
public PieceOfLuggage(int iden,double weight,int id){
super(iden,weight,id)
}
public addItem(){
fr[numItems]=this;
numItems++;
}
}
class PieceOfCargo extends Freight{
private degreeHazard;
public PieceOfCargo(int iden,double weight,int id,int degHazard){
super(iden,weight,id);
degreeHazard=degHazard;
}
public addItem(){
fr[numItems]=this;
numItems++;
}
}
所以在我的主程序中我可以做类似的事情:
Luggage l1=new Luggage(100,50,1234); //ident, weight, id
Cargo c1=new Cargo(300,123.56,1111,1); //ident, weight, id, degree of hazard
l1.addItem();
c1.addItem();
我可以将addItem方法添加到任何建议?,以便类Freight包含行李和货物类型的对象数组?
由于
答案 0 :(得分:6)
如果我理解这一点,我认为这里存在设计缺陷。您应该使用像Freight
这样的容器对象,其中包含Collection
项。但是如果你坚持这个设计,你需要的是Composite我认为。
摘自维基百科:
interface Freight{
void addItem();
}
/** "Composite" */
class CompositePieceOfCargo implements Freight {
private List<Freight> childFreights = new ArrayList<Freight>();
public void addItem(Freight freight) {
childFreights.add(freight);
}
}
/** "Leaf" */
class PieceOfCargo implements Freight {
private degreeHazard;
// your methods here
}
您可以使用“Leaf”对象,以防您处理具体的Freight
,如果它只是一个“容器”,您可以使用“复合”。
此伪代码指出了设计缺陷:在Leaf对象中,您无法为addItem
提供合理的实现。
答案 1 :(得分:5)
如果您希望Freight
能够容纳其他类型,您有三种选择:
让每个班级都延伸Freight
:
class Luggage extends Freight
OR
给Freight
一个数组:
class Freight
{
Luggage[] luggage = new Luggage[10];
Cargo[] cargo = new Cargo[10];
addItem(Luggage luggage){...}
addItem(Cargo cargo){...}
}
OR
make Luggage
和Cargo
扩展基类并将其放在Freight
内:
class DeliveryItem
{
addItem(DeliveryItem item){...}
}
class Luggage extends DeliveryItem
{
//override addItem if need be
}
class Freight
{
List<DeliveryItem> items = new ArrayList<DeliveryItem>();
List<DeliveryItem> getItems()
{
return this.items;
}
void addItem(DeliverItem item)
{
this.items.add(item);
}
}
答案 2 :(得分:4)
你的设计混淆了“有很多”的关系与“是一种”的关系。
PieceOfLugagge
不是Freight
,因为Freight
由一个或多个lugagge组成。
更好的设计如下。
当你想到它时,即使它是零,lugagge也可能具有危险程度。
Freight
包含FreightItem
个集合,每个FreightItem
可以是PieceOfLugagge
或PieceOfCargo
。
Freigth作为addItem()方法(未在图中显示)接受FreightItem
并将其添加到集合中。
答案 3 :(得分:2)
考虑将您的Freight类分为两类:
通常,面向对象设计的一种启发式方法是使每个类只代表一个概念。
答案 4 :(得分:2)
我的意思是它可以存放一块行李和货物。
这听起来更像Composition
关系,而不是inheritance
关系。例如,考虑一个更合乎逻辑的超类,如Item
,并使Cargo
和Luggage
成为其子类。
public abstract class Item {}
public class Luggage extends Item {}
public class Cargo extends Item{}
然后在你的Freight
课程中,你需要一个数组,它可以是Item
类型。
public class Freight
{
Item[] items;
}
addItem方法
现在可以进入Freight
课程,考虑到这是持有所有项目的课程。然后,您可以在Item
类中实现任何抽象方法,并确保您的Luggage
和Cargo
类实现这些方法。
危害程度
假设每个Item
都有一定程度的危险性。您可以做的是将degree
值放在您的超类Item
中,如下所示:
public abstract class Item {
int hazard;
public Item(int hazard)
{
// So hazard is in the superclass.
this.hazard = hazard;
}
public int getHazard() { return hazard; }
}
然后,在您的一个子类的构造函数中,例如Luggage
,您可以:
public Luggage()
{
super(5);
// Example value.
// Rest of constructor.
}
答案 5 :(得分:2)
Actually the problem that I got is that I want that the Freight class to be an array of objects.
我认为您的概念混淆了持有运费和 运费,这导致您的设计问题。在不了解整个环境的情况下,请考虑一下这个设计:
类FreightContainer :保存您的数组(实际上我会推荐一个LinkedList或ArrayList,具体取决于您希望在运行时使用的O(n))。负责添加(,发布)和删除您的货运物品,进行限额检查等。所以这就是你要实现addItem(Freight newItem)的地方。
类运费和子类:负责运费,因此具有与您的UML相似的所有属性。
可能会有进一步的调整,但这需要有关您问题的更多信息。
答案 6 :(得分:2)
我认为你应该拆分你的货运类。我会做那样的事情:
public interface Freight
public class Luggage extends Freight
public class Cargo extends Freight
public class FreightCollection
{
private ArrayList<Freight> freights;
public FreightCollection(){
freights = new ArrayList<Freight>()
}
public void addFreight(Freight freight){
freights.add(freight);
}
}
add方法必须属于一个集合,而不属于它自己的项目。
答案 7 :(得分:1)
由于您希望Freight类拥有PieceOfLuggage和PieceOfCargo的集合,我认为您希望它们扩展除Freight之外的其他类。
class Freight{
protected FreightPiece[] fr=FreightPiece[10];
protected int numItems;
public addItem(FreightPiece piece)
{
// add the piece to fr
}
}
abstract class FreightPiece {
}
class PieceOfLuggage extends FreightPiece{
public PieceOfLuggage(int iden,double weight,int id){
super(iden,weight,id)
}
}
class PieceOfCargo extends FreightPiece{
private degreeHazard;
public PieceOfCargo(int iden,double weight,int id,int degHazard){
super(iden,weight,id);
degreeHazard=degHazard;
}
}
那么
Freight fr = new Freight();
PieceOfLuggage l1=new PieceOfLuggage(100,50,1234); //ident, weight, id
PieceOfCargo c1=new PieceOfCargo(300,123.56,1111,1); //ident, weight, id, degree of hazard
fr.addItem(l1);
fr.addItem(c1);