这两者有什么区别:
class Machine {
public int x = 2;
}
class Car {
public void start(Machine myMachine) {
myMachine.x = 10;
}
}
和:
class Machine {
public int x = 2;
}
class Car extends Machine {
public void start() {
super.x = 10;
}
}
在第一个示例中,我将使用Car
类创建一种新的对象,并且我可以使用Machine
类中的变量x
。
在第二个示例中,我将从Machine
类继承到Car
类,因此我可以在Car
中使用Machine
中的变量。
但是我不知道什么时候应该先使用一个而不是第二个,哪个更好,依此类推。
有人可以解释其中的区别吗?
在第一个例子中,你说"我希望Car
为某些机器分配一个值 10(Car
与该Machine
没有真正的联系,它可能是"门"、"车库"或其他类,Car
可以与Car
合作,但它们不在关系中"汽车是......")可变x
">
在第二个中,你说"Car
是一台机器,我希望它能够将自己的x
变量的值更改为 10"。(例如,你可以说"我希望我的车启动自己的引擎)。
我知道在第一个例子中,我正在创建一种新对象(我说得对吗?)- 这不是通过将其作为参数传递来创建新的Machine
引用。您宁愿说您希望类Car
实例能够更改x
机器类的一个特定实例的值。不是对所有机器,只是对作为参数传递给start()
方法的机器。示例:myFerrari.start(gateThree)
汽车具有在需要时打开大门的功能,但汽车is not
门。
但我不知道什么时候应该使用第一个,什么时候应该使用第二个,哪个更好,依此类推。在第二个例子中,你说汽车是一台机器 - 所以它能够执行机器能够执行的所有动作,它也能够执行一些特定于汽车而不是所有机器的动作。要使用继承,你应该确保你可以说汽车是一台机器。
第一种关系有时被称为"使用"关系,如"汽车使用机器",而第二种有时称为"is-a"关系,如"汽车是机器"。这第二种关系称为继承。还有第三种广泛的类型,即您在此处未显示的"has-a"关系:
class Machine {}
class Car {
Machine machine;
}
第一种关系比第二种关系容易理解得多。通常,如果我们想将一个子类(在您的示例中为 Car)替换为另一个派生自同一父类(机器)的子类,我们只会对第二个子类进行建模。
当一个类需要成为其他类的类型时,使用继承,因为它们共享一些属性。因此,在这种情况下,汽车可能是一种机器,并且可能定义或扩展机器中的变量或函数。
如果一个类只需要访问或使用机器对象(它的变量或函数),最好使用你的第一个示例。例如,如果您想要一个 MachineManager 或 MachineList 类。