这是我一直有的问题,但现在是时候解决它了:
我尝试使用公共属性来实现对象的组合,例如:
Person {
public Car car;
}
Owner {
public Person person;
public Car car;
}
Car {
public Person person;
}
真的我的问题是:将组合属性设置为公共或私有是一种好习惯吗?
区别:
a)公开:公开,访问速度快而且不复杂,因为我只需要直接引用属性,例如:
$instancePerson.car.getNumberOfGearsGood()
问题:任何人都可以修改汽车属性。
b)私有:做私有,访问速度很慢,并且必须使用方法来获取这些属性,如:
$instancePerson.getCar().getNumberOfGearsGood()
当我说慢是因为你需要做一个方法两个方法调用,而在Public解决方案中你只需要做一个。
我知道这里的许多开发人员和软件工程师都更喜欢私有解决方案,但您能解释一下那里的性能吗?
答案 0 :(得分:0)
如果你正在做OO,那么就不应该有" public"属性。所有属性都是对象的实现细节,因此对每个人都是隐藏的。只有与对象责任相关的方法才是公开的。
所以回答这个问题:
是的,应该没有
person.getCar().getNumberOfGears();
有时称为Law of Demeter。该人员应该拥有与Person类的职责相关联的方法,因此访问属性没有性能损失,因为这种访问始终是类的内部和直接访问。
答案 1 :(得分:-1)
简短的回答是,除了极少数情况之外,您希望这些变量是私有的,并且JVM中的技术通常会使访问速度超出您的预期(有时甚至比C / C ++更快) 。
有关更详细的答案:
主要问题是:谁应该能够修改这些变量?例如,您可能希望创建Car
将Person
传递给其构造函数,并且永远不允许此人更改(在没有二手车市场的世界中)。在这种情况下,如果该字段是公共的,则另一个对象可以修改它并更改汽车的所有者。但是如果你将该字段设为私有,并提供getOwner()
方法,则没有人可以修改它。如果get方法是final
,因此无法在子类中重写,则JVM甚至可以在内部转换x.getOwner()
的任何x.owner
等效调用。但是在您的示例中,无法传递构造函数中的所有元素,因为它们相互引用。事实上,在我看来你的模型有太多的类。让我们试着用不同的方式写一下:
Person {
public Car car;
}
Car {
public Person owner;
}
现在,假设每辆车都有车主,并且每个人都拥有一辆车,这种车型很危险,因为你可以这样做:
Person p = new Person()
Car c = new Car();
p.car = c;
如您所见,我忘了设置c.owner = p
。
让我们看看如何解决这个问题:
Person {
private Car car;
public void setCar(Car c) {
if (car == c)
return;
car = c;
c.setOwner(this);
}
}
Car {
private Person owner;
public void setOwner(Person o) {
if (o == owner)
return;
owner = o;
o.setCar(this);
}
}
我现在可以做到:
Person p = new Person();
Car c = new Car();
p.setCar(c);
或
Person p = new Person();
Car c = new Car();
c.setOwner(p);
并且两种关系都将正确设置。
换句话说,被迫通过访问器允许设置的不仅仅是一个简单的字段,这对于在关系中涉及的模型元素建立连贯状态很有用。