1 、 为对象在使用前,都需要初始化。所以我们在写一类时,必须有一个构造函数。如果没有写,那么编绎器会自动用默认的构造器。但是,如果你有定义构造函数,那么编绎器是不会给你产生默认构造函数的。
2 、 我们常常需要继承一个类,而这个新的类也可能需要有自己的构造函数,这时候对于构造函数来讲,就有了重载的概念。
3 、 在新类的构造器中也常常要调用基类的构造器,这时候就要用到 this ,那么,我们就要讲讲 this :
public calss GisClass{ GisClass(int width,int height){ this.width = width; this.height = height; } void doPan(){}; } public class UseGisClass{ public static void main(String[] args){ GisClass aGis = new GisClass(1,2); GisClass bGis = new GisClass(1,2); aGis.doPan(); bGis.doPan(); } }
在以上的代码中,我们怎么知道 doPan() 方法到底是被 aGis 对象还是被 bGis 对象调用了呢?其实, doPan() 方法被在被对象调用时会暗中把调用它的对象传入到方法体内 。所以,如果你想在方法的内部得到对调用它的当前对象的引用,可以用 this 。
this 只能用在方法的内部,表示“调用方法的那个对象” 的引用 。
注意的是,在一个类的内部,一个方法要调用类的另一个方法,并不需要写 this ,直接调用即可。当前方法中的 this 引用会自动应用于同一类中的其它方法。
this 也常常用到一个类的一个方法的返回对象值,如下:
public class Leaf{ int i = 0; Leaf increment(){ i++; return this; } void methodprint(){System.out.print(i);} public static void main(String[] args){ Leaf l = new Leaf(); l.increment().increment().increment().increment().methodprint(); } }
在以上我们说的 this 都是指对象,而构造器里的 this 明确地表明是对基类的构造器的引用。这里注意的一点是,构造器里不能用两次 this 。
或者,我们常常用如下语句来写构造函数:
public class GisClass{ GisClass(int width,int height){ this.width = width; this.height = height; } }
这种方式用的 this ,是说明传入的参数与类成员名字相同,而我们为了产生歧义,使用 this 来代表数据成员。
4 、讲完了 this ,讲讲与它关系比较紧密的 static 。
Static 方法就是没有 this 的方法,在 static 方法内部不能调用非静态方法,反过来就可以。对于 static 方法,在没有创建对象前,只能通过类开访问调用它。这衽是 static 方法的所有内容。这有点像全局方法, java 中禁止使用全局方法,但是你在类中用了 static 方法,就可以用它来访问其它的 static 方法和 satic 域。
5 、讲了初始化,具体讲讲数组的初始化。
数组就是相同类型、用一个标识符名称封装在一起的一个对象序列或基本类型数据序列。
数组我们最常用的是用 [ ] 来访问它的元素。
定义数组如下:
int[] a = new int[length]; int[] a = {1,2,3} int[] a = {new Integer(1),new Integer(2),new Integer(3)}
注意的是:如果一个数组引用赋值给了另一个数组引用,当其中一个改变数组元素时,访问另一个数组引用时元素的值也是改变了的。如下:
public class TestArray{ public static void main(String[] args){ int[] a1 = {1,2,3}; int[] a2; a2 = a1; for(int I=0;I<3;I++){a2[i]=I*2;} for(int I : a1){print(a[i])} } }
以上代码中,因为 a1 与 a2 指向相同的数组,所以通过 a2 改变了数组,所做的修改在 a1 里也能够看得到。
下面讲讲数组的可变参数列表。
public Class TestVarArgs{ static void printArgs(Object[] args){ for(Object o : args){ print(o + “”); } } public static void main(String[] args){ printArgs(new Object[]{1,2,3}); printArgs(new Object[]{new Integer(1),new Integer(2),new Integer(3)}); } }
以上代码 printArgs 中传入的参数是一个数组,如果我们不想使用数组,而用可变参数,如下:
public Class TestVarArgsNoArray{ static void printArgs(Object… args){ for(Object o : args){ print(o + “”); } } public static void main(String[] args){ printArgs(1,2,3); printArgs(new Integer(1),new Integer(2),new Integer(3)); printArgs(new Object[]{1,2,3});//array is also ok printArgs();//empty is ok } }
有了可变参数,就不用去用数组了,因为实质上编绎器会自动地去填充数组。从以上可知,用可变参数,就算是数组、不是数组、空都行。可见,当要用可选的参数时,可变参数是一种很好的解决方案。
然而对于方法的重载,因为可变参数的原因,我们只能在重载方法的一个版本上使用可变参数列表,或是压根就不用它。
6 、枚举:
当我们需要群组处理时可以用枚举。
public enum EnumDegree{ LOWEST,LOW,MEDIA,HIGH,HIGHEST }
枚举的 ordinal() 方法表明特定的 enum 常量的顺序。以及它的 static values() 方法得到常量值构成的数组:
public class TestEnum{ public static void main(String[] args){ for(EnumDegree e : EnumDegree.values()){ printl(e + “” + e.ordinal()); } } }
我们可以把枚举当作一种数据类型来使用,也可以当作类来使用。
枚举有个很常用的特性,它常与 switch 一起来使用。
public class TestSwitchEnum{ private String degree; public TestSwitchEnum(degree){ this. degree = degree; } void methodSwitch(){ switch(degree){ case LOWEST: case LOW: } } public static void main(String[] args){ TestSwitchEnum twe01 = new TestSwitchEnum(TestEnum. LOWEST); TestSwitchEnum twe02 = new TestSwitchEnum(TestEnum. LOW); TestSwitchEnum twe03 = new TestSwitchEnum(TestEnum. MEDIA); twe01 .methodSwitch(); twe02 .methodSwitch(); twe03 .methodSwitch(); } }
由于 switch 在有限的值里选择,因此它与 enum 一起配合是很好的组合。
其实,我们用 enum ,是可以用 enum 创建数据类型,这个数据类型里存放着一些常量,然后直接把它们拿来用就行了。
7 、 foreach 语句:
最后,因为我们用到了很多的 foreach ,讲讲它。
Foreach 什么时候用呢?一般我们用它来访问数组和容器。用了它就不用像以前一样用计数器来计数,它将产生每一项元素。不要产生每一项,说明了我们只是得到每一个元素,并不需要得到每个元素的一些细节,这时候用 foreach 反而更加简洁。