对象与类
- 对象变量并没有实际包含一个对象,它只是引用一个对象,在Java中,任何对象变量的值都是对存储在另外一个地方的某个对象的引用。new操作符的返回值也是一个引用。
- 可以将实例字段定义为final。这样的字段必须在构造对象时初始化。也就是说,必须确保在每一个构造器执行之后,这个字段的值已经设置,并且以后不能再修改这个字段。
1 | java复制代码private final StringBuilder evaluations = new StringBuilder(); |
final关键字只是表示存储在evaluations变量中的对象引用不会再指示另一个不同的StringBuilder对象。 不过这个对象可以更改。
2. 对于类中非静态的实例字段,每个对象都有自己的一个副本,但是对于静态字段,类的所有实例将共享同一个静态字段,静态字段属于类,不属于任何单个的对象。
3. 在程序中,可以用Math.PI来访问这个常量。
1 | java复制代码public class Math{ |
如果省略关键字static,PI就变成了Math类的一个实例字段。也就是说,需要通过Math类的一个对象来访问PI,并且每一个Math对象都有它自己的一个PI副本,浪费资源。
4. 静态方法是不在对象上执行的方法。 静态方法不能访问非静态的实例字段,因为它不能在对象上执行操作。但是,静态方法可以访问静态字段。可以使用对象调用静态方法,但是不建议。
在下面两种情况下可以使用静态方法:
- 方法不需要访问对象状态,因为它需要的所有参数都通过显示参数提供(例如:Math.pow)。
- 方法只需要访问类的静态字段。
- Java中对方法参数能做什么和不能做什么:
* 方法不能修改基本数据类型的参数(即数值型或布尔型)。
* 方法可以改变对象参数的状态。
* 方法不能让一个对象参数引用一个新的对象。
- 有一种import语句允许导入静态方法和静态字段,而不只是类。例如:
1 | java复制代码import static java.lang.System.*; |
就可以使用System类的静态方法和静态字段,而不必加类名前缀:
1 | java复制代码out.println(“Hello World!”); |
继承
- 在设计类的时候,应该将最一般的方法放在超类中,而将更特殊的方法放在字类中。
- 在Java中,子类引用的数组可以转换成超类引用的数组,而不需要使用强制类型转换。
- 不允许扩展的类被称为final类,如果在定义类的时候使用了final修饰符就表明这个类是final类,如果类中的方法被声明为final类型,子类就不能覆盖这个方法,如果将一个类声明为final,只有其中的方法自动地成为final,而不包括字段。
- 将一个值存入变量时,编译器将检查你是否承诺过多。如果将一个子类的引用赋给一个超类变量,编译器是允许的。但将一个超类的引用赋给一个子类变量时,就承诺过多了。必须进行强制类型转换,这样才能通过运行时的检查。
- 综上:
* > 只能在继承层次内进行强制类型转换。
* > 在将超类强制转换成子类之前,应该使用instanceof进行检查。
* > 一般情况下,最好尽量少用强制类型转换和instanceof运算符。
- 为了提高程序的清晰度,包含;一个或多个抽象方法的类本身必须被声明为抽象的。即使不含抽象方法,也可以将类声明为抽象类。
- 抽象类不能实例化。也就是说,如果将一个类声明为abstract,就不能创建这个类的对象。
- 由于每个值分别包装在对象中,所以ArrayList 的效率远远低于int[] 数组。因此,只有当程序员操作的方便性比执行效率更重要的时候,才会考虑对较小的集合使用这种构造。
- ==运算符可以应用于包装器对象,不过检测的是对象是否有相同的内存位置。不过如果值是介于-128和127之间的两个包装器对象比较结果就会成功。
- 枚举类:
1 | arduino复制代码public enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE } |
实际上,这个声明定义的类型是一个类,它刚好有4个实例,不可能构造新的对象。因此在比较两个枚举类型的值时,并不需要调用equals,直接使用 “==” 就可以了。
10. 继承的设计技巧:
* 将公共操作和字段放在超类中。
* 不要使用受保护的字段。
* 使用继承实现“is-a”关系。
* 除非所有继承的方法都有意义,否则不要使用继承。
* 在覆盖方法时,不要改变预期的行为。
* 使用多态,而不要使用类型信息。
* 不要滥用反射。
本文转载自: 掘金