文章目录
- 1.类的抽象和封装
- 2.面向对象的思想
- 3.类的关系
- 3.1 关联
- 3.2 聚集和组合
- 4.包装类
- 4.1 Integer和Double
- 4.2 自动装箱和自动拆箱
- 4.3 Biginteger 和 BigDecimal类
- 4.4 String 类
- 4.4.1 创建
- 4.4.2 不可变字符串与驻留字符串
- 4.4.3 替换和拆分字符串
- 4.4.4 使用模式匹配、替换和拆分
- 4.4.5 字符串与数组之间的转换
- 4.4.6 将字符和数值转换成字符串
- 4.4.7 格式化字符串
- 4.5 StringBuilder 类和 StringBuffer 类
1.类的抽象和封装
类的抽象是指将类的实现和类的使用分离开,实现的细节被封装并且对用户隐藏,这被称为类的封装。
类抽象 是将类的实现和使用分离。类的创建者描述类的功能,让使用者明白如何使用类。从类外可以访问的 public 构造方法、普通方法和数据域的集合以及对这些成员预期行为的描述,构成了类的合约。
类的使用者不需要知道类是如何实现的。实现的细节通过封装对用户隐藏起来,这称为类的封装。由于这个原因,类也称为抽象数据类型(abstract Data Type, ADT) 。
可以使用一张UML图。
2.面向对象的思想
面向过程的范式重点在于设计方法。面向对象的范式将数据和方法耦合在一起构成对象。使用面向对象范式的软件设计重点在对象以及对象上的操作。
public class BMI{private String name;private int age;private double weight;private double height;public BMI(String name,int age,double weihgt,double height){this.name = name;this.age = age;this.weight = weight;this.height = height;}public BMI(String name,double weight,double height){this(name,20,weight,height);}public double getBMI(){...};public String getStatus(){double bmi = getBMI();if(bmi < 18.5)return "Underweight";else if(bmi < 25)return "Normal";else if(bmi<30)return "Overweight"else return "Obese";}public String getName(){return name;}public String getAge(){return age;}public String getWeight(){return weight;}public String getHeight(){return height;}
}
在面向过程程序设计中,数据和数据上的操作是分离的,而且这种做法要求传递数据给方法。面向对象程序设计将数据和对它们的操作都放在一个对象中。这个方法解决了很多面向过程程序设计的固有问题。面向对象程序设计方法以一种反映真实世界的方式组织程序,在真实世界中,所有的对象都和属性及动作相关联。使用对象提高了软件的可重用性,并且使程序更易于开发和维护。Java 程序设计涉及对象这个术语的思想,一个 Java 程序可以看作是一个相互操作的对象集合。
3.类的关系
为了设计类,需要探究类之间的关系。类之间的关系通常有关联、聚合、组合以及继承。
3.1 关联
关联中涉及的每个类可以给定一个多样性 (multiplicity), 放置在类的边上用于给定 UML图中关系所涉及的类的对象数。多样性可以是一个数字或者一个区间,决定在关系中涉及该类的对象数。字符* 意味着无数多个对象,而 m…n 表示对象数位于 m 和 n 之间,并且包括m 和 n。
public class Student{private String name;private Course[] courseList;public void addCourse(Course c){...};
}public class Faculty{private String name;private Course[] courseList;public void addCourse(Course c){...};
}public class Course{int time;String name;private Students[] classlist;private Faculty faculty;public void addStudent(Student s){...};public void setFaculty(Faculty f){...};
}
3.2 聚集和组合
聚集是关联的一种特殊形式,代表了两个对象之间的归属关系。聚集对 has-a 关系进行建模。所有者对象称为聚集对象,它的类称为聚集类。而从属对象称为被聚集对象,它的类称为被聚集类。
如果被聚集对象的存在依赖聚集 对象,我们称这 两个对象之间的关系为组合( composition)。 换句话说,被聚集对象不能单独存在。
组合暗示了独占性的拥有。一个对象拥有另外一个对象:当拥有者对象销毁了,依赖对象也会销毁。在 UML 中,附加在聚集类(例如:Student)上的实心菱形表示它和被聚集类(例如:Name)之间具有组合关系;而附加在聚集类(例加:Student)上的
空心菱形表示它与被聚集类(例如:Address)之间具有聚集关系
在图 10-6 中,每个学生只能有一个地址,而每个地址最多可以被 3 个学生共享。每个学生都有一个名字,而每个学生的名字都是唯一的。
4.包装类
基本数据类型值不是对象,但是可以使用 Java API 中的包装类来包装成一个对象。
出于对性能的考虑,在 Java 中基本数据类型不作为对象使用。因为处理对象需要额外的系统开销,所以,如果将基本数据类型当作对象,就会给语言性能带来负面影响。
然而,Java 中的许多方法需要将对象作为参数。Java 提供了一个方便的办法,即将基本数据类型合并为或者说包装成对象 (例如,将 int 包装成 Integer 类,将 double 包装成 Double 类,将 char 包装成 Character 类)。通过使用包装类,可以将基本数据类型值作为对象处理。
Java 在 java.lang 包里为基本数据类型提供了 Boolean、Character、Double、Float、Byte、Short、Integer 和 Long 等包装类。
大多数基本类型的包装类的名称与对应的基本数据类型名称一样,第一个字母要大写。对应int 的 Integer 和对应 char 的 Character 例 外
数值包装类相互之间都非常相似。每个都各自包含了 doubleValue()、floatValue()、intValue()、 longValue() 、shortValue()和 byteValue()等方法。这些方法将对象 “转换”为基本类型值。
4.1 Integer和Double
包装类没有无参构造方法。所有包装类的实例都是不可变的,这意味着一旦创建对象后,它们的内部值就不能再改变。
每一个数值包装类都有常量 MAX_VALUE 和 MIN_VALUE。MAX_VALUE 表示对应的基本数据类型的最大值。对于 Byte、Short. Integer 和 Long 而言,MIN_VALUE 表示对应的基本类型byte、short 、int 和 long 的最小值。对 Float 和 Double 类而言,MINJALUE 表示 float 型和 double 型的最小正值。
每个数值包装类都包含各自方法doubleValue(),floatValue() ,intValue() ,longValue()和 shortValue()。这些方法 返回包装对象对应的 double ,float,int,long或short 值。
数值包装类中包含compareTo 方法用于比较两个数值,并且如果该数值大于、等于或者小于另外一个数值时,分别返回1、0、 -1。
数值包装类有一个有用的静态方法 value0f(String s)。该方法创建一个新对象,并将它初始化为指定字符串表示的值。
new Double(12.5).intValue(); // 12new Double(2).compareTo(new Double(2)); // 0Integer intnum = Integer.valueOf("12"); // 12
Integer 类中的 parselnt 方法将一个数值字符串转换为一个 int 值。每个数值包装类都有两个重载的方法,将数值字符串转换为正确的以 10 (十进制) 或指定值为基数(例如,2 为二进制,8 为八进制,16 为十六进制) 的数值。
public static int parseint (String s)
public static int parseint (String s , int radix)// 例如:
Integer.parseInt("11",2) // 3
// 另外,可以使用 format 方法将一个十进制数转换为十六进制数
String.format("%x",26) // 1A
4.2 自动装箱和自动拆箱
根据上下文环境,基本数据类型值可以使用包装类自 动转换成一个对象,反之也可以。
将基本类型值转换为包装类对象的过程称为装箱 ( boxing), 相反的转换过程称为拆箱(unboxing)。
Java 允许基本类型和包装类类型之间进行自动转换。如果一个基本类型值出现在需要对象的环境中,编译器会将基本类型值进行自动装箱;如果一个对象出现在需要基本类型值的环境中,编译器会将对象进行自动拆箱。这称为自动装箱和自动拆箱。
//下面两者等价
Integer a = new Integer(2);
Integer a = 2;//下面两者等价
int i = 0;
int i = Integer(0);
4.3 Biginteger 和 BigDecimal类
如果要进行非常大的数的计算或者高精度浮点值的计算,可以使用 java.math 包中的Biginteger 类和 BigDecimal 类。它们都是不可 变的。long 类型的最大整数值为 long.MAX_VALUE (即 9223372036854775807), 而 Biginteger 的实例可以表示任意大小的整数。
可以使用 new Biginteger(String) 和 new BigDecimal (String) 来创建 Biginteger 和 BigDecimal的实例,使用 add、subtract、multiple、divide 和 remainder 方法进行算术运算,使用compareTo 方法比较两个大数字。
BigInteger a = new BigInteger("343435135133435433");
BigInteger b = new BigInteger("45");
BigInteger c =a.multiply(b);
BigDecimal 对象可以达到任意精度。如果不能终止运行,那么 divide 方法会抛出ArithmeticException 异常。但是,可以使用重载的 divide(BigDecimal d,int scale, int roundingMode) 方法来指定scale值和舍入方式来避免这个异常,这里的 scale 是指小数点
后最小的整数位数。
BigDecimal a = new BigDecimal("343435135133435433");
BigDecimal b = new BigInteger("45");
BigDecimal c =a.divide(b,20,BigDecimal.ROUND_UP);
4.4 String 类
4.4.1 创建
String newString = new String(stringLiteral);String message = new String("Weicome to Java");String message = "Weicome to Java";chart] charArray = {'G*, '0' , 'o*, 'd' , ' ', 'D*, 'a', 'y'};
String message = new String(charArray);
4.4.2 不可变字符串与驻留字符串
String 对象是不可改变的。字符串一旦创建,内容不能再改变。
String s = "Java";
s = "HTML";
第一条语句创建了一个内容为”Java" 的 String 对象,并将其引用赋值给s。第二条语句创建了一个内容为”HTML” 的新 String 对象,并将其引用赋值给 s。赋值后第一个 String 对象仍然存在,但是不能再访问它了,因为变量 s 现在指向了新的对象。
因为字符串在程序设计中是不可变的,但同时又会频繁地使用,所以 Java 虚拟机为了提高效率并节约内存,对具有相同字符序列的字符串字面值使用同一个实例。这样的实例称为驻留的 (interned) 字符串。
String s1 = "Welcome to Java";
String s2 = new String("Weicome to Java" ) ;
String s3 = "Welcome to Java";
System.out.printin("s1 == s2 is " + (s1 == s2) ) ;
System.out.println("s1 == s3 is " + (s1 == s3) ) ;// s1 == s2 is false
// s2 == s3 is true
4.4.3 替换和拆分字符串
"Wei come",replace('e', 'A' );
"Wei come".replaceFirst ("e", "AB") ;
"Weicome".replace ("e", "AB");
"Weicome".replace("el", "AB" );String[] tokens = "Java#HTML#Perl".split("#") ;
for (int i = 0; 1 < tokens.length; i++)System.out.print (tokens[i] + " ") ;
4.4.4 使用模式匹配、替换和拆分
正则表达式 (regularexpression)(缩写regex) 是一个字符串,用于描述匹配一个字符串集的模式。可以通过指定某个模式来匹配、替换或拆分一个字符串。这是一种非常有用且功能强大的特性。
"Java".matches("Java") ;
"Java".equals("Java") ;
matches 方法的功能更强大。它不仅可以匹配固定的字符串,还能匹配一组遵从某种模式的字符串,具体可以专门学习正则表达式。
4.4.5 字符串与数组之间的转换
字符串不是数组,但是字符串可以转换成数组,反之亦然。为了将字符串转换成一个字符数组,可以使用 toCharArray 方法。
char[] chars = "java".toCharArray();String str = new String(new char[]{'a','b'});
String str = new String(chars);
4.4.6 将字符和数值转换成字符串
4.4.7 格式化字符串
String 类包含静态方法 format, 它可以创建一个格式化的字符串。
String. format(format , iteml, item2 itemk);String s = String.format( "%7.2f%6d%-4s", 45.556, 14, "AB");
System.out.println(s);
4.5 StringBuilder 类和 StringBuffer 类
StringBuilder 和 StringBuffer 类似于 String 类,区 别在于 String 类是不可改变的。
一般来说,使用字符串的地方都可以使用 StringBui1der/StringBuffer 类。StringBuilder/StringBuffer 类比 String类更灵活。可以给一个 StringBuilder 或 StringBuffer 中添加、插入或追加新的内容,但是 String 对象一旦创建,它的值就确定了
StringBuffer 和StringBuilder 中的构造方法以及其他方法几乎是完全一样的。
具体使用见官方文档或其他资料