文章标题
2017-06-16 22:41
211 查看
组合和继承
本文是我读 think in java后做的一些记录,一些术语是以该书上的为标准:组合和继承都能从现有类型生成新类型.
组合一般是将现有类型作为新类型的底层实现的一部分加以复用,而继承复用的是接口
组合,继承,代理(介于组合和继承之间)
1. 在面向对象的编程的过程中,我们生成和程序代码最有可能采用的方法是将数据和方法封装进一个类中,并使用类的对象
2. 也可以使用组合技术使用现有类来开发新的类,继承技术应当慎用,一个最清晰的判断是:是否需要从新类向上基类向上转型
3. 我真的需要向上转型嘛?—-组合和继承的区别
初始化和类的加载
在许多的传统语言中,程序是作为启动过程的一部分被加载的.然后是初始化,接着程序运行java中采取了与传统语言不同的加载方式,在java中所有的事物是对象.
java中每个类的编译代码存在于他自己的独立文件中.
该文件只在需要使用程序代码时才会被加载,也可以说”类的代码在初次使用时才会被加载“—->这通常指加载发生于创建类的第一个对象时,但是当访问static域或static方法时,也会加载
初次使用之处也是static初始化发生之处.所有的static对象和static代码都会在加载时依据程序中的顺序(即:定义类时的书写顺序)而依次初始化
当然定义为static的东西只会被初始化一次
类的初始化
此处我们通过一个例子来介绍类的初始化过程class Insect { private int i = 9; protected int j; Insect() { print("i = " + i + ", j = " + j); j = 39; } static { System.out.println("Insect static"); } private static int x1 = printInit("static Insect.x1 initialized"); static int printInit(String s) { print(s); return 47; } } public class Beetle extends Insect { private int k = printInit("Beetle.k initialized"); public Beetle() { print("k = " + k); print("j = " + j); } private static int x2 = printInit("static Beetle.x2 initialized"); public static void main(String[] args) { print("Beetle constructor"); Beetle b = new Beetle(); } }
首先程序从Beetle的main方法进入程序,于是类加载器开始启动并加载Beetle类的编译代码(Beetle.class的字节码文件),加载的同时也会加载该类的所有基类(由extends关键字可知).
如果基类也存在基类,也会加载.加载基类时加载器也会同上一样,不管你是否创建基类的对象
接下来进行的是static域的初始化(记住:static域在类加载的过程中已经进行了初始化),首先从根基类开始,依次次向下,直到最后一个导出类.这样加载的原因是因为:导出类的加载可能会依赖于基类的成员能否被正确初始化.
至此为止,所有的类已经加载完毕就可以创建对象了:
首先将对象中所有的基本类型初始化为默认值,引用设为null(通过将对象的内存设为二进制零值)
然后基类的构造器会被调用,先初始化成员变量,再执行构造器中的代码,
直到最后的导出类
类的加载只执行一次.
Loading the class initializes the static variables. The base class
loads first, then the next-derived class, and finally the most-derived class. This creates the object and initializes the non-static members,also starting at the root class.
Remember, a constructor is a static method, even though you don’t define it using the static keyword.