2005年05月29日

import java.util.*;
public class ArrayListTest{
 public static void main(String dd[]){
  //new了一个存储list
  List l=new ArrayList();
  //因为Collection framework只能存储对象所以new封装类
  l.add(new Integer(1));
  l.add(new Integer(2));
  l.add(new Integer(3));
  l.add(new Integer(4));
  
  Iterator it=l.iterator();
  //hasNext是取值取的是当前值.他的运算过程是判断下个是否有值如果有继续.
  while(it.hasNext()){
   //设it.next封装类,调用Integer的intValue方法返回值为int赋给i;
   int i=((Integer)it.next()).intValue();
   System.out.println("Element in list is :  "+i);
  }
 }
}

//构造寄存异常类Ex继承父类Exception
class   Ex extends Exception{
 public Ex(String message){
  //继承父类message
  super(message);
 }
}
//构造异常类源
class Es{
 //声明可能有异常的方法
 static void aa()throws Ex{
  int b=3;
  //在可能出现异常的语句抛出异常给Ex显示错误信息error
  if (b==3)throw new Ex("error");
  {
  }
 }

public static void main(String arg[]){
 //捕捉异常
  try{
   //在类中引用方法直接方法名()
   aa();
  }catch(Ex e){
   //捕捉异常并显示错误信息
   System.out.println("lalaaalalallalaalla");
   //产生的Ex类中的错误信息
   System.out.println(e.getMessage());
   //显示异常出现位置
   e.printStackTrace();
  }
}
}

//exception
//这步是建立异常抛出类
class  Rr extends Exception{
 }

//Scource异常源
class Ro{
 // 如果有异常则抛出到Rr类
 //在方法后声明
 void o() throws Rr{
 int c=4;
 //在可能抛出异常的语句后抛出
 if (c!=5) throw new Rr();
 }
 }
class Rp{
 public static void main(String d[]){
 //捕捉异常try{}catch(Rr e)<-抛到Rr给新的名字e
 try{
  new Ro().o();
 }catch(Rr e){
  //如有异常抛出显示lala
 System.out.println("lala");
 }
 }
 }

class  ToStringFun{
  /*用toString方法覆盖Object的toString方法(这是OVERRIDDEN)
     这样当实例创建调用方法时,则是调用已经覆盖后方法的内容
  */
     public String toString(){
   //(" "+)是把数字转换字符
  return ""+456451+"拉拉";
}
 public static void main(String[] args) {
  //先建实例为了成员方法的调用(不是static的方法都是成员方法)
   ToStringFun fun=new ToStringFun();
  //h是局部变量(在方法中定义的变量叫局部变量);把对象fun用方法toString得到的值赋予h;
  String h=fun.toString();
  //输出变量h
  System.out.println(h);
 }
 
}

//讲解equals的用法
class Equals{
 //main
 public static void main(String dd[]){
  //创建实例
 String n1=new String("hello");
 String n2=new String("hello");
  //使用equals如果内容一样则返回true反之是false.
 System.out.println(n1.equals(n2));

 }
 }

//建一个A类
class A{
 //成员变量 其中num是实参
int num=0;
   //成员方法,其中 i 是型参
 public A(int i){
  //输入int型文件输出下面
  System.out.println("aaaaaaaaaaaaaaaaaaa");
  System.out.println("i=  "+i);
  //把输入的i赋值给成员变量num
  num=i;
  }
  
 }
 //B继承A
class B extends A{
 int num=0;
 //成员方法B.
 public B(){
  //继承类A的方法.因为B继承了A必然继承了A的特性.所以输入int值10令方法实现.
 super(10);
 System.out.println("bbbbbbbbbbbbbbbbbbbb");
 //这里的num是类B的.
 System.out.println("num=  "+num);
 //如果想显示类A的num则需要用下列的super.num.这里注意num在类A中需是成员变量才可以.
 System.out.println("super.num= "+super.num);
 }
 }
 //建立测试类C
public class C{
 //main
 public static void main(String aa[]){
  //new 一个对象B()
  new B();
  }
  }
  

//建立Cource类
class Course{
 //封装开始
 private String name ;
 private String id ;
 
 public Course( String name , String id ){
  this.name = name ;
  this.id = id ; 
 }//封装结束
 //方法
 public String getName(){
   return name ;
   }
 public void setName( String name ){
  this.name = name ;
  }
 public String getId(){
   return this.id ;
   }
 public void setId( String id ){
   this.id = id ;
   }
 //toString方法
 public String toString(){
  return "Course[ id= " + id +" , name= " + name + " ] "; 
 }
}
//建立Score类
 class Score{
  //封装
 private Course course ;
 private float grade;
 
 public Score( Course course , float grade ){
  this.course = course ;
  this.grade = grade ; 
 }//封装结束
 //声明方法
 public void setCourse( Course c ){
   this.course = c ;
   }
 public Course getCourse( ){
   return course ;
   }
 public void setGrade( float g ){
  grade = g ;
   }
 public float getGrade( ){
   return grade ;
   }
}

//建Student类
class Student{
 //封装
 private String name ;
 private String id ;
 private Score[] scores  ;
 
 private int scoresNumber = 0 ;
 
 public Student( String id , String name ){
  this.id = id ;
  this.name = name ;
  this.scores = new Score[ 10 ] ; 
 }//封装结束
 
 //判断scores容量是否饱和.如果饱和退出.否则继续添加数据
 public boolean addScore( Score s ){
  if( scoresNumber == 10 ){
   return false ; 
  } 
  
  scores[ scoresNumber++ ] = s ;
  return true;
 }
 //算Sum..i为下标
 private float getSum(){
  float sum = 0 ;
  for( int i = 0 ; i < scoresNumber ; i++ ){
   //把每个元素的Grade相加在一起
   sum += scores[i].getGrade();
  }
  //当i>scoresNubmer时循环退出把sum返回给sum
  return sum ;
 }
 //算平均值
 public float getAVG(){
  //如果scoresNubmer等于0.(也就是没有对象时)返回0;
  if( scoresNumber == 0 ){
   return 0 ; 
  }
  //否则用对象的grade之和除以scoresNubmer得到平均值.
  return getSum() / scoresNumber ;
 }
 //判断平均值是否达到90达到为ture.反之flase;
 public boolean isSuperStudent(){
  return getAVG() > 90 ; 
 }
 public boolean isSuperStudent2(){
  return getAVG()>80;
 }
 
}


//以下为测试类.
public class Test{
 public static void main( String[] args ){
  Course java = new Course( "001" , "java" );
  Course oracle = new Course( "002" , "oracle" );
  Course jdbc = new Course( "003" , "jdbc" );
  
  Student stu = new Student( "001" , "Tom" );
  Student stu2 = new Student( "002" , "Lala" );
  
  Score javaScore = new Score( java , 90 );
  Score oraScore = new Score( oracle , 100 );
  Score jdbcScore = new Score( jdbc , 70 );
  
  stu.addScore( javaScore );
  stu.addScore( oraScore );
  stu.addScore( jdbcScore );
  
  stu2.addScore( javaScore );
  stu2.addScore( oraScore );
  stu2.addScore( jdbcScore );
  
  System.out.println( "stu AVG   = " + stu.getAVG() );
  System.out.println( "stu super = " + stu.isSuperStudent() );
  
  System.out.println( "stu2 AVG   = " + stu2.getAVG() );
  System.out.println( "stu2 super = " + stu2.isSuperStudent2() );  
 }
}

//构造类的方法:

//首先class declare

class Person{
          //member variable
 private String name;
 private int age;
          //abstructor  method
 public Person(String name){
 this.name=name;
 }
          //Overloading
 public Person(String name,int age){
 this(name);
 this.age=age;
 }
         //member method
   
 public String getName(){
 return name;
 }
 public int getAge(){
 return age;
 }
 
      //main
 public static void main(String dd[]){
 Person one=new Person("lala",22);
 Person two=new Person("nono");
 System.out.println("one: "+one.getName()+one.getAge());
 System.out.println("two: "+two.getName());
 }

2005年05月21日

第二次:修饰符

2.1 访问控制
封装将数据和处理数据的代码连接起来。同时,封装也提供了另外一个重要属性:访问控制。通过封装你可以控制程序的某个部分可以访问类的成员,防止对象的滥用,从而保护对象中数据的完整性。对于所有的面向对象的语言,比如C++,访问控制都是一个很重要的方面。由于Java语言使用了包的概念,使它的访问控制相对来说更复杂一些。我们把控制访问控制权限的修饰符主要分为两类,类和它的方法及变量,下面我们分别简单介绍。

-类的访问控制

-> Default:当类不使用任何访问控制修饰符时,即采用的默认的访问控制权限。它允许同一个包内的类访问,而对于它所在包以外的类则不能访问。

-> Public:允许任何包中的任何类访问,对Java里面的所有类开放。

-方法和变量的访问控制

-> Public:所有类均可以访问。

-> Private:只能被它所在的类中的成员访问,使该定义的成员对外在的类不可见。

-> Protected:可以被同一个包的类访问,另外其所有子类也可以访问。

-> Default:当成员不使用任何访问控制修饰符时,即采用默认的访问控制权限。它和Protected类似,唯一的区别在于子类访问权限,它仅允许同一个包的子类访问,而其他包中的子类则不可以访问。

2.2 其他修饰符
除了访问控制修饰符,Java还有其他繁多的修饰符来声明类、方法和变量,下面分别针对所修饰的对象来简单介绍一下主要的修饰符。

-类修饰符

-> final:用来指定该类不能被其他类扩展,从而阻止继承。

-> abstract:表示该类是不允许被实例化的类,也就是说该类需要被扩展继承。被这样声明的类也称为抽象类。

显而易见,final和abstract不能同时使用。

-方法修饰符

-> abstract:被声明的方法称为抽象方法,不含任何代码,需要其继承的子类的相应方法覆盖重载。这里需要注意的是被声明有abstract方法的类必须被声明为abstract。

-> final:声明的方法不允许被覆盖重载。

-> static:声明的方法被成为类方法,不依赖于任何的对象,不需要实例化对象即可直接使用类名来调用该方法。注意的是在该方法体内不可访问实例变量。

-> 变量修饰符

-> static:被声明为static的变量实际可以看作就是全局变量,同样不需要实例化对象即可直接使用类名来引用之。

-> final:被声明的变量的内容不可以被修改,实际可以被看作是一个常量,类似于C或者C++中的const。

2.3 缺省构造函数
我们都知道当对象被实例化的时候,构造函数总是被调用。如果我们在定义类的时候不指定一个构造函数,Java会自行创建一个不带参数的缺省构造函数。而如果我们定义有了一个构造函数,则Java不会再创建缺省构造函数。

更值得注意的是,如果子类的超类不含有不带参数的构造函数,那么子类在使用缺省构造函数就会出错,Java不会为子类创建不带参数的缺省构造函数。因此,我们在使用缺省构造函数的时候要比较小心。我们可以看如下的例子:


代码:
class Fruit {

    public Fruit ( String color ) {

       System.out.print ( “color = ” + color ) ;

    }

}

class Apple extends Fruit {

    public static void main ( String [ ] args ) {

       Apple m = new Apple () ;

       }

}


运行结果出错:

Fruit.java:6: No constructor matching Fruit ( ) found in class Fruit .

Class Apple extends Fruit {

1 error

2.4 合法的返回类型
由于在方法调用的时候,方法返回的类型有可能与实际声明的类型不同,因此我们需要关心什么样的返回类型才是合法的。实际上,系统采用了隐式的类型转换来处理类型的返回。以下几种情况的是合法的:

-> 如果声明的是浮点类型,那么可返回整型类型。

-> 如果声明的是整型类型,那么只要返回的整型类型范围小于或等于声明的类型,返回合法。

-> 如果声明的是对象类型,那么只要返回的是该对象类型,或者是其子类的对象类型,合法。


第三次:JAVA运算符
3 运算符
同大多数的编程语言一样,Java语言也包含了许多的运算符。如果大家学习过C或者C++,会发现下面介绍的各种Java的运算符都与之类似。
3.1.1 赋值运算符 =
这是任何编程语言的最基本的运算符,它用来给变量指定一个值。对于基本类型来说,赋值都便于理解,将新的值赋给变量并保存在变量中供使用。但对于对象类型来说,这里就有一点区别,特别需要提醒大家注意。

对象类型并不是把实际的值(这里是实例)赋给了对象类型的变量,而是赋给的一个参考指针。这样,源对象类型的变量和新的这个变量实际上是指向的同一个实例,如果使用其中一个让实例改变,那么相应的另一个所指向的实例也会改变。这里我们可以借用C里面的指针的概念来方便理解,但实际上Java是不具有指针的概念和定义的。

我们通过下面的例子可以进一步来理解这个概念。


代码:
import java.awt.Dimension;
class ReferenceTest {
  Dimension a = new Dimension ( 5,10 );
  System.out.println (“a.height = ” + a.height ) ;
  Dimension b = a ;
  b.height = 30 ;
  System.out,println (“a.height = ” + a.height + “after change to b ”);
}
}


运行结果:

c:\java Project\Reference>java ReferenceTest

a.height = 10

a. height = 30 afer change to b

另外,赋值运算符还可以和其他的运算符,联合组成新的赋值符。如*=、/=、+=、-=等等,这于C或者C++类似。

3.1.2 比较运算符
比较运算符是用来对相同数据类型的变量进行大小或者是否相等、相同的比较,返回的是Boolean类型的值。因此也就大概分为两类。

n >、>=、<、<=

这是比较变量的大小关系,与我们学过的任何编程语言相同,就不再介绍了。

n = = 、! =

这是比较变量是否相等或相同。这对于平常的比较基本类型的变量容易理解,只是我们要强调一下对对象类型的比较。与我们前面介绍的赋值运算符类似的是,它也是进行的对其参考指针的比较,而并不是比较两个内容上的差别。我们可以借助下面的例子来理解。


代码:
import java.awt.Button
class CompareRefernce {
    public static void main ( String [ ] args ) {
       Button a = new Button ( “Exit”);
       Button b = new Button ( “Exit”);
       Button c = a;
       System.out.println ( “Is refernce a = = b ? ” + ( a = = b) ) ;
       System.out.println ( “Is refernce a = = c ? ” + ( a = = c) ) ;
}
}



运行结果:

Is refernce a = = b ? false

Is refernce a = = c ? true

3.1.3 instanceof运算符
这个是Java语言特殊的一个运算符,它是用来测试其对象是否属于某类或其超类。但是这里需要提醒大家的是,如果你使用instanceof来比较不是一个继承关系树上的类,Java能够编译通过,但运行的时候会报错。另外,你可以对null对象使用这个运算符,只是无论对于什么类测试的结果都是false。

3.1.4 算术运算符
加+、减-、乘*、除/和取模%运算,这与其他的编程语言类似,不再详述。

3.1.5 自增++、自减–运算符
Java的自增和自减运算符,与C语言类似,同样需要注意的是其放置的位置不同,可能的结果也不同。如果放置在变量的前面,表示先自增(减)再参与下步运算,而如果放置在后面则表示先参与运算再自增(减)。如下的例子说明了自增运算符的使用:


代码:
class IncDec{
    public static void main ( String [ ] args ) {
       int a = 1;
       int b = 1;
       int c;
int d;
c = ++b;
d = a++;
c++;
       System.out.println ( “a = ” + a );
       System.out.println ( “b = ” + b );
       System.out.println ( “c = ” + c );
       System.out.println ( “d = ” + d );
}
}



运行结果:

a = 2
b = 2
c = 3
d = 1

3.1.6 字符串连接运算符 +
Java语言与C语言类似,也使用+作为连接字符串的运算符,这实际是对String类重载了+运算符。

3.1.7 位运算符
包括位移运算和位逻辑运算,这也与C语言相似。

-> 位移运算

>>右移、<<左移、>>>无符号右移。

-> 位逻辑运算

&与、|或、^异或、~非运算,这于其他的编程语言类似,不再详述。

3.1.8 逻辑运算符
与&&、或||,这于其他的编程语言类似,不再详述。只是需要提醒大家不要把它们和位逻辑运算符混淆,这也是初学者最容易犯的错误。

3.1.9 条件运算符 ?:
这与C语言完全相同,具体不再解释。

3.1.10 类型转换
我们在编写程序的时候经常需要对变量的类型进行转换,Java语言与其他的编程语言类似,也提供两种类型转换方式,即显式转换和隐式转换。转换的对象可分为两类,一是基本类型,二是对象类型。

这里需要掌握这样一个要点。对于基本类型来说,凡是大转小(以类型的宽度考虑)需要使用显式转换,也就是需要在变量前面强制给出需要转换成的类型。而对小转大来说,系统会自行进行隐式转换。

对于对象类型来说,也与之类似。凡是超类转子类则需要使用显式强制转换,而子类转超类系统可自行进行隐式转换。另外还需要注意的一点是,对于不在一个继承关系树上的类要进行强制转换,Java编译可通过,但实际运行会出错。

3.2 equals()方法
equals()方法实际与= =运算符作用相同,也是用来比较相同类型的两个变量是否相同或相等。只是有点区别的是,对于String类来说,它重载equals()方法,使用它不是比较两个参考指针的区别,而是实际对所指向的具体内容进行比较,这也满足了平时我们对比较字符串的实际需求。当然,对其他类来说,你也可以重载equals()方法,使其满足你的实际需要,来比较两个对象类型的变量。

3.3 优先级
与其他编程语言类似的,Java语言的运算符同样涉及到优先级别的问题,书上130页从高到低给出了所有运算符的优先级。建议大家,如果对某些运算符之间的优先级不是很清楚的时候,可以使用()来改变它们的优先级关系。

3.4 方法的参数传递
最后,简单讨论一下方法的传递的问题。Java语言的参数传递类型主要可以分为两种,值传递和引用传递。借助C语言的概念,我们知道,第一种就是把参数值直接复制成方法体的参数,这样对方法体中的参数的改变不会影响到调用它的参数。而对于第二种,参数的引用(或者说是个指针)被传递给了方法体的参数,该引用用来访问调用中指定的实际参数。这样,对方法体参数的改变将会影响到调用方法体的参数。
由于没有指针的概念,Java的参数传递相对比较简单。对于一般的基本类型来说,都采用的是值传递;而对于对象类型则是使用的引用传递。



1.3 关键字和标识符
Java语言一共使用了48个保留关键字,他们主要可以分为如下几类。

-> 访问控制

private , protected , public

-> 类、方法和变量修饰符

abstract , class , extends , final , implements , interface , native , new , static , strictfp , synchronized , transient , volatile

-> 程序控制语句

break , case , continue , default , do , else , for , if , instanceof , return , switch , while

-> 错误处理

catch , finally , throw , throws , try

-> 包相关

import , package

-> 基本类型

boolean , byte , char , double , float , int , long , short

-> 变量引用

super , this , void

-> 未使用的关键字

const , goto

这些关键字的具体意义可以参考语法书,这里就不再详细阐述了。

另外,除了这48个关键字以外,还有3个语法保留字,即null、true和false。
1.4 变量的初始化
变量从声明的位置来看可以分为两种类型,一是实例变量instance variable,即声明在类一级;另一种是局部变量local variable,它声明在方法一级。这两类变量除了声明的位置不同,它们最主要的区别在于是否需要初始化的问题。下面我们具体来讨论一下这个问题。

-> 实例变量

类的成员就是定义在类一级的变量。它们实际上是可以不需要初始化的,系统一般会自动给它们赋一个默认值。

-> 基本类型

对于8种基本类型来说,Boolean型默认赋值false,char型会默认为Unicode字符集的/u0000,而其余几种类型都默认为0。

-> 对象类型

对于对象类型,系统不会赋予任何默认值,但会表示为null。

-> 数组类型

数组类型于对象类型类似,当你不初始化它的时候,它也是等于null。但如果你初始化它,则有些不同,它与基本类型相似会默认为0。

-> 局部变量

对于局部变量,一般来说它必须初始化。因为无论是基本类型还是对象类型,系统都不会自动赋于任何默认值,所以你必须指定一定的值。当然,如果你定义了局部变量而不去使用它,编译也是可以通过的。