首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

第七章 复用种

2012-10-17 
第七章 复用类第一种方法非常直观,就是组合。第二种方法就是继承。组合只需将对象的引用置于新类中即可。初始

第七章 复用类
第一种方法非常直观,就是组合。第二种方法就是继承。
组合只需将对象的引用置于新类中即可。


初始化基类

当创建了一个导出类的对象时,该对象包含了一个基类的子对象。这个子对象与你用基类直接创建对象是一样的。二者区别就是后者是来自于外部,前者来自于内部。
构建过程是从基类向外扩散的,所以基类在导出类构造器可以访问它之前,就已经完成了初始化。

结合使用组合和继承

Public class PlaceSertting extends Custom {    private Spoon sp;    private Fork frk;}

虽然编译器强制你去初始化基类,并且要求你要在构造器起始处就要这么做,但是它并不监督你必须将成员对象也初始化,比如上面的Spoon等,都不会马上初始化。但是可以在构造函数中进行初始化。

final关键字

使用到final的三种情况:数据、方法和类。

对于编译器常量这种情况,编译器可以将该常量值带入任何可能用到它的计算式中,也就是说,可以在编译时执行计算式,这减轻了一些运行时的负担。在java中,这类常量必须是基本数据类型,并且以关键字final表示。在对这个常量进行定义的时候,必须对其进行赋值。

一个既是static又是final的域只占据一段不能改变的存储空间。

当对对象引用而不是基本类型运用final时,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然而,对象其自身确实可以被修改的,java并未提供使任何对象恒定不变的途径。

必须在域的定义处或者每个构造器中用表达式对final进行赋值,这正是final域在使用前总是被初始化的原因所在。

final参数

Java允许在参数列表中以声明的方式将参数指明为final。这意味着你无法在方法中更改参数引用所指向的对象。

final方法

在java早期实现中,如果一个方法是final的,就是同意编译器将针对该方法的所有调用都转为内嵌调用。但是如果方法太大,那么你的程序就会膨胀。在使用java SE5/6时,应该让编译器和JVM去处理效率问题,只有想要明确禁止覆盖时,才将方法设置为final的。

final和private关键字

类中所有private方法都隐式地指定为final的。由于无法读取private方法,所以也就无法覆盖它。可以对private方法添加final修饰词,但这并不能给该方法添加任何额外的意义。
父类有一个private方法,子类的方法即使和父类的方法名字一样,也不属于重写,private只代表他属于本类的一部分。

final类

    当将某个类的整体定义为final时,就表明了你不打算继承该类。注意,final类的域可以根据个人的意愿选择为是或不是final。也就是说如果不是final的,类里面的属性是可以变化的。不论类是否被定义为final,相同的规则都适用于定义为final的域。然而,由于final类禁止继承,所以final类中所有方法都隐式指定为final的,因为无法覆盖它们。

初始化及类的加载


在Beetle上运行java时,所发生的第一件事情就是试图访问Beetle.main(),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class的文件之中)。在对它进行加载的过程中,编译器注意到它有一个基类(这是由关键字extends得知的),于是它继续进行加载。不管你是否打算产生一个该基类的对象,这都要发生。

接下来根基类中的static初始化,然后是下一个导出类,以此类推。这种方式很重要,因为导出类的static初始化可能会依赖于基类成员能否被正确初始化。

至此为止,必要的类都已加载完毕,对象就可以被创建了。首先对象中的所有基本类型都会被设置为默认值,对象引用被设置为null-----这是通过将对象内存设为二进制零值而一举生成的。然后基类的构造器会被调用。然后就是子类的了。
package com.neu.edu.apitest;public class Beetle extends Insect {private int k = Test.printInit("Beetle.k initalized");public Beetle() {System.out.println("Beetle constructor");System.out.println("k = " + k);System.out.println("j = " + j);}private static int x2 = Test.printInit("static Beetle.x2 initialized");public static void main(String[] args) {Beetle b = new Beetle();}}

package com.neu.edu.apitest;class Insect {private int i = 9;protected int j = Test.printInit("Insect.j initalized");Insect() {System.out.println("Insect constructor");System.out.println("I = " + i + ", j = " + j);j = 39;}private static int x1 = Test.printInit("static insect.x1 initialLized");}


打印的结果:
static insect.x1 initialLizedstatic Beetle.x2 initializedInsect.j initalizedInsect constructorI = 9, j = 1Beetle.k initalizedBeetle constructork = 1j = 39


加载顺序:
1.运行父类的static部分,然后是子类的static部分。
2.父类的变量开始初始化,然后调用构造方法。
3.子类的变量开始初始化,然后调用构造方法。

热点排行