目录
类与对象
定义类
要产生对象必须先定义类,类是对象的设计图,对象是类的实例。
类定义时使用 class 关键词,建立实例使用 new 关键词。
class Clothes{
String color;
char size;
}
new Clothes;
以类名称声明的变量,称为参考名称、参考变量或直接叫参考。
Clothes c1;
用 “=” 将 c1 指定给新建对象称为将 c1 名称参考至新建对象。
Clothes c1 = new Clothes();
这样一个基本的对象也就是实例就创建好了。
例:
class Clothes{
String color;
char size;
}
public class Field {
public static void main(String[] args) {
Clothes c1 = new Clothes();
Clothes c2 = new Clothes();
c1.color = "red";
c1.size = 'S';
c2.color = "green";
c2.size = 'M';
System.out.printf("c1 (%s %c)%n",c1.color,c1.size);
System.out.printf("c2 (%s %c)%n", c2.color,c2.size);
}
我对于这段代码的理解是:
1.我在 Field.java 中定义了两个类,而唯一的公开类是 Field 类,另一个类是 Clothes类。
2.我在 Clothes 类中声明了两个属性: color 和 size,前者是 String 类型,后者是 char 类型。
3.我在 Field 这个公开类建立了两个 Clothes 对象(实例),并且分别声明了 c1 与 c2 两个参考名称给它们。
4.我分别给它们声明的参考名称所绑定的对象的属性,也就是 color 与 size 指定值。
5.最后将 c1、c2 各自拥有的数据成员的值显示出来。
构造函数
构造函数是与类名相同的方法。
构造函数的作用就是在建立对象时,可以一并进行某个初始流程,比如指定数据成员值。
例:
class Clothes2{
String color;
char size;
Clothes2(String color, char size){
this.color = color;
this.size = size;
}
}
public class Field2 {
public static void main(String[] args) {
Clothes2 c1 = new Clothes2("red", 'S');
Clothes2 c2 = new Clothes2("green", 'M');
System.out.printf("c1 (%s %c)%n",c1.color,c1.size);
System.out.printf("c2 (%s %c)%n",c2.color,c2.size);
}
}
按我理解就是在公共类中定义接下来要用到的其他类所创建的对象时,在其他类里创建一个构造函数,然后给这个构造函数传参,构造函数的参数与其他类中的属性成员(创建的对象的数据成员)同名时,就在数据成员前面用 this 来区别。
也就是说 this.XX 这个XX指的是属性成员,就是在 Clothes 里面定义的那两个变量。
使用标准类
Java SE 提供了标准的 API,而 API 中由了大量的类组成,这些类称为标准类。
使用 java.util.Scanner
import java.util.Scanner;
public class Guess {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int number = (int) (Math.random() * 10);
int guess;
do {
System.out.print("猜数字(0~9):");
guess = scanner.nextInt();
}while(guess != number);
System.out.println("猜对了……XD");
}
}
先通过 import 关键字将标准类导入程序中,然后就可以在公共类直接使用。
在建立 Scanner 对象(实例)时,必须给它传入 java.io.InputStream 的实例,也就是 System.in(只是其中一种)才能使用。
java.util.Scanner 的 nextInt()方法会看标准输入中,是否有输入一个字符串(以空格或换行分隔),有的话就会剖析为 int 类型,其他对应的还有 nextByte()、nextShort()、nextLong()、nextFloat()、nextDouble()、nextBoolean()等。
如果想取得上一个字符串,则用 next(),想取得用户的整行文字,则用 nextLine()。
使用 java.math.BigDecimal
Java 遵循 IEEE 754 浮点数运算规范,使用分数与指数来表示浮点数。
如果追求精确度,那么使用浮点数时最好不要用 == 来比较浮点数的运算结果。
必须使用 java.math.BigDecimal 类得到更准确的精确度。
BigDecimal 提供有 plus()、substract()、multiply()、divide()等方法,可以进行加、减、乘、除等运算。
import java.math.BigDecimal;
public class DecimalDemo {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.8");
BigDecimal c = a.subtract(b);
System.out.print(c);
}
}
如果不使用 BigDecimal 类,那运算结果不会等于 0.2 的。
import java.math.BigDecimal;
public class DecimalDemo2 {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.1");
BigDecimal c = new BigDecimal("0.1");
BigDecimal result = new BigDecimal("0.3");
if(a.add(b).add(c).equals(result)) {
System.out.println("等于0.3");
}
else {
System.out.println("不等于0.3");
}
}
}
以及这段程序,如果使用:
double a = 0.1;
double b = 0.1;
double c = 0.1;
if((a + b + c)== 0.3){
System.out.println("等于0.3");
}
else{
System.out.println("不等于0.3");
}
那结果肯定是不等于 0.3 的。
所以在类类型要谨慎使用 = 和 == 两个符号。
对象的指定和相等性
在类类型(对象)中,我们比较两个对象的值是否相等,一般使用 equals()方法。
基本类型和类类型在 = 与 == 的运用是有很大不同的。
int a = 10;
int b = 10;
int c = a;
System.out.println(a == b);
System.out.println(a == c);
当 = 用于基本类型时,是将值赋值给变量。
当 == 用于基本类型时,是比较两个变量的值是否相等。
所以上面代码的结果是:
但如果是在操作对象:
BigDecimal a1 = new BigDecimal("0.1");
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal c1 = a1;
System.out.println(a1 == b1);
System.out.println(a1.equals(b1));
System.out.println(a1 == c1);
= 在这里是在指定参考名称参考某个对象
== 是用在比较两个参考名称是否参考同一对象
所以输出的第一句是 false,因为 a1 与 b1参考的并不是同一个对象,只是是相同的 BigDecimal 对象而已。
第二句采用 equals()方法,所以是在比较两个对象的实际内含值是否相等。
第三句是将 c1 这个参考名称的对象也参考为 a1 的参考对象,所以两者参考对象一致。
基本类型打包器
要让基本类型如同对象一样操作,可以使用 Long、Integer、Double、Float、Boolean、Byte等类来打包基本类型,这些类就是打包器。
基本类型打包器都是归类于 java.lang 包中。
public class IntegerDemo {
public static void main(String[] args) {
int data1 = 10;
int data2 = 20;
Integer wrapper1 = new Integer(data1);
Integer wrapper2 = new Integer(data2);
System.out.println(data1 / 3);
System.out.println(wrapper1.doubleValue() / 3);
System.out.println(wrapper1.compareTo(wrapper2));
}
}
如果要使用 Integer 打包 int 类型数据,那么可以用 new 创建一个 Integer 的对象(实例),然后传入 int 类型数据。
因为是在 int 整数空间运算,所以第一个值是 3。
可以使用 Integer 中的 doubleValue()方法将打包值以 double 类型返回。
第三句中是运用 Integer 提供的 compareTo()方法,与另一个 Integer 对象进行比较,如果打包值相同,则返回 0,小于 compareTo()传入的值则返回 -1,否则返回 1。
自动装箱、拆箱
自动装箱
J2SE 5.0 后提供了自动装箱功能。
可以将基本类型直接打包成这样:
Integer wrapper = 10;
使用自动装箱功能后,上面 IntegerDemo 可以改写成这样,更加简洁。
public class IntegerDemo {
public static void main(String[] args) {
Integer data1 = 10;
Integer data2 = 20;
System.out.println(data1.doubleValue() / 3);
System.out.println(data1.compareTo(data2));
}
}
自动装箱还可以有以下操作:
int i = 10;
Integer wrapper = i;
// 先将 3.14f 自动装箱为 Float,然后在指定给 number
Number number = 3.14f;
自动拆箱
除了自动装箱, J2SE 5.0 还提供了自动拆箱功能,也就是自动取出打包器中的基本形态信息。
Integer wrapper1 = 10; //自动装箱
int foo = wrapper1; //自动拆箱
wrapper1 会参考 Integer,被指定给 int 类型变量的 foo,那就会自动拆箱取出打包好的 int类型再指定给 foo。
Integer i1 = 10;
System.out.println(i1 + 10);
System.out.println(i1++);
按我理解编译器会先自动拆箱,把 Integer 中打包好的 int 类型拆箱,然后再去做计算。
自动拆箱除了算术运算还能运用在逻辑运算上。
Boolean foo1 = true;
System.out.println(foo1 && false);
装箱的内幕
Integer i = 100;
//编译程序会自动将上面代码展开为:
Integer i = Integer.ValueOf(100);
使用 Integer.valueOf()也是基本类型建立打包器的方式之一。
null 代表一个特殊对象,任何类声明的参考名称都可以参考至 null,表示该名称没有参考至然后对象实体。
Integer i2 = null;
int j = i2;
因为 i2 并没有参考任何对象,所以根本使用不了 intValue()方法。
最后这个装箱看起来也是迷迷茫茫的,看来还得再研究研究。。。
Java真难哦。。。。
PS:参考书籍 Java jdk7 学习笔记 ,Java 核心技术卷 I