类的重用
软件重用是提高软件质量及开发效率的有效途径,面向对象的分析和编程技术为软件重用提供了新的手段。面向对象开发方法得以流行的原因之一就是基于类和对象的重用比传统程序的重用更容易。
类的继承
继承是一种由已有的类创建新类的机制,是面向对象程序设计的基石之一。一个新类可以从现有的类中派生,这个过程称为类继承。通过继承,一个类可以拥有自己已有类的所有功能。
Java要求声明的每个类都有父类,当没有显式指定父类时,父类隐含为java.lang中的Object类。一个父类可以同时拥有多个子类,这时这个父类实际上是所有子类的公共属性及方法的集合,而每一个子类则是父类的特殊化,是公共属性的基础上的功能、内涵的扩展和延伸。
Java不支持类的多重继承,只支持类的单继承,即每个子类只能有一个直接父类,类的层次结构为树状结构,Object类为树的根节点。
Java虽然只支持类的单继承,但可通过实现接口来实现多继承功能。
[ClassModifier] class ClassName[extends SuperClassName][implement interface]{
//类体
}
其中,关键字extends说明要声明的类需要继承父类的属性和行为,SuperClassName是被继承的父类名称。
公有(及保护)属性及行为的继承
public class Person {
public String name;
public String getName() {
return name;
}
}
public class Employee extends Person {
public int employeeNumber;
public int getEmployeeNumber(){
return employeeNumber;
}
}
public class Manager extends Employee{
public String responsibilities;
public String getResponsibilities(){
return responsibilities;
}
}
public class Tester {
public static void main(String args[]){
Employee zhang=new Employee();
zhang.name="张三";
zhang.employeeNumber=123456;
System.out.println(zhang.getName());
System.out.println(zhang.getEmployeeNumber());
Manager li=new Manager();
li.name="李四";
li.employeeNumber=789012;
li.responsibilities="Java开发";
System.out.println(li.getName());
System.out.println(li.getEmployeeNumber());
System.out.println(li.getResponsibilities());
}
}
输出:
张三
123456
李四
789012
Java开发
子类不能直接访问父类中继承的私有属性及方法,但可以使用公有(及保护)方法进行访问。
私有属性及方法的继承
B.java
public class B {
public int a=10;
private int b=20;
protected int c=30;
public int getB(){
return b;
}
}
A.java
public class A extends B {
public int d;
public static void main(String args[]){
A t=new A();
System.out.println(t.a);
System.out.println(b);//报错
System.out.println(t.getB());
}
}
对类A进行编译时,系统会提示错误:
b是从类b中继承来的,由于b是私有属性,不能在A类中直接存取,但可以使用继承来的共有方法getB()获得。
隐藏与覆盖
隐藏与覆盖是指子类对从父类继承来的属性变量及方法可以重新加以定义。
1、属性的隐藏
子类对从父类继承来的属性变量重新加以定义,则从父类继承来的属性将被隐藏。
class A {
int x=2;
public void setx(int i){
x=i;
}
void printa(){
System.out.println(x);
}
}
class B extends A{
int x=100;
void printb(){
super.x=super.x+10;
System.out.println("super.x"+super.x+" x="+x);
}
}
public class Tester {
public static void main(String args[]){
A a1=new A();
a1.setx(4);
a1.printa();
B b1=new B();
b1.printb();
b1.printa();
b1.setx(6);
b1.printb();
b1.printa();
a1.printa();
}
}
输出结果:
4
super.x12 x=100
12
super.x16 x=100
16
4
注意,子类并不能继承父类中的静态属性,但可以对父类中的静态属性进行操作。
可以在int x=2前加一个static,再运行看看结果。
包的应用
Java提供了用于语言开发的类库,称为Java基础类库,也称为应用程序编程接口,分别放在不同的包中。Java提供的包住要有:java.long、java.io、java.math、java.util、java.applet、java.awt、java.awt.datatransfer、java.awt.event、java.awt.image、java.beans、java.net、java.rm、java.security、java.sql。
语言包java.long
1、数据类型包裹类;
对应Java的每一个基本数据类型都有一个数据包裹类。每个包裹类都有只有一个类型为对应的基本数据类型的属性域。
double x=1.2;
Double a=new Double(x);
Integer.valueOf("125");
2、常量字符串类String;
Java将字符串作为类来实现,而不强制使用字符数组。字符串有两个类:String和StringBuffer。String类的字符串对象的值和长度都不变化,称为常亮字符串;StringBuffer类的字符串对象的值和长度都可以变化,成为变量字符串。
String aString;
aString=new String("this is a string .")
String name="";
字符串对象的每一个字符都有一个位置序号(index),第一个字符的index值为0,第二个字符的index值为1…依此类推。但由于字符串对象不是数组,因此不能使用下标操作符对字符进行存取。
3、变量字符串类(StringBuffer)
StringBuffer类的对象是可以修改的字符串,与String类的对象相比,其执行效率要低一些。
new StringBuffer();//生成容量为16的空字符串对象
new StringBuffer(int size);//生成容量为size的空字符串对象
new StringBuffer(String aString);//生成aString的一个备份,其容量为其长度+16
StringBuffer类具有下面的方法;
int length();//返回字符串对象的长度
int capacity();//返回字符串对象的容量
void ensureCapacity(int size);//设置字符串对象的容量
void setLength(int len);//设置字符串的长度。如果len的值小于当前字符串的长度,则尾部被截掉
char charAt(int len);//返回index处的字符
void setCharAt(int index,char c);//将index处的字符设置为c
void getChars(int start,int end,char[] charArray,int newStart);
//将接收者对象从start位置到end-1位置的字符复制到字符数组charArray中,从位置newStart开始存放
StringBuffer reverse();//返回将接收者字符串逆转后的字符串
StringBuffer insert(int index,Object ob)//将ob插入到index位置
StringBuffer append(Object ob);//将ob连接到接收者字符串的末尾
举例,去掉非字母字符。
public class StringEditor {
public static String removeNonletters(String original){
StringBuffer aBuffer=new StringBuffer(original.length());
char aCharacter;
for (int i=0;i<original.length();i++){
aCharacter=original.charAt(i);
if(Character.isLetter(aCharacter)){
aBuffer.append(new Character(aCharacter));
}
}
return new String(aBuffer);
}
}
public class StringEditorTester {
public static void main(String args[]){
String original="hell0123,java.myname is jack.";
System.out.println(StringEditor.removeNonletters(original));
}
}
输出结果:
helljavamynameisjack
4)数学类(Math)
数学类Math提供了一组常量和数学方法,包括E和PI常数,求绝对值的abs方法,计算三角函数的sin方法和cos方法,求最小值、最大值的min方法和max方法,求随机数的random方法等。
public class mathTest {
public static void main(String args[]){
System.out.println("Math.round(6.6): "+Math.round(6.6));
System.out.println("Math.round(6.2): "+Math.round(6.2));
System.out.println("Math.ceil(9.2): "+Math.ceil(9.2));
System.out.println("Math.ceil(-6.6): "+Math.ceil(-6.6));
System.out.println("Math.floor(9.1): "+Math.floor(9.1));
System.out.println("Math.floor(-9.6): "+Math.floor(-9.6));
System.out.println("Math.sqrt(144): "+Math.sqrt(144));
System.out.println("Math.pow(5,2): "+Math.pow(5,2));
System.out.println("Math.exp(2): "+Math.exp(2));
System.out.println("Math.log(7.38905609893065): "+Math.log(7.38905609893065));
System.out.println("Math.min(9.1,10): "+Math.min(9.1,10));
System.out.println("Math.random(): "+Math.random());
}
}
输出:
Math.round(6.6): 7
Math.round(6.2): 6
Math.ceil(9.2): 10.0
Math.ceil(-6.6): -6.0
Math.floor(9.1): 9.0
Math.floor(-9.6): -10.0
Math.sqrt(144): 12.0
Math.pow(5,2): 25.0
Math.exp(2): 7.38905609893065
Math.log(7.38905609893065): 2.0
Math.min(9.1,10): 9.1
Math.random(): 0.5750856507353048
实用包
实用包java.util提供了实现各种不同实用功能的类,包括日期、集合类。
1)日期类
日期类包括Data、Calendar、GregorianCalendar类,它们描述日期和时间。
Data类有两种构造方法:Date( )和Date(long date)。Date( )获得系统当前日期和时间值。如:
import java.util.Date;
public class mathTest {
public static void main(String args[]){
Date today=new Date();
System.out.println(today);
}
}
输出结果:
Sat Dec 18 19:02:44 CST 2021
Date(long date)以date创建日期对象,date表示从GMT时间1970-1-1 00:00:00开始至某时刻的毫秒数。
Date类提供了以下常用方法:
getTime();//返回一个长整型表示时间,单位为毫秒(millisecond);
after(Date d);//返回接收者表示的日期是否再给定的日期之后;
before(Date d);//返回接收者表示的日期是否在给定的日期之前;
Calendar是一个抽象的基础类,支持将Date对象转换成一系列单个的日期整型数据集,如YEAR、MONTH、DAY、HOUR等常量。Calendar类派生的GregorianCalendar类实现标准的Gregorian日历。但由于Calendar是抽象类,不能用new方法生成Calendar的实例对象,可以使用get Instance()方法创建一个GregorianCalendar类的对象。
java.util.GregorianCalendar类用于查询及操作日期,下面是一些构造方法;
new GregorianCalendar();
new GregorianCalendar(2021,12,18);
new GregorianCalendar(2000,0,8,11,55);
代码示例:
import java.util.GregorianCalendar;
public class Test {
public static void main(String args[]){
System.out.println("new GregorianCalendar().getTime(): "+new GregorianCalendar().getTime());
System.out.println("new GregorianCalendar(2021,12,18).getTime(): "+new GregorianCalendar(2021,12,18).getTime());
System.out.println("new GregorianCalendar(2000,0,8,11,55).getTime(): "+new GregorianCalendar(2000,0,8,11,55).getTime());
}
}
输出结果:
new GregorianCalendar().getTime(): Sat Dec 18 23:32:30 CST 2021
new GregorianCalendar(2021,12,18).getTime(): Tue Jan 18 00:00:00 CST 2022
new GregorianCalendar(2000,0,8,11,55).getTime(): Sat Jan 08 11:55:00 CST 2000
2)集合类
主要包括Collection(无序组合)、Set(不重复组合)、List(有序不重复集合)、Enumeration(枚举)等,以及表示数据结构的多个类:LInkedList(链表)、Vector(向量)、Stack(栈)、Hashtable(哈希表)、TreeSet(树)等。
3)StringTokenizer类
java.util.StringTokenizer类允许以某种分隔标准将字符串分隔成单独的字字符串,如可以将单词从语句中分离出来。术语分隔符(delimeter)是指用于分隔单词(也称为标记,tokens)的字符。
示例代码:
import java.util.StringTokenizer;
public class Token {
public static void main(String [] args){
String s="3.6*2+(-1.2)-5";
StringTokenizer st=new StringTokenizer(s,"+-/*)(",true);
//hasMoreElements()返回是否还有单词
while (st.hasMoreElements()){
System.out.println(st.nextToken());//nextToken()将单词逐个取出
}
}
}
输出结果:
3.6
*
2
+
(
-
1.2
)
-
5