PDF 课件和源代码下载地址:
https://gitee.com/geektime-geekbang/LetsJava
作者回复: 手动点赞,说的很好~
作者回复: 优先使用has a,谨慎使用is a。
作者回复: 这个不算是典型的依赖注入,因为HuaweiPhone会有很多实例。比较典型的依赖注入是只有单个实例。 从组合的角度来说,并不存在耦合关系。因为HuaweiPhone是负责创建Phone的实例的。 以这个例子举例,如果Phone是别的代码创建的,然后HuaweiPhone需要用到这个Phone的实例。那么就算是依赖注入。 所以这个点在于,被依赖的对象(Phone)是谁创建的。在这个例子里,就是单纯的组合。 再举个例子。比如,A模块初始化好,才能初始化B模块。那么就是Spring擅长的依赖注入。如果B模块在初始化的过程中,自己用代码创建了一个A模块,那不需要依赖注入。
作者回复: 创建一个Merchandise类型的属性变量,不是属性。 属性是指的Merchandise类内部的成员变量。 在方法里这样写是不行的,因为m是局部变量,局部变量没有初始化不可以使用。 Merchandise m; m.xxx 这样是可以的: Merchandise m = null; // 虽然肯定会报错,但是是可以通过编译的 m.xxx 或者这样 Merchandise m = new Merchandise(); m.xxx
作者回复: 这个问题,不确定我理解的对不对。我想你说的是,在Phone里定义一个buy方法,然后创建一个Merchandise的实力,用这个buy方法覆盖Merchandise实例的buy方法。 如果是这样的话,做不到的原因是Java里只有集成才有覆盖,也就是说,如果两个类没有继承关系,那就没法覆盖对方的方法。如果要Phone里的buy能够覆盖Merchandise类Buy方法,那么Phone就必须继承Merchandise类。但是有继承,就不叫组合了。 这个从理论上说,就牵扯到继承的具体实现了。像JS这种语言,是基于原型的继承(多态)。可以灵活的插拔更换各种方法/函数。Java是基于类这种类型的继承(多态),不能那么灵活。 但是换个角度,从设计的角度说,Phone本身,也不应该有buy方法。Phone就是Phone,有的是功能。只有Phone作为商品的时候,才有buy这种行为。当然,如果把Phone看作商品,那么继承Merchandise并覆盖buy方法没问题。
作者回复: 构造方法的参数
作者回复: 如果只是属性重用,是的,组合更合适。 如果是属性和用到属性的方法被重用,进而需要被覆盖,继承/传递给子类这种,可以考虑继承。
作者回复: 🉑️
作者回复: 这个没有严格的标准。用什么都是出于自己的判断。虽然道理很简单,is-a,用继承,has-a,用组合。 但是如果有人就是觉得“手机是一个有芯片和电池的屏幕”,是“is-a”,你也没法说他就是不对,他就是从那个角度看问题的。
作者回复: :-)