作者回复: 好的,我把这个问题在答疑那讲里作为一个点。
作者回复: 我看看在讲Java那讲里能否把这个内容兼顾。
有同学提的泛型,其实我还没有安排进去...实在不行做个加餐。
这里先提一句:java的泛型其实只是语法糖,是在基础语法的基础上封装了一层而已。运行期,带泛型和不带泛型的,是完全同一套代码,没区别。LinkedList<String>和LinkedList<Object>运行时没区别。只是在编译期添加了额外的类型检查功能。
这跟C++的模板完全不是一回事。
作者回复: 线程的原理,是操作系统的内容,你可能要去那门课程多学一下:)
过去的语言(如C语言),只是提供标准的库,让你访问操作系统的线程管理功能,包括信号量、同步互斥什么的。
Java语言增加了一些专门处理多线程的元素,比如synchronized关键字。
go语言又更进一步,把操作系统的线程进行了封装,变成了轻量级的goroutine,很受欢迎。
作者回复: 抱歉回复晚了。
方法的overide,是下级覆盖商机,所以应该先从下级查找。如果下级实现了,就用下级的。
如果下级没有,就用上级的,这就是inheritence。
作者回复: 能把你的“结构化继承”的含义描述得更细致一些吗?
如果你是指基于结构体来做继承,go语言做得就不错。你可以了解一下。对组合的支持做得很好。
作者回复: 允许多态正常,因为虽然是在构造函数中,但已经要使用对象的方法了,所以多态逻辑就会发生作用。
不过,java对象的初始化的语法设计,似乎还可以做得更好。比如,如果调用super(),必须出现在第一行等等。需要明白初始化的原理,才会理解为什么这么设计。
另,你的问题:加不加this都是一样的。
作者回复: Java语言的成员变量,只要给它分配了内存空间,就一定会做初始化。所以,即使还没有运行这个类的构造方法,其实这些变量也都可以用了,只不过里面的是缺省值。
Java只所以采取这个机制,可能就是跟面向对象的生存期特征有关的。也就是,所有成员变量要在调用任何方法之前就创建,并且可用。所以,这个时候调用方法并没有问题。
所以,Cow类的初始化过程,如果用放大镜看的话,可能会分成多个阶段。对于int a = 10;这样一个语句来说:
阶段1:Cow及其父类的成员属性都获得了内存,并具备了缺省值。
阶段2:使用变量声明时的初始化部分,让a的值变为10;
在这个阶段,其实还可以用int a = b;或者int a = foo()这样的方式来做初始化,这时候要求b一定是在a的前面。
阶段3:运行自定义的构造函数。这时候,a的值可能又被修改成其他值。
作者回复: 在RefResolver.exitPrimary()中,在这里做与primary有关的引用消解。
This variable = theClass.getThis();
at.symbolOfNode.put(ctx, variable);
作者回复: 对,目前没有支持类方法。也没有支持类级别的成员变量。
作者回复: 好的,我安排在后端部分会讨论一下这个问题。
深度学习发展速度太快。从长远来看,需要标准的IR。这又是一次标准之争。
作者回复: 总的来说,this和super在三个场景中,它的语义是有差别的。
场景1:对象属性:适用原理,是变量作用域。
场景2:对象方法:适用原理,是多态;
场景3:构造方法。这个只是长得像方法,其实不是方法。要用对象初始化的逻辑去分析它。
this和super的实现,你可以参考一下playscript-java的代码。
另外,可以再像ThisSuperTest.java一样,写点代码深入测试一下this和super特性。