| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 33861 人关注过本帖, 7 人收藏
标题:[原创]课堂笔记学习java(初级)
取消只看楼主 加入收藏
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 

嗯 可能是偶没有表述清楚 你说的对
子类是继承了父类中非私有的方法(假如是在同一包中),包括构造方法,为什么我会说子类不继承构造方法呢?(这是描述的问题)因为,
1.子类是从父类继承来的 所以变量自然继承过来,子类即使没有构造方法,也会有个默认的构造方法(不带参数) 这个构造方法里默认的(不用super关键字引用)包含有父类中默认的构造方法
2.但当子类有自己的构造方法时,这时父类的构造方法就会隐藏,就会被重写,这时可以说父类里的构造方法根本没有(因为隐藏了)被继承下来


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-10-20 20:49
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 
以下是引用yangte在2006-10-20 21:32:45的发言:
楼主啊,这世上难得碰到你样好心的人啊,,
期待后续。。。。。。。
楼主,一起有多少节课啊,你们几才上一节课,

多少节课? 这可不好统计 因为是笔记 所以这个帖子上的课程安排是偶自己排的 老师讲的很快哦 现在都讲到组件了
笔记要整理 打字上来 分析程序 还有检查语言描述的漏洞等所以要花时间的 更新速度不能太快哦
因为这个帖子是基础 出学嘛 大家就当复习了 呵呵
有时间我就会马上更新的 .... no problem


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-10-21 12:44
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 
这周忙完就好了
下周准时更新 ~

unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-01 13:02
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 

第七节课

接 口

接口在java中尤其是面向对象语言中是一个很重要的概念.
java中使用接口概念的原因:java不支持多继承性,即一个类只能有一个父类.单继承性使得java简单,易于管理程序.为了克服单继

承的缺点,java使用了接口.

一个类可以实现多个接口.使用关键字interface来定义一个接口.接口的定义和类的定义很相似,分为接口的声明和接口体.

1.接口声明及接口体

前面曾使用class关键字来声明类,接口通过使用关键字interface来声明.格式

interface 接口的名字

接口体中包含常量的定义和方法定义两部分.接口体中只进行方法的声明,不允许提供方法的实现,所以,方法的定义没有方法体,且

用";"结尾.如

interface Printable
{
final int max=100;
void add();
float sum(float x,float y);
}

2.接口的使用
一个类通过使用关键字implements声明自己使用一个或多个接口.如果使用多个接口,用逗号隔开接口名.如:
class A implements Printable,Addable

类A使用接口Printable 和接口Addable

子类使用接口格式也一样,如:
class B extends A implements Printable,Addable
子类B使用接口Printable 和接口Addable

如果一个类使用了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体.需要注意的是:在类中实现接口的

方法时,方法的名字,返回值类型,参数个数及类型,必须与接口中的完全一致.特别要注意的是:接口中的方法默认是public

abstract方法,所以类在实现接口方法时必须给出方法体,并且一定要用public来修饰,而且接口中的常量默认是public static常

量.

由于接口体中只有常量定义和public的abstract方法定义,程序在编写接口时,允许省略常量前面的public,final和static修饰,也

允许省略方法前的public和abstract修饰.另外,如果接口方法的返回类型不是void型,那么在类中实现接口方法时,方法体至少要

有一个return语句;如果是void型,类体除了两个大括号外,也可以没有任何语句.


java提供的接口都在相应的包中,通过引入包可以使用java提供的接口.也可以自己定义接口,一个java源文件就是由类和接口组成的.

虽然"使用接口"的描述的很罗嗦,看看下面的例子就容易掌握了


interface Computable//定义接口
{ int MAX=100;
int f(int x);//声明方法(是public abstrac型的,只是省略了关键字)
}
class China implements Computable
{ int number;
public int f(int x) //不要忘记public关键字
{ int sum=0;
for(int i=1;i<=x;i++)
{ sum=sum+i;
}
return sum;
}
}
class Japan implements Computable
{ int number;
public int f(int x)//不要忘记public关键字
{ return 44+x;
}
}
public class E
{ public static void main(String args[])
{ China zhang;
Japan henlu;
zhang=new China();
henlu=new Japan();
zhang.number=991898+Computable.MAX;
henlu.number=941448+Computable.MAX;
System.out.println(\"number:\"+zhang.number+\"求和\"+zhang.f(100));
System.out.println(\"number:\"+henlu.number+\"求和\"+henlu.f(100));
}
}

还要注意的就是如果一个类声明实现一个接口,但没有实现接口中的所有方法,那么这个类必须是abstract类,如


interface Computable
{final int max=100;
void speak(String s);
int f(int x);

abstract class A implements Computable//类A使用的接口但类体中并没有实现接口中speak()的方法,所以此类必须是抽象类
{public int f(int x)//只是实现了接口中的一个方法
{int sum=0;
for(int i=1;i<=x;i++)
sum+=i;
return
}
}


类实现的接口方法以及接口中的常量可以被类的对象调用,而且常量也可以用类名或接口名直接调用.这理解不难,因为前面讲过

final修饰的常量,在内存程序加载字节码时,内存就给常量分配了一个固定空间,不可以改变(直到程序结束),所以这个地址是固定

了,并且这个常量是来自一个接口,所以此接口名或者使用这个接口的类的对象可以直接调用这个常量喽.方法也是一样的.

接口声明时,如果关键字interface前面加public关键字,就称这样的接口是一个public接口.public接口可以被任何一个类使用.如

果一个接口不加public修饰,就称为友好接口类,友好接口可以被同一包中的类使用.

如果父类使用了某个接口,那么子类也就自然使用了该接口,子类不必再使用关键字implements声明自己使用这个接口了.

接口也可以被继承,即可以通过关键字extends声明一个接口是另一个接口的子接口.由于接口中的方法和常量都是public的,子接

口将继承父接口中的全部方法和常量.

3.理解接口

讲了半天,你已经知道如何定义和使用接口了,但你会疑问,使用接口的好处在哪里?其实接口的思想就在于它可以增加很多类都需

要实现的功能,使用相同的接口类不一定由继承的关系,就是象各种各样的商品,他们可能隶属不同的公司,工商部门要求不管哪里

的商品必须具有显示商标的功能(即实现同一接口),但商标的具体制作由各个公司自己去实现,这就是接口的灵活所在.再比如,你

是一个项目的主管,你需要管理许多部门,这些部门要开发一些软件所需要的类,你可能要求某个类实现一个接口,也就是说你对一

些类是否具有这个功能非常关心,但不关心功能的具体实现.比如,这个功能是speaklove,但你不关心是用汉语实现功能还是用英语

实现speaklove.还是用个例子来理解一下接口,如:


interface 收费 //定义接口收费功能
{ public void 收取费用();
}
interface 调节温度 //定义接口调节温度功能
{ public void controlTemperature();
}
class 公共汽车 implements 收费 //一般的公共汽车只具有收费功能,空调车少
{ public void 收取费用()
{ System.out.println(\"公共汽车:一元/张,不计算公里数\");
}
}
class 出租车 implements 收费, 调节温度//出租车比较高级当然除了收费功能还有空调喽
{ public void 收取费用()
{ System.out.println(\"出租车:1.60元/公里,起价3公里\");
}
public void controlTemperature()
{ System.out.println(\"安装了Hair空调\");
}
}
class 电影院 implements 收费,调节温度//电影院有收费和调节温度功能
{ public void 收取费用()
{ System.out.println(\"电影院:门票,十元/张\");
}
public void controlTemperature()
{ System.out.println(\"安装了中央空调\");
}
}
class E
{ public static void main(String args[])
{ 公共汽车 七路=new 公共汽车();
出租车 天宇=new 出租车();
电影院 红星=new 电影院();
七路.收取费用();
天宇.收取费用();
红星.收取费用();
天宇.controlTemperature();
红星.controlTemperature();
}
}

从这个例子可以看出来定义了多个接口,不同类根据自己的需要可以灵活使用想要的接口.建议接口里实现的方法越少越好,可以定

义多个接口来实现多种功能.


4.接口回调
接口回调是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中.那么该接口变量就可以调用被类实现的

接口中的方法.实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法.通过例子掌握接口回调

的意义,如


interface ShowMessage//接口
{ void 显示商标(String s);
}
class TV implements ShowMessage//使用接口
{ public void 显示商标(String s)
{ System.out.println(s);
}
}
class PC implements ShowMessage//使用接口
{ public void 显示商标(String s)
{ System.out.println(s);
}
}
public class E
{ public static void main(String args[])
{ ShowMessage sm;//声明了一个接口变量
sm=new TV();//把使用该接口的类的对象赋给接口变量
sm.显示商标(\"长城牌电视机\");//此时接口变量就可以使用被该类实现的接口中的方法了
sm=new PC(); //另一个对象赋给接口变量
sm.显示商标(\"联想奔月5008PC机\");
}
}

体会一下,如果你理解上节课讲的上转型对象,就可以很轻松理解接口回调的过程
回顾下上节课中将抽象类时给的例子,计算面积的那个,下面用接口l来实现,比较不同点


interface Computerable
{ public double 求面积();
}
class 梯形 implements Computerable
{ double a,b,h;
梯形(double a,double b,double h)
{ this.a=a;
this.b=b;
this.h=h;
}
public double 求面积()
{ return((1/2.0)*(a+b)*h);
}
}
class 圆形 implements Computerable
{ double r;
圆形(double r)
{ this.r=r;
}
public double 求面积()
{ return(3.14*r*r);
}
}
class 堆
{ Computerable 底;
double 高;
堆(Computerable 底,double 高)
{ this.底=底;
this.高=高;
}
void 换底(Computerable 底)
{ this.底=底;
}
public double 求体积()
{ return (底.求面积()*高)/3.0;
}
}
public class E
{ public static void main(String args[])
{ 堆 zui;
Computerable bottom;//声明接口变量
bottom=new 梯形(2.0,7.0,10.7); //回调
System.out.println(\"梯形的面积\"+bottom.求面积());
zui=new 堆(bottom,30);
System.out.println(\"梯形底的堆的体积\"+zui.求体积());
bottom=new 圆形(10);
System.out.println(\"半径是10的圆的面积\"+bottom.求面积());
zui.换底(bottom);
System.out.println(\"圆形底的堆的体积\"+zui.求体积());
}
}

上面的例子明白后或者理解了什么时接口回调,再讨论下"接口做参数"的概念

如果准备给一个方法的参数传递一个值,可能希望该方法的参数的类型时都不了类型,这样就可以想该参数传递byte int long float double类型的数据.

如果一个方法的参数时接口类型,就可以将任何实现改接口类的实例传递给该接口参数,那么接口参数就可以回调类实现的接口方法.

比如上面的例子中堆那个类,

class 堆 
{ Computerable 底;//声明接口类型变量
double 高;
堆(Computerable 底,double 高) //方法的参数类型是接口
{ this.底=底;
this.高=高;
}
void 换底(Computerable 底)
{ this.底=底;
}
public double 求体积()
{ return (底.求面积()*高)/3.0;//\"底\"是接口类型的变量怎么能使用求面积的方法呢,说明了肯定是接口回调,即传进来的参数是一个被对象赋过值的接口变量,才使得此接口变量可以使用被类实现的方法
}
}

如果还是不太明白过程,把下面的程序理解就行了


interface SpeakHello //接口
{ void speakHello();
}
class Chinese implements SpeakHello//使用接口
{ public void speakHello()
{ System.out.println(\"中国人习惯问候语:你好,吃饭了吗? \");
}
}
class English implements SpeakHello//使用接口
{ public void speakHello()
{ System.out.println(\"英国人习惯问候语:你好,天气不错 \");
}
}
class KindHello
{ public void lookHello(SpeakHello hello)//接口做参数
{ hello.speakHello();//被赋值了的接口(回调后的接口)就可以使用被类实现了的方法speakHello();
}
}
public class E
{ public static void main(String args[])
{ KindHello kindHello=new KindHello();
kindHello.lookHello(new Chinese());//可以把它分解为SpeakHello hello; 和hello=new Chinese();
kindHello.lookHello(new English());
}
}


总结:花了一个篇幅讲接口,就证明它的重要性,灵活使用接口对以后编写java程序再性能上会有质的提高的.


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-10 20:22
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 
以下是引用千里冰封在2006-11-10 21:08:54的发言:
楼主,建接口或者类的时候,能不能不用中文名?

呵呵 以后尽量 我看着也别扭
但为了通俗吗 毕竟是unicode字符集 用汉语描述容易理解


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-10 21:59
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 

第八节课

一些比较重要的类

1.内部类

类可以有两种重要的成员:成员变量和方法,类还可以有一种成员:内部类.
java支持在一个类中声明另一个类,这样的类称为内部类,而包含内部类的类称为内部类的外部类.声明内部类如同在类中声明方法

和成员变量一样,一个类把内部类看作是自己的成员.内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用

外嵌类中的方法.内部类的类体中不可以声明类变量和方法.外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员.举例体会:


class China
{ final String nationalAnthem=\"义勇军进行曲\";
Beijing beijing; //Beijing 是个内部类,其声明了一个对象作为外嵌类的成员
China()
{ beijing=new Beijing();
}
String getSong()
{ return nationalAnthem;
}
class Beijing //内部类的声明
{ String name=\"北京\";
void speak()
{ System.out.println(\"我们是\"+name+\" 我们的国歌是:\"+getSong());
}
}
}
public class E
{ public static void main(String args[])
{ China china=new China();
china.beijing.speak();
}
}

2.匿名类

a) 和类有关的匿名类
当使用类创建对象时,程序允许把类体与对象的创建组合在一起,也就是说,类创建对象时,除了构造方法还有类体,此类体被认为是

该类的一个子类去掉类声明后的类体,称作匿名类.匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明对象,但却可以直

接用匿名类创建对象.假设People是类,那么下列代码就是用People的一个子类(匿名类)创建对象:
new People()
{
匿名类的类体
}

因此,匿名类可以继承父类的方法也可以重写父类的方法.使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定

是内部类,匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和static方法.

尽管匿名类创建的对象没有经历类声明的步骤,但匿名对象的引用必须传递一个匹配的参数,匿名类的主要途径就是向方法的参数传

值.

假设f(B x)是一个方法
void f(B x){
x调用B类中的方法
}

其中参数是B类的对象,那么在调用方法f时可以向其参数x传递一个匿名对象,例如:
f(new B()
{匿名类的类体}
)

如果匿名类继承了类的方法,x就调用继承的方法,如果匿名类重写了父类的方法,x就调用重写的方法.
看看下面的例子,用匿名类创建一个对象,并向一个方法的参数传递一个匿名类的对象.


class Cubic
{ double getCubic(int n)
{ return 0;
}
}
abstract class Sqrt
{ public abstract double getSqrt(int x);
}
class A
{ void f(Cubic cubic)
{ double result=cubic.getCubic(3);//执行匿名类体中重写的getCubic()
System.out.println(result);
}
}
public class E
{ public static void main(String args[])
{ A a=new A();
a.f(new Cubic() //使用匿名类创建对象,将该对象传递给方法f的参数cubic
{ double getCubic(int n)//类体
{ return n*n*n;
}
}
);
Sqrt ss=new Sqrt() //使用匿名类创建对象,ss是该对象的上转型对象
{ public double getSqrt(int x) //匿名类是abstract类Sqrt的一个子类,所以必须实现getSqrt()方法
{ return Math.sqrt(x);
}
};
double m=ss.getSqrt(5); //上转型对象调用子类重写的方法
System.out.println(m);
}
}

b) 和接口相关的匿名类

假设Computable是一个接口,那么,java允许直接调用接口名和一个类体创建一个匿名对象,此类体被认为是实现Computable接口的

类去掉类声明后的类体,称为匿名类.下面这个例子就是用实现了Computable接口的类(匿名类)创建对象:

interface Cubic 
{ double getCubic(int n);
}
interface Sqrt
{ public double getSqrt(int x);
}
class A
{ void f(Cubic cubic)
{ double result=cubic.getCubic(3); //执行匿名类体中实现getCubic()方法
System.out.println(result);
}
}
public class E
{ public static void main(String args[])
{ A a=new A();
a.f(new Cubic() //使用匿名类创建对象,将该对象传递给方法f的参数cubic
{ public double getCubic(int n)
{ return n*n*n;
}
}
);
Sqrt ss=new Sqrt() //使用匿名类创建对象,接口ss存放该对象的引用
{ public double getSqrt(int x)//匿名类是实现Sqrt接口的方法,所以必须要实现getSqrt方法
{ return Math.sqrt(x);
}
};
double m=ss.getSqrt(5); //接口回调类实现的方法
System.out.println(m);
}
}

3.异常类

所谓异常就是程序运行时可能出现的一些错误,如试图打开一个根本不存在的文件等,异常处理将会改变程序的控制流程,让程序有机会对错误作出处理.

当程序运行出现异常时,java运行环境就用异常类Exception的相应子类创建一个异常对象,并等待处理,例如读取下一个不存在的文

件时,运行环境就用异常类IOException创建一个对象.异常对象可以调用如下方法得到或输出有关异常的信息:

public String getMessage() , public void printStackTrace() , public String toString()

java使用try-catch语句来处理异常,将可能出现的异常操作放在try-catch语句的try的部分.当try部分中的某个语句发生异常

后,try部分将立刻结束执行,而转向执行相应的catch部分,所以程序可以将发生异常后的处理放在catch部分.try-catch语句可以由

几个catch组成,分别处理发生的相应异常.

try-catch语句格式如下:

try
{
包含可能发生异常的语句
}

catch(ExceptionSubClass1 e)
{
}

catch(ExceptionSubClass2 e)
{
}

...

各个catch参数中的异常类都是Exception的某个子类,标明try部分可能发生的异常,这些子类之间不能由父子关系,否则保留一个含

有父类参数的catch即可.

通过例子掌握try-catch语句的用法,如:


public class E
{ public static void main(String args[ ])
{ int n=0,m=0,t=555;
try{ m=Integer.parseInt(\"8888\");//Integer.parseInt是可以将数字格式的字符串转换成int型数据
n=Integer.parseInt(\"abc789\");//\"abc\"不是属于数字格式的字符串,所以通过Integer.parseInt转换时会出现异常
t=9999; //发生异常后就立刻进入catch部分,所以t=9999没有被执行
}
catch(NumberFormatException e)
{ System.out.println(\"发生异常:\"+e.getMessage());//得到发生异常的部分
e.printStackTrace();
n=123;
}
System.out.println(\"n=\"+n+\",m=\"+m+\",t=\"+t);
}
}//结果应该是n=123,m=8888,t=555

在程序中也可以扩展Exception类定义自己的异常类,然后规定哪些方法产生这样的异常.一个方法在声明时可以使用throws关键字声明要产生的若干异常,并在该方法的方法体中具体给出产生异常类的操作,即用相应的异常类创建对象,并使用throw关键字抛出该异常类,导致该方法结束执行.程序必须在try-catch语句中调用能发生异常的方法,其中catch的作用就是捕获throw方法抛出的异常现象.

注意:throw时java的关键字,该关键字的作用就是抛出异常.throw和throws是两个不同的关键字.

下面的例子中,Computer类中有一个计算最大公约数的方法,如果向该方法传递负整数,方法就抛出定义的异常.

class NopositiveException extends Exception//子定义的异常类
{ String message;
NopositiveException(int m,int n)
{ message=\"数字\"+m+\"或\"+n+\"不是正整数\";
}
public String toString()
{ return message;
}
}
class Computer
{ public int getMaxCommonDivisor(int m,int n) throws NopositiveException//声明NopositiveException自定义的异常类
{ if(n<=0||m<=0)//不满足条件时候
{ NopositiveException exception=new NopositiveException(m,n);//创建自定义异常类的对象,用来抛出异常
throw exception; //抛出异常,结束方法的执行
}
if(m<n)
{ int temp=0;
temp=m;
m=n;
n=temp;
}
int r=m%n;
while(r!=0)
{ m=n;
n=r;
r=m%n;
}
return n;
}
}
public class E
{ public static void main(String args[])
{ int m=24,n=36,result=0;
Computer a=new Computer();
try { result=a.getMaxCommonDivisor(m,n);
System.out.println(m+\"和\"+n+\"的最大公约数 \"+result);
m=-12;
n=22;
result=a.getMaxCommonDivisor(m,n);
System.out.println(m+\"和\"+n+\"的最大公约数 \"+result);
}
catch(NopositiveException e)
{ System.out.println(e.toString());
}
}
}


4. Class 类

Class 是java.lang包中的类,该类的实例用来封装对象运行时的状态.当一个类被加载且创建对象时,和改类相关的一个类型为Class的对象就会自动创建.Class类本身不提供构造方法,因此,不能用new运算符和构造方法创建一个Class对象.任何对象调用getClass()方法都可以获取和该对象相关的一个Class对象,这个Class对象调用如下的方法可以获取创建对象的类的有关信息,比如类的名字,类中的方法名称,成员变量的名称等.

String getName() //返回类的名字
Constructor[] getDeclaredConstructors() //返回类的全部构造方法
Field[] getDeclaredFields() //返回类的全部成员变量
Method[] getDeclaredMethods() //返回类的全部方法

执行下面的例子来演示这几个函数的作用,如


import java.lang.reflect.*;
class Rect
{ double width,height,area;
public double getArea()
{ area=height*width;
return area;
}
}
public class E
{ public static void main(String args[])
{ Rect rect=new Rect();
Class cs=rect.getClass();//通过getClass来获取rect这个对象
String className=cs.getName();
Constructor[] con=cs.getDeclaredConstructors();
Field[] field=cs.getDeclaredFields() ;
Method[] method=cs.getDeclaredMethods();
System.out.println(\"类的名字:\"+className);
System.out.println(\"类中有如下的成员变量:\");
for(int i=0;i<field.length;i++)
{ System.out.println(field[i].toString());
}
System.out.println(\"类中有如下的方法:\");
for(int i=0;i<method.length;i++)
{ System.out.println(method[i].toString());
}
System.out.println(\"类中有如下的构造方法:\");
for(int i=0;i<con.length;i++)
{ System.out.println(con[i].toString());
}
}
}


创建对象最常用的方式就是使用new运算符和类的构造方法,实际上也可以使用Class对象得到一个类的实例.为了得到一个类的对象,可以先得到一个和该类相关的Class对象,做到这点并不是难,只要使用Class的类方法:

public static Class forname(String className) throws ClassNotFoundException

就可以返回一个和参数calssName指定的类相关的Class对象.再让这个Class对象调用

public Object newInstance () throws InstantiationException,IllegalAccessException

方法就可以得到一个className类的对象.

要特别注意的是,使用Class对象调用newInstance()实例化一个className类的对象时,className类必须有无参数的构造方法.
看看下面的例子,如


class Rect
{ double width,height,area;
public double getArea()
{ area=height*width;
return area;
}
}
public class
{ public static void main(String args[])
{ try{ Class cs=Class.forName(\"Rect\");//没有通过new来创建对象,用forname()制定类的实例
Rect rect=(Rect)cs.newInstance();//得到此实例即创建对象
rect.width=100;
rect.height=200;
System.out.println(\"rect的面积\"+rect.getArea());
}
catch(Exception e){}
}
}

5.基本类型的类

java的基本数据类型包括byte,int,short,long,float,double,char.java同时也提供了基本类型相关的类,实现了对基本类型的封装.这些类在java.lang包中,分别是Byte,Integer,Short,Long,Float,Double,Character

这些基本类型都有自己的构造方法,如

Double(double num) //创建了一个Double类型的对象 并调用doubleValue()方法可以返回该对象含有double型数据

Float(float num) //创建了一个Float类型的对象 并调用floatValue()方法可以返回该对象含有float型数据

Byte(byte num) //创建了一个Byte类型的对象 并调用byteValue()方法可以返回该对象含有byte型数据

Integer(int num) //创建了一个Integer类型的对象 并调用intValue()方法可以返回该对象含有int型数据

Short(short num) //创建了一个Short类型的对象 并调用shortValue()方法可以返回该对象含有short型数据

Long(long num) //创建了一个Long类型的对象 并调用longValue()方法可以返回该对象含有long型数据


Character类实现了对char基本型数据的类包装.

可以使用Character的构造方法:
Character (char c)

创建一个Character类型的对象.Character对象调用charValue()方法可以返回该对象含有的char类型数据.

Character类还包括了一些类方法,这些方法可以直接通过类名调用,用来进行字符分类,比如判断一个字符是否是数字字符或改变一个字符的大小写等.

public static boolean isDigit(char ch) //如果ch是数字字符,方法返回true,否则返回false

public static boolean isLetter(char ch) //如果ch是字母,方法返回true

public static boolean isLetterOrDigit(char ch) //如果ch是数字字符或者字母,方法返回true

public static boolean isLowerCase(char ch) //如果ch是小写字母

public static boolean isUpperCase(char ch) //如果ch是大写字母

public static char toLowerCase(char ch) //返回ch的小写形式

public static char toUpperCase(char ch) //返回ch的大写形式

public static boolean isSpaceChar(char ch) //如果是空格,返回true

通过下面的例子掌握Character类的这些成员方法的使用,如


public class E
{ public static void main(String args[ ])
{ char a[]={'a','b','c','D','E','F'};
for(int i=0;i<a.length;i++)
{ if(Character.isLowerCase(a[i]))
{ a[i]=Character.toUpperCase(a[i]);
}
else if(Character.isUpperCase(a[i]))
{ a[i]=Character.toLowerCase(a[i]);
}
}
for(int i=0;i<a.length;i++)
{ System.out.print(\" \"+a[i]);
}
}
}

总结:此小节主要将了一些特殊的类的用法


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-11 22:31
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 
以下是引用yangte在2006-11-13 12:50:13的发言:
是呀,楼上的楼上的说的对啊,,我现在越看越晕啊,
前几节很好理解,现在什么也看不懂了。。。。
哎~~~~~~~~~~~~~~~!!!》
能不能简单点。。

关于抽象类,接口,以及重要的类这几节课都是java比较深奥但又很精华的东东...

如果是初学还没有C++基础(接触过OOP),可以先试着将"类和对象"的概念理解透彻了,在这个基础上再看这些知识点就不难了

以后的课程(除了线程)应该没有这么多文字描述了...AWT组件, 输入输出流 ,网络,applet等都是给定某个对象的,现学现用就可以了,不象前面这些学要抽象的理解.你想, 一个事务最初在认识的时候.只能用文字描述出它的定义才可以掌握它的,对吧.

所以劝大家还是不要着急的,学好语言不是为了速成,打好基础是关键的
我的能力也有限,只能帮助引导大家学习java的基础知识,提高可不敢说,但愿共同进步...

这个帖子会持续更新的,因为最近一直都有考试,上网不太方便的,更新的会慢,再次感谢大家支持!!


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-13 18:36
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 


第九节课

字符串

1.什么是字符串

java使用java.lang包中的String类来创建一个字符串变量,因此字符串变量是一个对象.

a) 字符串常量

如, "你好","bc-cn","12345789"
字符串常量在内存中一但定义,地址空间是不可改变的,直到程序结束.就是说字符串常量在内存中有固定的地址.

b) 声明字符串

String str;

c) 创建字符串

使用String类的构造方法,例如:

str=new String("I like bc-cn.net"); //当然如果没有声明直接创建也是可以的,回忆一下匿名类的概念

声明和创建可以一步完成:

String str=new String("I like bc-cn.net");

也可以用一个已创建的字符串创建另一个字符串,如

String s=String(str);

String类还有两个比较常用的构造方法.

(1)String (char a[]) //用一个字符数组a创建一个字符串对象,如

char a[]={'b','o','y'};
String s=new=new String(a);

上述过程相当于:

String s=new String("boy");

(2)String(char a[],int startIndex,int count)

提取字符数组a中的一部分字符创建一个字符串对象,参数startIndex和count分别指定在a中提取字符的起始位置(例如第一位置从0开始依次类推)和从该位置开始截取的字符个数,例如

char a[]={'s','t','b','u','s','n'};
String s=new String(a,2,3); //从2开始,即第三个位置(b),截取3个字符

上述过程相当于:

String s=new String("bus");

d)引用字符串常量对象

字符串常量是对象,因此可以把字符串常量的引用赋值给一个字符串变量,例如:

String s1,s2;
s1="how are you";
s2="how are you";

分析:"how are you"是个字符串常量,所以在内存中的地址是固定的,赋值给了s1和s2,就说明s1和s2用的是同一个空间


2.字符串的常用方法

1)public int length()
使用String类中的length()方法可以获取一个字符串的长度,如

String s="we are student",tom="我们是学生";
int n1,n2,n3;
n1=s.length(); //n1的值是15
n2=tom.length(); //n2的值是5.
n3="we are student=我们是学生".length();// n3的值是21

2)public boolean equals(String s)
字符串对象调用String类中的equals方法,比较当前字符串对象的实体是否与参数指定的字符串s的实体相同,如:

String tom=new String("we are student");
String boy=new String("We are students");
String jerry=new String(tom);

则:tom.equals(boy)或tom.equals(jerry) 的值都是true 因为比较是是实体,即字符串本身(各个位置的字符与长度是否相同)

注意:如果是tom==jerry或tome==boy 的值就是false,因为new了之后,字符串就是对象,tom,boy,jerry是引用值(地址),因为每个对象在创建后都有自己的内存空间,所以用"=="比较当然会不同喽

字符串对象调用public boolean equalsIgnoreCase(String s) 比较当前字符串对象与参数指定的字符串s是否相同,比较时候忽略大小写.
仔细体会下面的例子:


class E
{ public static void main(String args[])
{ String s1,s2;
s1=new String(\"we are students\");
s2=new String(\"we are students\");
System.out.println(s1.equals(s2));//字符串实体相同,输出结果是true
System.out.println(s1==s2); //对象各自分配的空间不同,输出结果为false
String s3,s4;
s3=\"how are you\";
s4=\"how are you\";
System.out.println(s3.equals(s4)); //同一个空间,结果为true
System.out.println(s3==s4); //同一个空间,结果为true
}
}


3)public boolean startsWith(String s) 和public boolean endWith(String s)
字符串对象调用startsWith(String s)方法,判断当前字符串对象的 前缀 是否是参数指定的字符串s,如

String tom="bbs.bc-cn.net",jerry="www.bc-cn.net";
tom.startsWith("bbs")的值是true
jerry.startsWith("bbs")的值是false

同样,endWith(String s)判断的就是后缀

字符串对象调用public boolean startsWith(String prefix,int toffset)方法,判断当前字符串从toffset索引处开始的前缀是否是参数指定的字符串prefix,如:

String str="123456";
boolean boo=str.startsWith("456",3)// 很容易看出来,boo的值应该是true

4)public boolean regionMatches(int firstStart,String other,int otherStart,int length)
字符串调用此方法,从当前字符串参数firstStart指定的位置开始处,取长度为length的一个子串,并将这个子串和参数other指定的一个子串进行比较.其中,other指定的字符串是从参数otherStart指定的位置开始,从other中取长度为length的一个子串.如果两个子串相同则该方法返回true

使用该方法的重载方法:
public boolean regionMatches(boolean b,int firstStart,String other,int otherStart,int length)
可以通过参数b决定是否忽略大小写,当b为ture时,忽略大小写

这个方法描述起来虽然罗嗦,但看完下面的例子就很容易掌握了,如


class E
{ public static void main(String args[])
{ int number=0;
String s=\"student;entropy;engage,english,client\";
for(int k=0;k<s.length();k++)
{ if(s.regionMatches(k,\"en\",0,2))//k是第一个串的其实位置,0是\"en\"的其实位置,2是每次取的子串的长度
{ number++;
}
}
System.out.println(\"number=\"+number);
}//这个例子很容易看出是在统计s中出现en的次数
}


5)public int compareTo(String s)
字符串对象可以使用String类中的compareTo(String s)的方法,按字典序与参数s指定的字符串比较大小.如果当前字符串与s相同,该方法返回值0;如果当前字符串对象大于s,该方法返回正值;如果小于s,该方法返回负值.例如:

String str="abcde";
str.compareTo("boy")小于0
str.compareTo("aba")大于0
str.compareTo("abcde")等于0

按字典序比较两个字符串还可以使用public int compareToIgnoreCase(String s) 该方法忽略大小写

看看下面的例子是将一个字符串数组按字典序重新排序


class E
{ public static void main(String args[])
{ String a[]={\"door\",\"apple\",\"Applet\",\"girl\",\"boy\"};
for(int i=0;i<a.length-1;i++)
{ for(int j=i+1;j<a.length;j++)
{ if(a[j].compareTo(a[i])<0)//如果当前字符串比下一个字符串字典序号大,交换
{ String temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
for(int i=0;i<a.length;i++)
{ System.out.print(\" \"+a[i]);
}
}
}


6)public int indexOf(String s)
字符串对象调用indexOf(String s)方法从当前字符串的头开始检索字符串s,并返回首次出现s的位置.如果没有检索到字符串s,该方法返回-1.

字符串调用public int indexOf(String s,int startpoint)方法从当前字符串的startpoint位置处开始检索字符串s,并返回首次出现s的位置.如果没有检索到返回-1.

字符串调用public int lastIndexOf(String s)方法从当前字符串的头开始检索字符串s,并返回最后出现s的位置.如果没有检索到返回-1.

如:
String s="bbs.bc-cn.net";
s.indexOf("b"); //值为0
s.indexOf("b",3); //值为4
s.lastIndexOf(".");//值为9 即net前面那个"."

7)public String substring(int startpoint)
字符串对象调用该方法获得一个当前的字符串的子串,该子串是从当前字符串的startpoint处截取到字符串的末尾处所得到的字符串.

字符串对象调用substring(int start,int end)方法获得一个当前字符串的子串,该子串是从当前串的start处截取到end处所得到的字符串,但不包括end处所对应的字符.
例如:
String tom="I love tom";
string s=tom.substring(2,5);// 得到的s应是"lov"


8)public String replaceAll(String oldString,String newString)
字符串对象调用该方法可以获得一个串对象,这个串对象是通过参数newString指定的字符串替换s中由oldString指定的所有字符串而得到的字符串.

字符串对象调用public String replaceFirst(String oldString,String newString)方法可以获得一个串对象,这个串对象是通过用参数newString指定的字符串替换s中出现的第一个oldString指定字符串而得到得字符串.
例如:
String tom="hello,tom";
String jerry=new String(tom.replaceAll("tom","jerry")); //jerry的应该是"hello,jerry"

9)public String trim()
字符串常量调用此方法得到一个字符串对象,该字符对象是s去掉前后空格后的字符串.
如:


class E
{ public static void main(String args[])
{ String path=\"c:\\myfile\\2000\\result.txt\";
int index=path.lastIndexOf(\"\\\"); //得到最后出现'\'的位置,注意'\'是转移字符,要想单独表示'\'时应该写成\"\\\"
String fileName=path.substring(index+1);//得到'\'后面的子串即result.txt
String newName=fileName.replaceAll(\".txt\",\".java\"); //把result.txt中的txt替换成java
System.out.println(path);
System.out.println(fileName); //输出应为result.txt
System.out.println(newName); //输出应为result.java
}
}

3.字符串与基本数据的相互转换
a)
java.lang包中的Integer类调用其类方法:
public static int parseInt(String s)
其可以将"数字"格式的字符串,如"123456",转化为int型数据,例如

int x;
String s="123456";
x=Integer.parseInt(s);//整形x值为123456

类似的还有Byte,Short,Long,Float,Double类调相应的类方法:
byte Byte.parseByte(String s); //将字符串转换为byte格式

short Short.parseShort(String s);

long Long.parseLong(String s);

float Float.parseFloat(String s);

double Double.parseDouble(String s);

注意使用这些时候要放在try-catch中捕获异常 NumberFormatException ,后面会有例子格式说明

b)可以用下列的方法把数字型变量转换为字符串:

public static String valueOf(byte n)

public static String valueOf(int n)

public static String valueOf(long n)

public static String valueOf(float n)

public static String valueOf(double n)

如: String str=String.valueOf(12345678.9);

c)可以用下列方法(Long 类)得到整数的各种进制的字符串:

public static String toBinaryString(long i)

public static String toOctalString(long i)

public static String toHexString(long i)

public static String toString(long i,int p)

其中的toString(long i,int p)返回整数i的p进制表示

下面一个转换的综合例子,仔细体会一下:

public class E
{ public static void main(String args[])
{ double n,sum=0,item=0;
boolean computable=true;
for(int i=0;i<args.length;i++)
{ try{ item=Double.parseDouble(args[i]);
sum=sum+item;
}
catch(NumberFormatException e)
{ System.out.println(\"您键入了非数字字符:\"+e);
computable=false;
}
}
if(computable)
{ n=sum/args.length;
System.out.println(\"平均数:\"+n);
}
int number=123456;
String binaryString=Long.toBinaryString(number);
System.out.println(number+\"的二进制表示:\"+binaryString);
System.out.println(number+\"的十六进制表示:\"+Long.toString(number,16));
String str=\"1110110\";
int p=0,m=0;
for(int i=str.length()-1;i>=0;i--)
{ char c=str.charAt(i);
int a=Integer.parseInt(\"\"+c);
p=p+(int)(a*Math.pow(2,m));
m++;
}
System.out.println(str+\"的十进制表示:\"+p);
}
}

分析:应用程序中的main方法中的参数args能接受从键盘输入的字符串.首先编译源文件:
编译通过后,输入java E 12 15 16 36 回车
这时,程序中的args[0],args[1],args[2],args[3]分别得到字符串12,15,16和36.在程序中再将这些字符串转换为数值进行计算,得到所需的结果.

上述例子输出结果为:
平均数:19.75
123456的二进制表示:11110001001000000
123456的十六进制表示:1e240
1110110的十进制表示:118


4.对象的字符串表示

所有的类都默认时java.lang包中Object类的子类或者间接子类.Object类有一个public方法toString,一个对象通过调用该方法可以获得该对象的字符串表示.如:


import java.util.Date;
import java.awt.*;
public class E
{ public static void main(String args[])
{ Date date=new Date();//Date包中的类 获取系统当前时间
Button button=new Button(\"确定\");//awt包中的类
System.out.println(date.toString());//date的属性用字符串表示,即当前系统时间
System.out.println(button.toString());//把button的属性用字符串表示出来,(即位置,大小,可用,名称等等)
}
}

显示结果为:
Sun Nov 26 20:38:30 CST 2006
java.awt.Button[button0,0,0,0x0,invalid,lable=确定]


5.StringTokenizer类

StringTokenizer(String s) 为字符串s构造一个分析器.使用默认的分隔符集合,即空格符(若干个空格被看成一个空格),换行符,回车符,Tab符,进纸符.

StringTokenizer(String s,String dilim) 为字符串s构造一个分析器,参数dilim中的字符被作为分隔符.

如:StringTokenizer fenxi=new StringTokenizer("we are student");//用空格区分单词
StringTokenizer fenxi=new StringTokenizer("we,are ;student",", ; ");//用"," 和";"还有空格来区分单词

StringTokenizer可以用nextToken()方法逐个获取字符串中的语言符号(单词),每当调用nextToken()时,都将在字符串中获得下一语言符号,每当获取到下一个语言符号,字符串分析器中负责计数的变量的值就自动减一,该计数变量的初始值等于字符串中单词的个数.通常用while循环来逐个获取语言符号,为了控制循环,可以使用StringTokenizer类中的hasMoreTokens()方法,只有字符串中还有语言符号,即计数变量的值大于0,该方法就返回true,否则返回false.另外还可以随时让分析器调用countTokens()方法得到分析器中计数变量的值.

通过下面的例子理解StringTokenizer类的使用,如


import java.util.*;
public class E
{ public static void main(String args[])
{ String s=\"I am Geng.X.y and she is my girlfriend\";
StringTokenizer fenxi=new StringTokenizer(s,\" ,\");
int number=fenxi.countTokens();
while(fenxi.hasMoreTokens())
{ String str=fenxi.nextToken();
System.out.println(str);
System.out.println(\"还剩\"+fenxi.countTokens()+\"个单词\");
}
System.out.println(\"s共有单词:\"+number+\"个\");
}
}



unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-27 10:25
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 

6.字符串与字符,字节数组
1)字符串和字符数组
a)用字符数组创建字符串对象

String (char[]) //该构造方法用指定的字符数组构造一个字符串对象
String (char[],int offset,int length) //用指定的字符数组的一部分,即从起始位置offset开始取length个字符构造字符串对象

如前面的例子:

char a[]={'b','o','y'};
String s=new=new String(a);

b)将字符串中的字符复制到字符数组
public void getChars(int start,int end,char c[],int offset) //字符串调用此方法将当前的字符串中的一部分字符复制到数组c中,将字符串中从start到end-1位置上的字符复制到数组c中,并从数组c中的offset处开始存放这些字符,需要注意的是,必须保证数促c能容纳下要复制的字符.

public char[] toCharArray() 字符串对象调用该方法可以初始化一个字符数组,该数组的长度与字符串的长度相等,并将字符串对象的全部字符复制到该数组中.

体会下面俩个例子:


class E
{ public static void main(String args[])
{ char c[],d[],e[];
String s=\"巴西足球队击败德国足球队\";
c=new char[2];
s.getChars(5,7,c,0);
System.out.println(c); //输出击败
d=new char[s.length()];
s.getChars(7,12,d,0);
s.getChars(5,7,d,5);
s.getChars(0,5,d,7);
System.out.println(d);//d[]中保存的是德国足球队击败巴西足球队
e=new char[s.length()];
e=s.toCharArray()
System.out.println(e);//e[]中保存的s的内容即\"巴西足球队击败德国足球队\"

}
}



class E
{ public static void main(String args[])
{ String s=\"编程论坛\";
char a[]=s.toCharArray();//把字符串转成字符数组
for(int i=0;i<a.length;i++)
{ a[i]=(char)(a[i]^'t');//把每个字符都处理下
}
String secret=new String(a);
System.out.println(\"密文:\"+secret);
for(int i=0;i<a.length;i++)
{ a[i]=(char)(a[i]^'t');
}
String code=new String(a);
System.out.println(\"原文:\"+code);
}
}


2)字符串和字节数组
和字符数组的形容类似
a)用字节创建字符串对象
String (byte [])

String (byte[],int offset,int length)

b)将字符串转换为字节数组
public byte[] getBytes()

例如:


public class E
{ public static void main(String args[])
{ byte d[]=\"你我他\".getBytes();
System.out.println(\"数组d的长度是(一个汉字占两个字节):\"+d.length);//输出\"数组d的长度是(一个汉字占两个字节):6\"
String s=new String(d,0,2);
System.out.println(s);//输出\"你\"
}
}

7.StringBuffer类

前面学习了String字符串对象,String类创建的字符串对象是不可修改的,也就是说String字符串不能修改,删除,替换字符串中的某个字符,即String对象一但创建,那么实体是不可以再发生变化的.

下面介绍StringBuffer类,该类能创建可修改的字符串序列,也就是说,该类对象的实体的内存空间可以自动改变大小,便于存放一个可变的字符序列.比如,一个StringBuffer对象调用用append()方法可以追加字符序列,例如:
StringBuffer s=new StringBuffer("I love this game");
s.append(" !!");
//s的值就变为I love this game !!

1)StringBuffer的构造方法

a)StringBuffer()//无参数,可容纳16个字符,可以通过调用capacity()方法获取当前实体的实际容量

b)StringBuffer(int size)//指定size大小的容量,当存放大于size时,实体容量自动增加,以便存放所增加的字符

c)StringBuffer(String s)//指定实体的初始容量为参数s的长度额外再加16个字符,当超过size大小时,实体容量自动增加,以便存放所增加的字符

注意:可以用String(StringBuffer bufferstring)创建一个字符串的对象

2)StringBuffer类常用的方法

a)append方法//追加字符串,刚刚讲过

b)char charAt(int n)//得到第n(n>=0&&n<=s.capacity())个位置的字符

c)void setCharAt(int n,char ch)//替换第n个位置的字符

d)StringBuffer insert(int index,String str)//再第index的位置插入字符串str,并返回当前对象的引用

e)StringBuffer reverse()//逆置当前对象的实体,并返回当前对象的引用

f)StringBuffer delete(int startIndex,int endIndex)//删除从startIndex~endIndex-1之间的字符串,并返回当前对象的引用

g)StringBuffer replace(int startIndex,int endIndex,String str)//用字符串str替换startIndex~endIndex-1之间的字符串,并返回当前对象的引用

例如:


class E
{ public static void main(String args[ ])
{ StringBuffer str=new StringBuffer(\"62791720\");
str.insert(0,\"010-\");//在第0个位置插入010-,当前实体变为\"010-62791720\"
str.setCharAt(7 ,'8'); //把第8个位置的字符设置为8,当前实体变为\"010-62781720\"
str.setCharAt(str.length()-1,'7');//把最后一个位置的字符设置为7,当前实体变为\"010-62781727\"
System.out.println(str); //输出当前实体\"010-62781727\"
str.append(\"-446\");//追加字符串-446,当前实体变为\"010-62781727-446\"
System.out.println(str);
str.reverse();//逆置当前实体,实体变为644-72718726-010
System.out.println(str);
}
}

总结:字符串是很重要的概念,此节深入理解字符串及其相关方法的应用


unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-27 10:31
unicorn
Rank: 4
等 级:贵宾
威 望:14
帖 子:1066
专家分:0
注 册:2005-10-25
收藏
得分:0 
大下周就期末考试了 ,java是第二科

忙起来就更新慢了,不过即使考完java了,我也会来继续更新的,因为java这门语言我才学个皮毛,还要和大家共同学习 !!

unicorn-h.spaces. ◇◆ sava-scratch.spaces.  noh enol ! pue pu!w hw u! shemle aq ll!m noh 
2006-11-27 21:21
快速回复:[原创]课堂笔记学习java(初级)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016410 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved