JAVA学习体会

学Java之前我听许多人说Java很难,学了之后我感觉Java确实不容易,想学好它并非易事。

怎么学习Java,这是很多新手经常会问的问题,现在简单描述下我的心得。 首先要明白Java体系设计到得三个方面:J2SE,J2EE,J2ME(KJAVA)。J2SE,Java 2 Platform Standard Edition,我们经常说到的JDK,就主要指的这个,它是三者的基础,属于桌面级应用开发,这部分如果学得好很容易拓展J2EE和J2ME。J2ME,The Micro Edition of the Java 2 Platform。主要用于嵌入式Java,如手机,PDA等等。J2EE,Java 2 Platform,Enterprise Edition,就是所谓的企业级Java,适合企业的大型应用开发。

J2SE:

新手最初学习的时候先要从J2SE开始学起,所包含的内容主要分为:面向对象概念的理解、Java基本语法的学习,Java桌面图形界面应用程序的开发,掌握常用的Java API等(关键是要学会怎样查阅)。

重点:Java基本语法(循环结构,数据类型,数组,运算符等)、Swing,awt,事件机制、文件输入输出流处理等

难点:面向对象思想的理解(接口、类等)、线程、socket网络编程等

视频教程推荐:孙鑫的Java基础视频教程、张孝祥的Java基础视频教程,讲的都很细,而且这两位老师在教学方面都有很好的经验。

J2EE:

在学习了J2SE之后,你可以尝试着慢慢过渡到J2EE,当然,学习J2EE海需要很多非JAVA技术的支撑,比如数据库技术,网页编程技术等等,待会我会详细介绍这两方面的内容。J2EE有三个必学的框架,如果你说你学了J2EE,但又不会这三个框架的话,那会让人笑掉大牙,这三个框架分别是Struts、Spring和Hibernate,虽然这三个框架应用很广,但不代表这三个框架就代表了

J2EE,J2EE还有很多其他的东西,比如EJB,作为一款重量级(此重量级不是指重量级选手那个意思,此重量级非彼重量级)框架,虽然这个应用慢慢的再被其他框架所取代,但EJB3.0的出现也给它带回一些生机,作为一个分布式应用的框架,也是大家要去学习和了解的知识。

当然,刚才说到J2EE包含的范围很广,即使我把我所了解的所有技术说出来,也并不能代表J2EE,这是一个很深很广的学问,需要大家以后再工作的时候慢慢去发现了。我所了解的还包括:

JDBC:Java数据库连接对象,基础中的基础,Hibernate也只是对它的封装而已 JNDI: Java 命名与目录接口,J2EE重要规范之一

EJBS: 上面已经提到过了

RMI: 提供远程调用方法的支持,主要用于程序分布式开发

JMS: Java消息服务,中间件技术

JAVA IDL: 提供J2EE平台与CORBA交互能力和互联能力的技术

JTS: 组件事务监视器

JTA: 事务划分的一个技术

JAVAMAIL: Java中的邮件技术

JAF: Java启动框架,没研究过

Log4j,一款日志处理的框架应用

Junit:单元测试的好帮手

freemarker、velocity:两款不错的模板引擎

与Flash的交互Flex:目前很多的SNS应用就是使用到了这个技术

Web services:想知道我们论坛天气预报的效果是怎么做的吗?请关注这个技术 SOA:面向服务架构,未来技术发展的趋势之一

JAVA总的来说和C++、.NET、DELPHI等语言是同一祖先生出来,所以熟悉这类编程的人学起来特别容易,它们都是面向对象化编程语言。

学习任何语言(包括英语),基础一定要打好,没有学会走路跑步不可能快

吧。所以学习JAVA一定要先把JAVA的几个基本组成元素学好。以下是我总结出来的学习顺序和注意事项:

1、数据类型 JAVA是一种强类型语言,各种类型不会自动转换,使用前必须先定义。

2、方 法 方法相当于定义一个"宏"、一个"函数", 方法的定义格式为:

"说明符 修饰符 返回值 方法名(参数){方法体}。"

在学习方法的时候要注意"说明符、"修饰符"、"返回值"这三样东西。

我们在调用JAVA的自带的"类"里面的"方法"的时候,我们一开始是不用看懂这些方法里面写什么(当然,你能看懂是最好)。我们只要知道,使用了这个方法后,"返回值"的"类型"说明

3、类 在JAVA中最经常听到词,也是最麻烦的东西,类的定义格式为:

说明符 class 类名 extends超类名 implements 接口名{主体}

4、变量常量 JAVA的常量名一般用全大写字母表示,并且为了节省内存,一般定义为静态(JAVA程序中的名字我们经常有个默认的规则,类名所有单词第一个字母大写,方法名第二个单词开始第一个字母大写,变量名小写,这样我们一看程序就非常清楚了,从小养成良好的习惯嘛,呵呵),变量的定义格式为:

"修饰符 数据类型 变量名"

变量在类中定义(不在方法体中的部分称为域)和在方法体中定义是不同的(在方法体中定义不需要修饰符)。学习变量的时候要注意两个特殊的东西

"this" 和"super"。同时我们就要学习什么叫"覆盖"、"重载"。

5、控制流 所有的编程语言的控制语句无非就是几个if else for while do switch。

6、接口: 一个抽象的东西,接口可以多继承,解决了类只能单继承的问题。接口的定义格式为:

说明符 interface 接口名{主体},

接口内的方法都是没有主体的,只有常量或变量。当类使用接口的时候,一定要"覆盖"接口的方法。

7、线程: 线程是个比较复杂的东西,例如一个赛马程序有七匹马赛跑,就有七个线程,看起来好象是同时在跑,其实是计算机分配不同的时间段让七个线程运行。我们初学者的程序可能还用不上。

到这里为止,JAVA的基本概念我们有一定的了解了,我们就开始研究JAVA的类了。JAVA的核心API(也就是SUN公司已经为我们写好的类)有以下几种。(还有其他很多的扩充类)

Java.lang java.io java.util java.net java.awt java.applet java.sql java.text

每个类有很多方法,每个对象的类型不同,可以使用的方法也不同,我们最好有一本类库在手中,可以随时查阅,如果您的英语好,也可以上SUN公司的网站或使用JBUILDER的帮助文档。谁都不可能一下子记住这么多类的用法,而且也并不是所有的类对我们的程序都有用,我们当然是选择我们需要的类进行学习。

一般程序都逃不过字符串操作、文件操作、数据库操作,所以java.lang

java.io java.sql这几个类我们必须要看。

如果你要编写APPLET小程序(小程序可以应用在网络上,非常有用。可能大家对小程序的应用影象最深的是一些动画效果,其实小程序用于证券、游戏等方面的效果是其他网络脚本程序无法代替的)。那么你就要学java.applet java.awt这两个类。

如果你要编写一些网络程序,你就要学java.net。

如果我们要学习编写JSP、EJB、SERVLET(JSP和SERVLET其实是一回事),我们就需要学习JAVA的图形方面的类(java.awt)。我们可以通过学习字符串操作、文件操作、数据库操作快速入门,然后学习java.net和如何编写EJB(比较抽象和复杂的东西,和COM的概念差不多)。

学习Java这段时间,有时候会觉得有点苦,但是我觉得正是有了你奋斗时的苦,才能换来学成后的甜。当你经过认真写代码做完一个项目时,你会有一种成就感。心里有一种说不出的喜悦之情。

学习Java靠得是韧劲,靠得是拼劲,考得是坚持不懈。如果做好了这几点,我想Java对你来说不会太难。还有,你自己要有信心,相信自己能学会。以上就是我在学了Java后的一些感言。

 

第二篇:JAVA学习体会

1. JAVA语言严格区分大小写。

如:system 与System是两个不同的概念,后者为正确的系统变量。

2. 环境变量一定要设置好。

编译时用javac xx.java,一定要带上后缀.java,成功后将生成xx.class

运行时用 java yy (yy为xx中定义的类名) ,也要注意区分大小写!注意若一个.java文件中可能有多个类时,则只执行有main{}函数的那一个。

3. 注意每行语句后面的;号不能漏掉。

4. 关于错误信息“类A是公共的,应在名为A.java的文件中声明”的含义包括:

1、如果类A被声明为公共的(public),那么必须将类A保存在名为A.java的文件中,文件名和类名必须完全一致,包括大小写。

2、反之,在一个文件中最多包含一个顶级的公共类,并且该公共类的名字与文件名相同。比如文件A.java中,允许定义一个或多个类,但最多允许一个顶级的公共类,此类名为A。此处强调的顶级的意思是,允许非顶级的公共类存在,如内部公共类等。

4. 任何一个类对象被生成时一定会调用该类的构造函数,如下面的例子

class A

{

private int i;

//private static int cnt = 0; //结果为0,1,2,3

}

public class TestStatic_1

{

public static void main(String[] args) { System.out.printf("当前时刻A对象的个数是: %d\n", A.getCnt()); A aa1 = new A(); //public static int cnt = 0; //结果为0,1,2,3 //public int cnt=0; //编译错误 public A() { ++cnt; } public A(int i) { } public static int getCnt() { } //return 返回的是A对象的个数; return cnt; this.i = i; ++cnt;

System.out.printf("当前时刻A对象的个数是: %d\n", A.getCnt()); A aa2 = new A(); System.out.printf("当前时刻A对象的个数是: %d\n", A.getCnt()); A aa3 = new A(); System.out.printf("当前时刻A对象的个数是: %d\n", A.getCnt());

}

}

程序执行的结果为0,1,2,3,

5. 类的成员可以是变量、函数,也可以是类对象,在类的内部,成员函数可以直接调用成

员(无论是private或public)。

6. 子类内部可以访问父类非私有的成员,私有成员无法被子类方法访问。 通过子类对象名

只能访问从父类继承过来的非私有成员

7. 私有不能被继承,私有物理上已经被继承过来,只不过逻辑上程序员不能去访问它。因

此继承必须慎重,否则会浪费内存

8. 要执行的main函数的标准写法:

public class xxx

{

public static void main(String[] args)

{

….

}

?

}

程序执行时,用java xxx 方式,其中 xxx 不能在同目录下出现.java文件重名(即有不允许有xxx.java),否则编译出错。

5.构造函数的名称与类名一定要相同,如下面中的两个public B()为构造函数,均无返回值,且都用于初始化类B的成员变量I,j,和flag,唯一不同的是一个带形参,一个不带形参。 而void show()为类B的成员函数

一个类中的成员变量:

1、 如果在定义的时候不初始化,则它的值是系统自动分配好的默认值! 如int型为零 boolean型是false

2、 如果在定义的同时赋初值, 则是可以的,也就是说该值是生效的.注意在C++中则不可以,在C++中一个类的数据成员不能在定义的同时初始化,它只能在构造函数中初始化

3、 如果在定义的同时赋初值,当然生效,但如果在构造函数中又改变了定义时赋的初值,则该数据成员最终的值就是构造函数中修改之后的那个值,因为:系统会先执行定义时赋的初值,然后再执行构造函数中赋的初值

class B(类名)

{

int i; int j = 10; boolean flag; public B()(构造函数,无返回值, 用于初始化类B的成员变量I,j,和flag) { System.out.println("以前的值是 " + i + " " + j + " " + flag); } i = 88; j = 88; flag = true;

public B(int x, int k,boolean f) (构造函数名,且无返回值,用于初始化类B的成员变量I,j,和flag)

{

i = x;

j=k;

flag = f;

}

void show()

{

System.out.println("i = " + i);

System.out.println("j = " + j);

System.out.println("flag = " + flag);

}

}

6. 所谓函数的重载,指的是在一个类中允许多个名字相同的成员函数存在,但有一个前提

就是:这些函数要么形参的个数不同,要么形参的类型不同,要么两者都不同,不允许两个函数只是函数的返回值不一样,其他都一样的情况出现,这构不成函数的重载,并且编译时会报错。因为计算机在执行函数时无法确定。

如:

class A

{

int add(int i, int j)

{

return i+j;

}

//如果两个函数只是函数的返回值不一样,其他都一样,这构不成函数的重载,并且编译时会报错!

// double add(int i, int j) 该函数与上一个函数不能重载!

// {

// return 6.0;

// }

int add(int i, int j, int k)

{

return i + j + k;

}

double add(int i, double x, int j)

{

return i + x + j;

}

}

7. 每执行New操作,都将自动重新对类成员变量进行初始化->执行构造函数-

而成员函数则不会自动执行!

class Student{

public static int cnt = 0;

private String sname;

private int sage;

public Student(){

cnt++;

}

public Student(String name, int age) {

this.sname = name; this.sage = age;

cnt++;

}

}

public class TestStatic_1{

public static void main(String[] args) {

System.out.println("Student.cnt = " + Student.cnt ); Student st1 = new Student("zhangsan", 20);

Student st2 = new Student("lisi", 30);

System.out.printf("Student类总共构造了%d个对象!\n", Student.cnt);

}

}

结果:cnt分别为0 和2

以下两个例子说明构造函数及类赋值的意义

例子A的执行结果为无,因为类初始化不会自动执行成员函数,本例中类A没有构造函数,因此在执行A aa = new A();语句中不会执行A中的成员函数f()和g(). class A

{

private int i = 10;

private void f()

{

System.out.printf("%d\n", i);

g();

}

public void g()

{

}

}

class M

{

public static void main(String[] args)

{

A aa = new A();

} }

例子B的执行结果为20,说明了类bb1和bb2相等的情况。若屏蔽红色部分,只保留兰色部分,则执行结果为10,说明不同的类在初始化时是互不影响的.,即类bb1的初始化与类bb2无关。

class B

{

public int i = 10;

public void show()

{

System.out.printf("%d\n", i);

}

}

class M

{

//

//

} public static void main(String[] args) { B bb1 = new B(); B bb2 = new B(); bb1 = bb2; bb1.i = 20; bb2.show(); bb1.i = 20; bb2.show(); }

8.关于This运算符的作用

this表示当前时刻正在调用show方法的对象,可以理解成表示一个具体的类实例.在类中定义的所有成员变量x,实际上都可以写为this.x,一般情况下this是省略的,只有当类实例化调用构造函数的形参与成员变量名字相同时,this运算符是不可以省略的,否则将出错。

程序执行结果为100,200

class A

{

private int i;

public A(int i)

{

this.i =i; //将形参 i 赋给该构造方法本次运行所创建的那个新对象的i数据成员this.i

}

public void show(){

System.out.println("i = " + i);

//this表示当前时刻正在调用show方法的对象 //this可以省略

}

}

public class TestThis

{

public static void main(String[] args){

A aa1 = new A(100);

//类aa1实例子化的方法,表示是类A的一个实例子,100表示将100传递给构造函数中的变量

aa1.show();

A aa2 = new A(200);

aa2.show();

}

}

9.This的例子

class A

{

public int i = 99;

public A(int i)

{

System.out.printf("%d\n", this.i); //此时i为99

this.i = i; //this 代表当前时刻正在创建的对象

System.out.printf("%d\n", i);

}

public void show()

{

System.out.printf("%d\n", this.i); //this 代表正在调用show方法的对象

}

}

//以下程序执行结果为:

99

2

2,

//具体过程为:i初始化赋值为99,在执行构造函数时未初始化时为99,参数传递后变为2,执行成员函数show()时又输出一次2

public class TestThis_2

{

public static void main(String[] args)

{

A aa = new A(2);

aa.show();

//System.out.printf("%d\n", aa.i);

} }

10.关于变量的初始化问题

下面的例子中类A中定义的成员变量I,flag可以初始化赋值,也可以不初始化,系统会根据该变量的类型自动初始化赋值. 而成员函数中(本例中show())的变量(又称为局部变量)局部变量编译器是不会自动进行初始化的,java要求所有

的局部变量在使用之前都必须的初始化。所以红色部分加入编译时将出错误。应将int k 改为 int k=2;即可。

class A

{

public int i = 2;

public boolean flag = true;

//也可以写为下面两句,不会影响本程序的执行结果

//public int i ;

//public boolean flag;

//也可以写为下面两句,不会影响本程序的执行结果

// int i ;

// boolean flag;

//也可以写为下面两句,不会影响本程序的执行结果

//private int i ;

//private boolean flag;

public A(int j, boolean f)

{

i = j;

flag = f;

}

public void show()

{

System.out.printf("%d\n", i);

System.out.printf("%b\n", flag); //boolean用%b或%B来输出 }

}

class TestConst_2

{

public static void main(String[] args)

{

A aa = new A(88, false);

aa.show();

// int k; //局部变量编译器是不会自动进行初始化的,java要求所有的局部变量在使用之前都必须的初始化,比如 ink k=2;

// System.out.printf("%d\n", k);

} }

11关于Public 和Private修饰符的作用

以下的例子执行结果为:

Name=张三,age=30

Name=雷平,age=40

Name=雷平,age=40

Student.Name=李四,Student.age=22

bb.Name=李四,bb.age=22

cc.Name=李四,cc.age=22

如果采用兰色的语句,则编译出错,因为用Private修饰的变量是无法用Student.name/Student.age来访问的。同时也说明类Student在实例化bb 后其成员变量的值由张三,30变为雷平,40,再实例化cc后变为李四,22. 而对于类Student,其public static成员变量name 、age而言,经过两次New后,无论是基类Student还是子类bb,cc, 最后这些变量的值都变为最后一次New的值,即覆盖式赋值:Student.Name=李四,Student.age=22 bb.Name=李四,bb.age=22

cc.Name=李四,cc.age=22。注意此处成员变量必须声明为public static 否则程序将编译出错。

class Student

{

//private static String name="张三";

//private static int age=30;

public static String name="张三";

public static int age=30;

public Student(String name, int age)

{

this.name = name;

this.age = age;

}

public void showInformation()

{

System.out.printf("name = %s, age = %d\n", this.name, this.age);

}

}

class AA

{

public static void main(String[] args)

{

System.out.printf("name = %s, age = %d\n", Student.name, Student.age); Student bb=new Student("雷平",40);

bb.showInformation();

System.out.printf("name = %s, age = %d\n", Student.name, Student.age); Student cc=new Student("李四",22);

//cc.showInformation();

System.out.printf("Student.name = %s,Student. age = %d\n",

Student.name, Student.age);

System.out.printf("bb.name = %s, bb.age = %d\n", bb.name, bb.age); System.out.printf("cc.name = %s, cc.age = %d\n", cc.name, cc.age);

}

}

12本例子中类A没有构造函数,系统将自动执行一个空的构造函数(什么也不做),程序执行结果

20

成员变量i值的变化如下:

初始化10?aa1 、aa2、aa3后为10?aa1.i=20后所有的类中的i均为20,所以结果为:

10

20

20

/*下面的程序证明了: A类的多个对象公用一个static属性i */

class A

{

public static int i = 10;

public void show()

{

System.out.printf("%d\n", i);

}

}

class M

{

}

public static void main(String[] args) { A aa1 = new A(); A aa2 = new A(); A aa3 = new A(); System.out.printf("%d\n", aa3.i); aa1.i = 20; aa2.show(); System.out.printf("%d\n", aa3.i); }

13.下面程序证明了即使没有定义子类(没有对象),仍然可以直接通过类名的方式访问该类内部的static类型的成员变量和成员函数(同时也必须满足public);当然更可以通过类对象名的方式访问(红色部分)

class A

{

public static int i = 10;

public static void f()

{

System.out.printf("20xx年5月29日15:15:50");

}

}

class TestStatic_2

{

public static void main(String[] args)

{

System.out.printf("%d\n", A.i); //直接访问基类的成员变量

A.f(); //直接访问基类的成员函数

//A aa = new A();

//aa.f();

//System.out.printf("%d\n", aa.i);

} }

14程序证明了只有非private的static成员才可以通过类名的方式访问,static只是表明了该成员具有了可以通过类名访问的潜在特征,但是否可以通过类名访问,还必须满足一个条件: 该成员必须是非private

本例中如果成员变量i和 成员函数f()虽然为static,但为private,仍然不可以直接访问。本例中由于都是private,所以编译出错。

class A

{

private static int i = 10;

private static void f()

{

System.out.printf("20xx年5月29日15:15:50\n"); }

}

class TestStatic_4

{

public static void main(String[] args)

{

A.f();

A.i = 22;

}

}

15.

静态方法(指基类名、或基类中带有static修饰的函数)不能访问非静态成员(指没有static修饰的变量和函数.); 只能访问静态成员(指有public和static修饰的变量和函数)

非静态方法(指子类名、或基类中没有static修饰的函数)可以访问非静态成员(指没有static修饰的变量和函数.)和静态成员(指有public和static修饰的变量和函数)

下面的例子说明了:静态方法不能访问非静态成员;非静态方法可以访问静态成员;此处类的成员包括成员变量和成员函数

class A

{

private static int i = 10;

public int j = 99; //非静态变量

public static void f() //静态函数

{

//g(); //error 静态方法f()不能访问非静态成员g()

//j = 22; //error

System.out.printf("FFFF\n");

}

public void g() //非静态函数(无static)

{

//f(); //OK 说明非静态方法g()可以访问静态成员f() System.out.printf("GGGG\n");

System.out.printf("%d\n", i);

System.out.printf("%d\n", j);

}

}

class TestStatic_5

{

public static void main(String[] args)

{

A aa = new A();

aa.g(); //ok 非静态方法可以访问非静态成员

//A.g(); //error静态方法不能访问非静态成员(包括变量和函数) }

}

16.关于类的继承

以下例子说明:

先定义一个类Human及其成员函数laugh()和cry()(注意这两个成员函数均为public),然后再定义一个类Student继承其父类Human,并有自己的成员函数doHomework()(也为public);最后对子类Student实例化,调用上述三个成员函数。

class Human

{

//人笑

public void laugh()

{

System.out.println("笑!");

}

//人哭

public void cry()

{

System.out.println("哭!");

}

}

class Student extends Human //定义一个类Student继承其父类Human, {

//做作业

public void doHomework()

{

System.out.println("做作业!");

}

}

public class TestExtends_1

{

public static void main(String[] args) //main函数入口

{

Student s = new Student(); //对子类Student实例化 s.laugh();

s.cry();

s.doHomework();

}

}

/*在JDK 1.6中的运行结果是:

笑!

哭!

做作业!*/

17.关于继承2

A.子类的所有方法内部都可以访问父类除私有成员以外的所有成员;

例如下面的例子:

父类A有私有成员(private)

Int s ,fs()

非私有成员(包括公有成员public和缺省成员)

缺省成员int m, int b ,fm(),fb()

公有成员Int g , fg()

则其子类B可以访问父类的成员包括上面兰色的部分:

B.同样,当对子类B实例化后,通过子类对象名可以访问父类除私有成员外的所有成员。

A和B可以访问的范围是相同的,区别在于写法不同.一个是直接调用,一个是通过子类对象名。如例子中的红色部分:

class A

{

private int s;

int m;

public int g;

protected int b;

private void fs()

{

}

public void fg()

{

}

void fm()

{

}

protected void fb()

{

}

}

class B extends A

{

//子类的所有方法内部都可以访问父类除私有成员以外的所有成员 private void g()

{

m = g = 10;

fg();

fm();

fb();

//s = 10; //error

//fs(); //error

}

}

public class TestExtends_2

{

public static void main(String[] args)

{

B bb = new B();

//通过子类对象名可以访问父类除私有成员外的所有成员 bb.g = bb.b = bb.m = 22;

//bb.s = 11; //error

//bb.fs(); //error

bb.fg();

bb.fm();

bb.fb();

System.out.println("20xx年2月10日17:44:37"); }

}

18.关于继承super的使用

A.JAVA仅支持单继承,不支持多继承。(即一个类只能有一个父类),但支持多层继承,(即B继承A,C继承B,则C继承A)

B.子类可以继承父类所有的成员变量和成员函数,但无法继承父类的构造函数,在子类的构造函数中,可以使用super(实参)语句来调用或重写父类的构造函数。

C.一个子类的构造函数中只能出现一个super(实参)语句。每个子类的构造函数的第一条语句都是隐含调用super(实参),因此在子类的构造函数中可以不写super语句,但是如果要写出来的话,则必须保证:

super()语句是第一条语句,至于super()语句是否带实参,完全取决于其父类的构造函数,两者应一致。

关于重写的概念:

所谓重写,就是指在子类中重新定义父类中已有的函数。

A.如果在子类中重写父类的构造函数,则必须要满足与父类构造函数同名、同参数(个数和类型)且返回值类型相同,同时还不能使用比父类更严格的访问权限,如父类用public,而子类用protect则是不行的,否则编译出错;同样地,子类中的其它成员函数也不允许出现与父类同名、同参数但返回值不同的情况。 下面的例子说明了上述观点:

class A //父类

{

A()

{

System.out.println("AAAA");

}

A(int i)

{

}

}

class B extends A //子类

{

B()

{

super(2); //如果把该语句注释掉的化,则编译器默认的是自动隐藏调用super(); 但如果父类没有无参的构造函数,则会报错一个子类的构造函数中只能出现一个 super(....)

System.out.println("BBBB");

}

}

class C extends B //子类

{

C()

{

//int k = 10; //如果该语句生效 则会出错,因为会导致super()语句不是构造函数的第一条语句

super(); //35行 每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有无参的构造函数,那么在编译的时候就会报错。 //super();语句可以写,也可以不写,不写的化,系统会自动调用的

//如果显示写出来的话,编译器要求该语句前面不能加任何语句,也就是说该语句必须保证是第一条语句

// super()也可以改为super(2); 但前提是父类必须有带一个参数的构造函数,否则也会报错 //如果把35行改为 super(2); 编译时就会报错!

System.out.println("CCCC");

}

}

class TestSuper_1

{

public static void main(String[] args)

{

C cc = new C();

//System.out.println("Hello World!");

}

}

//程序的运行结果:

BBBB

CCCC

总结:

1、每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。

2、如果显示的写出super();语句,则必须保证该语句是第一条语句,否则会出错

3、super();如果不写,则编译器会自动添加,所以此时如果父类没有无参的构造函数就会出错

4、既可以显示写super();前提是父类必须有无参的构造函数也可以显示写super(实参); 前提是父类必须有带参的构造函数

5、调用父类的构造函数的语句必须借助于super,不能直接写父类的类名,这与C++不同

下面的例子说明如果子类(派生类)如果不写super()语句,而父类中的构造函数是带形参的,则编译出错!

class A

{

public int i;

A(int i)

{

this.i = i;

}

}

class B extends A

{

public B()

{

super(2); //如果将本语句注释掉 则会出错,因为 “派生类构造函数中如果不写super(...); 则默认的会添加super();”

}

}

class TestSuper_2

{

} public static void main(String[] args) { A aa = new A(5); B bb = new B(); } System.out.println("Hello World!");

19.关于继承的例子

假设A派生出B B派生出C ,且类A,B,C均有名字相同的成员函数f(),编程实现调用A B C 类对象f方法的函数。本例中的关键为:类也可以作为成员函数的形参数据类型

class A

{

public void f()

{

System.out.println("AAAA");

}

}

class B extends A

{

public void f()

{

System.out.println("BBBB");

}

}

class C extends B

{

public void f()

{

System.out.println("CCCC");

}

}

public class TestPoly_2

{

//m函数可以实现调用整个A类族所有对象f方法的功能

public static void m(A xx1) //说明类也可以作为函数的形参数据类型 {

} xx1.f(); } public static void main(String[] args) { A aa = new A(); B bb = new B(); C cc = new C(); m(aa); m(bb); m(cc); }

20.关于多态的定义

一个“父类引用”类型变量既可以指向父类对象本身也可以指向它的子类对象,它可以根据当前时刻指向的不同,自动调用不同对象的成员函数,这就是多态。

class A //父类

{

public void f()

{

System.out.println("AAAA");

}

}

class B extends A //子类

{

public void f()

{

System.out.println("BBBB");

}

public void g()

{

System.out.println("哈哈");

}

}

public class TestPoly_4

{

public static void main(String[] args)

{

A aa = new B(); //定义一个父类引用aa,指向子类对象B aa.f(); //父类引用调用子类对象从父类继承过来的成员

aa=new A(); //将父类引用aa再指向父类A,并调用f();

aa.f();

}

}

定义多态的语句如下:

A aa = new B(); //等价于 A aa; aa = new B();

值得注意的是:此处的aa被称为“父类引用”,虽然它可以指向父类对象或子类对象,但是当它指向子类对象时,不能把它等同于一个子类对象,它有自己的特殊性,主要包括:

a 通过“父类引用”只能访问子类对象从父类继承过来的成员;

b 通过“父类引用”不能访问子类对象所特有的成员;

c “父类引用”永远不可能直接赋给子类引用,子类对象可以直接赋给“父类引用”, 就好比“子类可以当作父类看待,但父类不可以当作子类看待”;

d 只有在“父类引用”本身指向的就是一个子类对象时,才可以把“父类引用”强制转化为子类引用,其它情况下是不允许的;

如下面的例子:

class A

{

}

class B extends A

{

}

public class TestPoly_3

{

public static void main(String[] args)

{

A aa = new A(); //定义一个父类引用指向父类对象

B bb = new B(); //定义一个子类引用指向子类对象 //bb = aa; //error

//bb = (B)aa; //24行 error 编译没有错误,但运行时出错! 因为aa指向的是父类对象

A aa2 = new B(); //定义一个父类引用指向子类对象

// B aa3=new A(); //error 定义一个子类引用指向父类对象,是不可以的

//bb = aa2; //error 永远不可以把父类引用直接赋给子类引用 bb = (B)aa2; //OK 因为aa2 本身指向的就是一个B类对象 所以可以进行强制转化(B),注意与24行的区别 如果父类引用指向的是个子类对象,则可以通过强制类型转化把父类引用强制转化为子类引用,注意必须强制转化,在Java中无论如何绝对不可能直接把父类引用赋给子类引用的 } }

21.关于抽象类

用abstract修饰一个类时,将该类称为“抽象类”,在定义函数时,只给出方法头,而没有方法体(连大括号都没有),这样的函数称为“抽象函数”或“抽象方法”,此时必须在函数名前加上abstract修饰符。

例如:public abstract void f();

“抽象类”是不可以派生的,(即不可用New方法实例化),但可以定义一个抽象类的引用,用抽象类的引用访问子类的方法(这就是多态)。

如下面的例子:

abstract class A

{

public abstract void f(); //抽象类的成员函数不一定是抽象函数,但有 //抽象函数的类一定是抽象类

}

class B extends A

{

public void f()

{

System.out.println("哈哈");

}

}

public class TestAbs_1

{

public static void main(String[] args)

{

//A aa1 = new A(); //error抽象类不可以派生

A aa2 = null; //可以定义一个抽象类的引用

aa2 = new B(); //将子类对象的地址赋给抽象类的引用

}

} aa2.f(); //用抽象类的引用访问子类的方法 这就是多态

22.关于final关键字

final关键字可以修饰类、类中的若干属性和类中的若干函数。使用final关键字修饰的类将不能被继承;

语法形式:public final class A{ } (其中public 和final可以互换)

使用final关键字修饰的类的属性表示该属性必须被赋值且只能赋值一次(系统缺省的变量初始化不算),该赋值语句只能在定义成员变量的同时初始化或者在类中所有的构造函数中初始化。

一个类的所有方法内部都不可以修改final修饰过的成员变量的

下面的例子来说明:

/* final类型修饰的属性必须在定义的同时初始化,如果final类型修饰的属性没有在定义的同时初始化,则必须在该类中的所有构造函数中完成初始化

不过这两种初始化只能存在一种,否则编译时会报错!因为final表示常量的意思,常变量当然不能被初始化两次了*/

class Point

{

int x;

final double PI = 1.9; //10 final定义的变量必须在定义的同时初始化 如果这里只定义不初始化则我们就必须在所有的构造函数中完成对final变量的初始化 不过这两种方式只能选择其中的一种

Point()

{

//PI = 1.234; //只要10行对PI进行了初始化,本语句就必须的被注释掉,否则编译时会报错!

}

Point(int m, int n)

{

//PI = 2.33; //只要10行对PI进行了初始化,本语句就必须的被注释掉,否则编译时会报错!

}

void output()

{

//PI = 2; //error 因为“一个类的所有方法内部都不可以修改final修饰过的成员变量的”

System.out.printf("%d %f\n", x, PI);

}

public static void main(String[] args)

{

Point pt = new Point();

pt.output();

}

}

程序运行结果是:

0 1.900000

23 关于接口

接口就是抽象方法和常量的集合,本质上是一种特殊的抽象类。也就是说在接口的定义中,所有的成员变量(属性)都必须是public static final类型的,所有的成员函数都必须是public abstract类型的。这些修饰符可以全部或部分省略

如下面的例子:

interface It //定义接口lt

{

int i = 10; //不能改为 int i;

void f();

voidg();

}

类可以实现某个接口,但不能继承接口

例如:

interface It //定义接口lt

{

int i = 10;

}

class A implements It //定义一个类A并实现接口It

{

public A(int j)

{

//this.i = j; //error 接口It中的属性i 是public static final 类型,不可以在实现类中被改变

}

}

class TestInter_1

{

public static void main(String[] args)

{

A aa = new A(55);

System.out.println("aa.i = " + aa.i);

System.out.println("aa.i = " + A.i);

}

}

执行结果:10,10

接口可以多重继承,即一个接口可以有多个父接口,但是一个类只能有一个父类,Java类不允许多继承,接口却允许多继承;

一个类可以在继承一个父类的同时实现一个或多个接口,但extends关键字必须的在implements 之前

class A

{

}

interface It1

{

}

interface It2 {

}

//接口可以多重继承,即一个接口可以有多个父接口,但是一个类只能有一个父类,Java类不允许多继承,接口却允许多继承

interface It3 extends It1, It2

{

}

interface It4

{

int i = 20;

}

//一个类可以在继承一个父类的同时实现一个或多个接口,但extends关键字必须的在implements 之前

class T extends A implements It4,It3

{

}

class TestInter_2

{

public static void main(String[] args)

{

System.out.println("嘿嘿!");

}

}

不可以用New的方法派生接口对象,但可以定义一个“接口引用”对象变量并将其指向实现接口的类对象,以达到多态的目的。

interface It

{

void f();

void g();

}

class A implements It //类A实现接口It

{

public void f() //在类A中调用接口It的函数的方法,public不可少 {

System.out.println("nnmaaa");

}

public void g()

{

System.out.println("sssnnmaaa");

}

}

class M

{

public static void main(String[] args)

{

It it=new A(); //定义接口引用it指向类 A,而类A实现了接口It,因此实现 it.f(); //了接口的多态

}

}

接口与抽象类的区别:

接口中的函数不允许有方法体,而抽象类中则允许;

接口可以多继承,而类只能单继承

24 关于Java的一些特殊函数

toString()

特别注意:toString()函数的名称大小写,错一点都不行!!

System.out.println(类对象名)

该语句实际输出的是该对象的toString()函数所返回的字符串,如果在该类中没有定义toString()函数,则返回的是类名+该类对象哈希码组成的一个字符串。如下面的例子:

class A

{

public String toString()

{

return "helloworld!" ;

}

}

public class TestToString

{

public static void main(String[] args)

{

A aa = new A();

System.out.println(aa);

}

}

执行结果:

如果有兰色部分,则为helloworld. 否则为:A@de6ced

25.Java的String类常用的方法(成员函数)

a.判断字符串是否以prefix字符串开头

public boolean startsWith(String prefix)

b.判断字符串是否以prefix字符串结尾

public boolean endWith(String prefix)

c.返回一个字符串为该字符串的大写形式

public string toUpperCase()

d.返回一个字符串为该字符串的小写形式

public string toLowCase()

e.返回该字符串从beingIndex开始到结尾的子字符串

public String substring(int beginIndex)

f .返回该字符串从beingIndex开始到endIndex结尾的子字符串 public String substring(int beginIndex,int endIndex)

g. 返回字符串中第index个字符

public char charAt(int index)

h. 返回字符串的长度

public int length()

I . 返回字符串中出现str的第一个位置

public int indexof (String str)

j. 返回字符串中从fromIndex开始出现str的第一个位置

public int indexof(String str,int fromIndex)

k. 比较字符串与another是否一样(忽略大小写)

public boolean equalsIgnoreCase(String another)

l. 在字符串中用newChar字符替换oldChar

public String replace(char oldChar,char newChar)

String类的强制转换方法(成员函数)

public static String valueOf()

可以将基本类型数据转换为字符串

public String[ ] split(String regex)

可以将一个字符串按照指定的分隔符分隔,返回分隔后的字符串数组。

例子如下: class Test

{

public static void main(String[] args)

{

String s1="sun java",s2="Sun Java"; //String类的定义方法 System.out.println(s1.charAt(1)); //结果为u

System.out.println(s2.length()); //8

System.out.println(s1.indexOf("java"));//4

System.out.println(s1.indexOf("Java"));//-1

System.out.println(s1.equals(s2));//false

System.out.println(s1.equalsIgnoreCase(s2));//true

String s="我是程序员,我在学java";

String sr=s.replace("我","你");

System.out.println(sr);

String S="Welcome to Java World!";

String S1=" sun java ";

System.out.println(S.startsWith("Welcome")); //true

System.out.println(S.endsWith("World")); //false

String sL=S.toLowerCase();

String sU=S.toUpperCase();

System.out.println(sL+sU);

String subs=S.substring(11);

System.out.println(subs); //Java World!

String sp=S1.trim();

System.out.println(sp); //sun java

int j=1234567;

String sNumber=String.valueOf(j);

System.out.println("j 是"+sNumber.length()+"位数"); String ss="Mary,F,1976";

String[] sPlit=ss.split(",");

for (int i=0; i<sPlit.length;i++)

{

System.out.println(sPlit[i]);

}

}

}

重要提示:

①定义String类时,注意String的大小写;

②String类的成员函数名称也要注意大小写;

③字符串位置下标从0开始;

④字符串找不到时返回值为-1;

⑤在String定义时要使用双引号;

⑥String定义严格区分大小写,同时不可重复定义或覆盖;

⑦java.lang.String类对象表示不可修改的Unicode编码字符串; ⑧在Java中用双引号括起来的字符串也被当作String对象; System.out.println(“abc”.length); // 3

System.out.println(“abc”.equals(“abc”));//true

⑨关于String类中注意“==”和“equals”符号含义的区别; 如下面例子:

class A

{

public int i = 10;

}

public class TestObjectEquals

{

public static void main(String[] args)

{

A aa1 = new A();

A aa2 = new A();

if (aa1.equals(aa2))

{

System.out.println("aa1 == aa2");

}

else

{

System.out.println("aa1 != aa2"); //aa1和aa2分配的是两块不同的内存,但这两块内存的值都是一样的,尽管如此,还是返回false, } aa1 = aa2; //让aa1和aa2指向同一块内存空间,则返回true if (aa1.equals(aa2))

{

System.out.println("aa1 == aa2");

}

else

{

System.out.println("aa1 != aa2");

}

String str1=new String("china");

String str2=new String("china"); //str1和str2很明显指向不同的对象 System.out.println(str1.equals(str2)); //true

System.out.println(str1==str2); //false

String str3="china";

String str4="china"; //str3 和 str4都指向了匿名对象"hello"

System.out.println(str3.equals(str4)); //true

System.out.println(str3==str4); //ture

}

}

程序运行结果是:

------------------------------

aa1 != aa2

aa1 == aa2

------------------------------

String类的equals方法用于比较内容是否相等;而其它Object类的equals方法则用于判断两个对象是否为同一个对象(即是否指向同一块内存),这是String类与其它类不同的地方!

总结: str1 == str2 是用来比较str1变量本身所占内存的值和str2变量本身所占内存的值是否相等

str1.equals(str2) 是用来比较str1变量本身所占内存的值所指向的对象和str2变量本身所占内存的值所指向的对象的内容是否相等

也就是说如果str1和str2占用不同的内存,但是这两个不同内存的值是一样的,Stirng.equals()方法也会返回true.但是Object中的equals()方法却是返回false,Object中就含有equals()方法,不过String类重写了Object中的equals()方法API:

equals

public boolean equals(Object anObject)将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。

覆盖:

类 Object 中的 equals

参数:

anObject - 与此 String 进行比较的对象。

返回:

如果给定对象表示的 String 与此 String 相等,则返回 true;否则返回 false。 另请参见:

compareTo(String), equalsIgnoreCase(String)

26 Java的StringBuffer类的构造函数和常用的方法(成员函数)

下面为StringBuffer类的构造函数

创建一个空的没有任何字符的StringBuffer对象

public StringBuffer()

创建一个不带字符,但具有指定初始容量的字符串缓冲区

public StringBuffer(int capacity)

创建一个StringBuffer对象,包含与str对象相同的字符序列

public StringBuffer(String str)

StringBuffer类常用的方法(成员函数)有:

a. 为StringBuffer对象添加字符序列

public StringBuffer append(String str)

…..

b. 为StringBuffer对象在指定位置插入字符序列,返回修改后的StringBuffer对象引用。

public StringBuffer insert(int offset,String str)

public StringBuffer insert(int offset,double d)

c. 可以删除从start开始到end-1为止一段字符序列,返回修改后的StringBuffer对象引用

public StringBuffer delete(int start,int end)

d. 将字符序列逆序输出

public StringBuffer reverse()

e. 与String类含义类似的方法(成员函数)

public int indexof(String str)

public int indexof(String str,int fromIndex)

public String substring(int start)

public String substring(int start,int end)

public int length()

下面的例子说明StringBuffer类的方法:

public class TestStringBuffer{

public static void main(String[] args){

StringBuffer sb = new StringBuffer(); //StringBuffer类的定义方法 sb.append("abc");

sb.append("123");

System.out.println("sb = " + sb); //sb = abc123

sb.insert(3, "--");

System.out.println("sb = " + sb); //sb = abc--123

sb.delete(2,6); //把下标从2开始到6-1结束的字符删除

System.out.println("sb = " + sb); //sb = ab23

sb.reverse();

System.out.println("sb = " + sb); //sb = 32ba

String str = sb.toString();

System.out.printf("str = " + str); //str = 32ba

}

}

27Java中String类和StringBuffer类的区别:

String类对象一旦创建就不可更改,因此如果需要经常对字符串内容更改的话,一般不使用String类定义,而用StringBuffer类。

28Java的内部类

在A类的内部但是在其所有的成员函数(方法)的外部定义了一个B类,则称B类是A类的内部类,A是B的外部类。

内部类的访问原则

内部类的方法(成员函数)可以访问外部类所有的成员;注意:此时内部类和内部类的方法都不能是静态static类型的! 而外部类的方法不可以直接访问内部类的成员。注意:只能通过实例化访问内部类的成员!

内部类可以让一个类方便地访问另一个类中的所有成员,并可有效避免其他不相关类对该类的访问,有助于增加程序的安全性;如果一个A类要使用B类的所有

成员,且A类不需要除B类以外的其它类访问,则可以把A类定义为B的内部类。

以下程序说明的内部类的访问原则:

class A{

private (static) int i = 1; //int i

private void f(){

System.out.println("哈哈");

}

//B是A的内部类,但不可以是static类型的

static class B{ public int bi = 10; public static void g() //非静态的内部方法可以访问外部类所有的成员 { System.out.printf("i = %d\n", i); f(); } } public void k(){ //g(); //error 外部类的方法不可以直接访问内部类的成员 //System.out.println(bi); //error 外部类的方法不可以直接访问内部类的成员 B bb = new B();

bb.g(); //外部类的方法只能通过实例化访问内部类成员 }

}

public class Test{

public static void main(String[] args){

A aa = new A();

aa.k();

}

}

29 Java的匿名类

定义:

通常的编程例子,输入一个数,求出其平方:

import javax.swing.JOptionPane; //引用的java类

class Square2

{

public static void main(String args[])

//public static void main(String[] args) 这两种写法均不错

{

String s=JOptionPane.showInputDialog("输入一个浮点数:");

double d=Double.parseDouble(s);

double dd=d*d;

JOptionPane.showMessageDialog(null,s+"的平方根为:"+dd,"标题

",JOptionPane.PLAIN_MESSAGE);

System.exit(0);

}

}

JAVA类的继承关系:

javax.swing.JApplet?java.awt.Applet?java.awt.Panel?java.awt.Container?Java.awt.Component?java.Object

关于applet程序:

可以将.java文件编译成.class文件后,将其加载到HTML文件的CODE属性中,使用appletviewer来执行。如下面的AAA.HTML文件内容 :

<APPLET CODE=”test.class” WIDTH=200 HEIGHT=100>

</APPLET>

执行顺序:先init(),然后start();最后paint(),要想变量可以在这三个方法中传递,需将其定义到方法()的外面。如:

Int s,n

Init(s,n)?start(s,n)?paint(s,n)

关于main函数参数调用的例子

class Sumall

{

public static void main(String args[])

{

int n=Integer.parseInt(args[0]);

//将main函数的第1个参数值强制转化为Int并调用

String str1=args[1];

//将main函数的第2个参数值直接赋给str1并调用

int sum=0 ; int i=0;

while(i<=n)

{sum=sum+i;

//i=i+1;} //i=i+1与i++均可

i++;}

System.out.println("sum=" + sum);

System.out.println("str1=" + str1);

}

}

执行时使用:

Java Sumall 10 “dd” 即可将10和dd传递到程序中,注意参数之间有空格,对于字符串可使用单或双引号。

注意与do….while语句的区别

while 为先判断再执行,而do …while为先执行再判断。

关于break和continue语句的作用:

Break语句只能出现在do 、for、 switch、 while等循环体内部,若条件满足,则只中止该层次的执行,而继续执行下一循环,若要中止整个嵌套循环,可使用return语句。

Continue语句用在do、 for、 while语句本体中,若条件满足,则忽略其后的循环体语句,然后继续执行下一个循环体。

关于return语句的例子

class Ret

{

public static void main(String args[]) //main后面的参数不可以不要

{

int result=sum(2,5);

System.out.println("和为" + result);

}

static int sum(int a, int b)

{

return(a+b);

}

}

关于异常事件的捕获与处理 throw语句

class DividedByZero extends ArithmeticException {

public DividedByZero() //构造函数 {

super("除数不可以为0!!");

}

}

class ThrowTest

{

public static void main(String args[])

{

System.out.println("9/3=" + divide(9,3)); System.out.println("7/0=" + divide(7,0)); }

public static int divide(int a,int b)

{

if (b!=0)

return(a/b);

else

throw new DividedByZero();

}

}

关于Try语句的例子(错误处理)

class TryTest

{

public static void main(String args[])

{

int a ;

String s="s89" ;

try

{

a=Integer.parseInt("123");

System.out.println("a=" + a);

a=Integer.parseInt(s);

System.out.println("s=" + s);

}

catch (NumberFormatException e)

{

System.out.println("NumberFormatException:" + s + "不能转换成整数!"); }

}

}

标准结构:

try

{……}

catch() {….}

catch() {….}

finally

{…}

关于锁定语句synchronized

它可以锁定对象,让指定的程序代码执行时不受干扰。通常用在处理大量数据,如大数组赋值等的情况,防止未完成赋值而其它线程进行存取时发生错误。 例如;

static int a[]=new int[10000];

public SynTest()

{

synchronized(a)

{

for (int i=0;i<a.length;i++)

{

a[i]=I;

}

}

}

关于JAVA的类

System类

三个成员函数(或方法)

System.in 标准输入

System.out 标准输出

System.err.标准错误输出

同时提供对象的拷贝、取得及设置系统属性、取得及设置安全数据、载入文件和程序库等功能。

以下为从键盘输入的例子:

import java.io.* ;

class KeyInStr

{

public static void main(String args[]) throws Exception

{

BufferedReader br=new BufferedReader(new

InputStreamReader(System.in));

String s;

System.out.print("输入一个字符串");

System.out.flush(); //将缓冲区中的信息清除

s=br.readLine();

/* 此处可以对输入的字符串进行类型转换

如:double d=Double.parseDouble(s);

*/

System.out.println("你输入的是:" + s);

} }

以下为逐行读取文本文件的例子

import java.io.* ;

class ReadFile

{

public static void main(String args[]) throws Exception

{

BufferedReader br=new BufferedReader(new FileReader("person.txt")); String s;

while (br.ready()) //ready方法检查输入缓冲区是否有数据,有则为true,否则为false

{

s=br.readLine();

System.out.println("你读入的是:" + s);

}

} }

以下为从键盘逐行输入并写入文件的例子

import java.io.* ;

class WriteFile

{

public static void main(String args[]) throws Exception

{

BufferedReader br=new BufferedReader(new

InputStreamReader(System.in));

BufferedWriter bw=new BufferedWriter(new FileWriter("myself.txt")); String s;

while (true)

{

System.out.print("输入一个字符串:");

System.out.flush();

s=br.readLine();

if(s.length()==0) break; //length后的括号容易漏掉

bw.write(s);

bw.newLine(); //换行

}

bw.close();

} }

以下为文件拷贝的例子

import java.io.* ;

class CopyFile

{

public static void main(String args[]) throws Exception

{

BufferedReader br=new BufferedReader(new FileReader("person.txt")); BufferedWriter bw=new BufferedWriter(new FileWriter("mycopy.txt")); String s,space=" ";

int num=0;

while (br.ready())

{

s=br.readLine();

num++;

bw.write(String.valueOf(num));

bw.write(space);

bw.write(s);

bw.newLine();

}

bw.close();

} }

以下是另一个文件拷贝的例子

将源文件逐行读出并变成一个个的句元,遇到空格后就换行,处理后再复制到另一个文件中。

import java.io.* ;

class Token

{

public static void main(String args[]) throws IOException

{

BufferedReader br=new BufferedReader(new FileReader("person.txt")); BufferedWriter bw=new BufferedWriter(new FileWriter("token.txt")); StreamTokenizer st=new StreamTokenizer(br);

int tokeType;

st.whitespaceChars(0,32);

st.eolIsSignificant(true);

while (br.ready())

{

tokeType=st.nextToken();

switch (tokeType)

{

case StreamTokenizer.TT_NUMBER:

bw.write(String.valueOf((long)st.nval));

bw.newLine();

break;

case StreamTokenizer.TT_WORD:

bw.write(st.sval);

bw.newLine();

break;

default:

;

}

}

bw.close();

} }

以下为屏幕输出的例子

关于函数的设计

class XSquare //定义一个外部类

{

int square(int x) //定义成员函数

{

return (x*x);

}

}

class Square //定义主程序类

{

public static void main(String args[]) throws Exception

{

int n=Integer.parseInt(args[0]);

XSquare obj=new XSquare(); //类实例化

int result=obj.square(n); //调用类的成员函数

System.out.println(result);

}

}

本例子中调用的是外部类中的成员函数,如果要调用本类中的成员函数,则该成员函数必须声明为static,如下面的例子.

class Square2 //定义主程序类

{

static int square(int x) //在本类中定义成员函数

{

return (x*x);

}

public static void main(String args[]) throws Exception

{

int n=Integer.parseInt(args[0]);

int result=square(n); //直接调用本类中的成员函数

System.out.println(result);

} }

函数地址传递的例子

class CallByRef

{

static String show(int b[])

{

String result="";

for (int i=0;i<b.length;i++)

result=result+b[i]+" ";

return result;

}

static void passArray(int c[])

{

for (int i=0;i<c.length;i++) c[i]=c[i]*2;

}

public static void main(String args[])

{

int a[]={1,2,3}; //数组赋值

System.out.println("传递之前数组a" + show(a)); passArray(a);

System.out.println("传递之后数组a" + show(a)); }

}

递归调用的例子

class Factor

{

static long factorn(long i)

{

if (i==1)

return 1;

else

return i*factorn(i-1) ;

}

public static void main(String args[])

{

long n=Long.parseLong(args[0]);

long result=factorn(n);

System.out.println(n + "!=" + result);

}

}

递归调用也可以用重复语句执行来完成,如上面的例子 for (int i=0;i<=n;i++)

result=result*i

函数重载的例子

class Overload

{

static int square(int n) { return n*n ;}

static double square(double n) { return n*n ;}

public static void main(String args[])

{

int n=Integer.parseInt(args[0]);

double x=Double.parseDouble(args[1]);

System.out.println(n + "*" +n + "=" + square(n));

System.out.println(x + "*" +x + "=" + square(x));

} }

关于Math类

该类以static方式提供数学上常用的常数、常用的函数包括算术的、三角函数的、指数的、对数的、随机数以及某些转换函数等。

class MathTest

{

public static void main(String args[])

{

double r=Math.random();

int n=(int)(r*100);

System.out.println("随机数=" + n);

double pi=Math.PI;

double s=Math.sin(pi/6);

System.out.println("30度正弦值为:=" +s);

double root=Math.sqrt(100.0);

double d=Math.pow(2,3);

System.out.println("root=" +root);

System.out.println("d=" +d);

} }

P110

关于Applet类

主要的几个成员函数及执行顺序

Init()?start()?paint()?stop()?destroy()

Init() 通常用于载入applet程序时被调用;

start()通常在init()执行后调用;

paint()通常在start()后调用;

stop()通常在退出网页或applet程序时调用;

destroy()在离线时释放本对象及其相关的资源;

如下面的例子:

import java.awt.Graphics;

import javax.swing.JApplet;

public class Myapplet extends JApplet

{

StringBuffer sb=new StringBuffer();

int x,y;

public void init() {sb.append("init(...)代码");x=10;y=10;}

public void start() {sb.append("start(...)代码");}

public void stop() {sb.append("stop(...)代码");}

public void destroy() {sb.append("destroy(...)代码");}

public void paint(Graphics g)

{

sb.append(" paint()代码");

g.drawString(sb.toString(),x,y);

}

}

Applet程序与普通的java程序最大的区别在于:

a. 没有main()类

b. 不能直接用java xx.来运行

c. 必须创建一个html文件,文件格式固定,将编译好的类xx.class加到该html

文件中,然后使用appletviewer xx.html来执行。

关于数组

数组一般属于静态static的,即建立时就决定了数组的数据类型和个数;数组下标从0开始;a[x][y]表示第x行y列元素;数组声明时若不赋值,则必须使用new语句获得内存空间。例如:

Int a[];

a=new int[6];

或者; int a[]=new int[6];

以下数组排序的一个例子

public class BubbleSort

{

static String printArray(int[] a)

{

String result="" ;

for (int i=0;i<a.length;i++) result+=a[i] + " " ;

return result;

}

static int[] bubbleSort(int[] a)

{

int t;

for(int i=0;i<a.length;i++)

{

for(int j=0;j<a.length-i-1;j++)

if(a[j]>a[j+1]) {t=a[j];a[j]=a[j+1];a[j+1]=t;}

}

return a;

}

public static void main(String args[])

{

int a[]={25,36,47,32,12,39};

System.out.println("排序前:\n" +printArray(a));

a=bubbleSort(a);

System.out.println("排序后:\n" +printArray(a));

}

}

关于调用自定义类的方法:

a. 首先定义一个类:(SelfClass.java)

public class SelfClass

{

String name="leip";

String sex="男";

public void mymetho1()

{

System.out.println(name);

}

}

b. 然后进行编译 javac SelfClass.java 成功后生成一个SelfClass.class文件; c. 在当前目录下建立一个子文件夹,如myselt,将SelfClass.class文件拷贝到该目录中,注意不要将同名的.java文件也拷贝进去。

d. 建立一个UseMyclass.java文件就可以调用了,如下面的例子

import myself.* ; //该句与建立的文件夹要对应,不能少了*.

public class UseMyclass

{

public static void main(String args[])

{

SelfClass aa=new SelfClass();

System.out.println(aa.name);

System.out.println(aa.sex);

aa.mymetho1();

} }

关于类的一些基本概念

1. 类的成员变量或函数前加public表示有权存取该类就有权存取该成员变量

或函数;若加上private表示只有本类中的成员函数才有权存取该成员变量或函数,要求类的成员变量或函数必须加public或private。

2. 在一个类定义中,通常的做法为成员变量声名为private,而成员函数声名

为public.,当然你也可将成员变量声名为public,将成员函数声名为private,但这样定义是不常见的,也是危险的。

3. 定义在成员函数中的变量称为局部变量,只能在该函数中使用;如果该局

部变量名字与类中定义的成员变量名字相同,则成员变量就隐藏起来,此时如果要使用该隐藏的成员变量,则必须通过this对象。如:this.a,其中this表示的是类。

4. 在类中定义private的成员变量主要是为了数据封装;达到不能类的使用

者看到/访问这些成员;这样可以有效保护成员变量不被修改。但是,如果确实要在类调用中要存取这些private成员变量时,可以通过在类中定义public类型的get和set成员函数的方法实现间接调用。这样做既可以保护数据,又可以对数据进行检验后在修改。如下面的例子:

public class aa

{

private int hour;

public int getHour(){ return hour;}

public int setHour(){hour=((hh>0&&hh<24)?hh:0);}

}

当然,对于private类型的成员函数则一般用于类内部的数据检验,类调用时无法看见。

5. 对于常量的定义,只须在变量声明时加上final关键字即可,这样就变成了

常量,常量在代码中是不可以修改的.

例如:private static final double pi=3.14159

6. 类本身也可以作为另一个类的成员变量;

7. 当一个类的成员变量或函数之前没有修饰字(也可称为友谊成员),称为友

谊存取(friendly access)或套件存取(package acccess)表示同一个目录中的类均可存取。若程序中包含许多类,那么类间可以通过友谊成员互相直接使用变量或方法的名称,而省略set和get方法,但它会破坏信息的隐藏,因此要慎重使用。

如下面的例子:

class Friend

{

Int y;

String s;

public Friend()

{

y=0:s=new String(“Hello!”);

}

public String toString()

{

Return “y=” + y + “s=” + s ;

} }

public class MyFriend

{

Private static Friend f;

Public static void main(String args[])

{

f=new Friend();

f.y=2000;

f.s=new String(“xxxxx”);

System.out.println(f,toString());

}

}

8. 关于静态变量的理解

一个类中定义的静态变量可以被该类所有对象使用,它相当于该类所有对象的公共数据域,可以理解为公共记数器,每调用一次,其值会发生一次变化,并且该变化同时会影响到其它对象的调用。必须用static进行修饰;

9. 数据抽象与信息隐藏(接口)

JAVA要求成员函数中定义的局部变量在使用时一定要赋值,在类中定义的局部变量由于系统会自动赋初始化值而除外。当然也不包括成员函数的形参

P147

比如说你新建一个包,下面再放你自己写的类,那样你就可以引用自己的类了 //A.java

package abc;

public class A{

...

}

//使用类A

import abc.A;

punlic class B{

...

A a = new A();

}

这就是一个简单的包的用法

其实JAVA也是这么做的

只是它的包是有规律的

比如JAVA.LANG包是通用的

但是要使用Arraylist就得引入java.util.arraylist包了

相关推荐