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就调用重写的方法.
看看下面的例子,用匿名类创建一个对象,并向一个方法的参数传递一个匿名类的对象.
复制内容到剪贴板
代码:
<BR>class Cubic <BR>{ double getCubic(int n)<BR> { return 0;<BR> }<BR>}<BR>abstract class Sqrt<BR>{ public abstract double getSqrt(int x);<BR>}<BR>class A<BR>{ void f(Cubic cubic)<BR> { double result=cubic.getCubic(3);//执行匿名类体中重写的getCubic()<BR> System.out.println(result);<BR> } <BR>}<BR>public class E<BR>{ public static void main(String args[])<BR> { A a=new A();<BR> a.f(new Cubic() //使用匿名类创建对象,将该对象传递给方法f的参数cubic <BR> { double getCubic(int n)//类体<BR> { return n*n*n;<BR> }<BR> }<BR> );<BR> Sqrt ss=new Sqrt() //使用匿名类创建对象,ss是该对象的上转型对象 <BR> { public double getSqrt(int x) //匿名类是abstract类Sqrt的一个子类,所以必须实现getSqrt()方法<BR> { return Math.sqrt(x); <BR> }<BR> };<BR> double m=ss.getSqrt(5); //上转型对象调用子类重写的方法<BR> System.out.println(m);<BR> } <BR>}</P> <P>
b) 和接口相关的匿名类
假设Computable是一个接口,那么,java允许直接调用接口名和一个类体创建一个匿名对象,此类体被认为是实现Computable接口的
类去掉类声明后的类体,称为匿名类.下面这个例子就是用实现了Computable接口的类(匿名类)创建对象:
复制内容到剪贴板
代码:
interface Cubic <BR>{ double getCubic(int n);<BR>}<BR>interface Sqrt<BR>{ public double getSqrt(int x);<BR>}<BR>class A<BR>{ void f(Cubic cubic)<BR> { double result=cubic.getCubic(3); //执行匿名类体中实现getCubic()方法<BR> System.out.println(result);<BR> } <BR>}<BR>public class E<BR>{ public static void main(String args[])<BR> { A a=new A();<BR> a.f(new Cubic() //使用匿名类创建对象,将该对象传递给方法f的参数cubic<BR> { public double getCubic(int n)<BR> { return n*n*n;<BR> }<BR> }<BR> );<BR> Sqrt ss=new Sqrt() //使用匿名类创建对象,接口ss存放该对象的引用<BR> { public double getSqrt(int x)//匿名类是实现Sqrt接口的方法,所以必须要实现getSqrt方法<BR> { return Math.sqrt(x); <BR> }<BR> };<BR> double m=ss.getSqrt(5); //接口回调类实现的方法<BR> System.out.println(m);<BR> } <BR>}<BR>
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语句的用法,如:
复制内容到剪贴板
代码:
<BR>public class E<BR>{ public static void main(String args[ ]) <BR> { int n=0,m=0,t=555;<BR> try{ m=Integer.parseInt("8888");//Integer.parseInt是可以将数字格式的字符串转换成int型数据<BR> n=Integer.parseInt("abc789");//"abc"不是属于数字格式的字符串,所以通过Integer.parseInt转换时会出现异常<BR> t=9999; //发生异常后就立刻进入catch部分,所以t=9999没有被执行<BR> }<BR> catch(NumberFormatException e)<BR> { System.out.println("发生异常:"+e.getMessage());//得到发生异常的部分<BR> e.printStackTrace();<BR> n=123;<BR> }<BR> System.out.println("n="+n+",m="+m+",t="+t);<BR> }<BR>}//结果应该是n=123,m=8888,t=555</P> <P>
在程序中也可以扩展Exception类定义自己的异常类,然后规定哪些方法产生这样的异常.一个方法在声明时可以使用throws关键字声明要产生的若干异常,并在该方法的方法体中具体给出产生异常类的操作,即用相应的异常类创建对象,并使用throw关键字抛出该异常类,导致该方法结束执行.程序必须在try-catch语句中调用能发生异常的方法,其中catch的作用就是捕获throw方法抛出的异常现象.
注意:throw时java的关键字,该关键字的作用就是抛出异常.throw和throws是两个不同的关键字.
下面的例子中,Computer类中有一个计算最大公约数的方法,如果向该方法传递负整数,方法就抛出定义的异常.
复制内容到剪贴板
代码:
</P> <P>class NopositiveException extends Exception//子定义的异常类<BR>{ String message;<BR> NopositiveException(int m,int n)<BR> { message="数字"+m+"或"+n+"不是正整数";<BR> }<BR> public String toString()<BR> { return message;<BR> }<BR>}<BR>class Computer<BR>{ public int getMaxCommonDivisor(int m,int n) throws NopositiveException//声明NopositiveException自定义的异常类<BR> { if(n<=0||m<=0)//不满足条件时候<BR> { NopositiveException exception=new NopositiveException(m,n);//创建自定义异常类的对象,用来抛出异常<BR> throw exception; //抛出异常,结束方法的执行<BR> }<BR> if(m<n)<BR> { int temp=0;<BR> temp=m;<BR> m=n;<BR> n=temp;<BR> }<BR> int r=m%n;<BR> while(r!=0) <BR> { m=n;<BR> n=r;<BR> r=m%n;<BR> }<BR> return n;<BR> }<BR>}<BR>public class E<BR>{ public static void main(String args[])<BR> { int m=24,n=36,result=0;<BR> Computer a=new Computer();<BR> try { result=a.getMaxCommonDivisor(m,n);<BR> System.out.println(m+"和"+n+"的最大公约数 "+result);<BR> m=-12;<BR> n=22;<BR> result=a.getMaxCommonDivisor(m,n);<BR> System.out.println(m+"和"+n+"的最大公约数 "+result);<BR> }<BR> catch(NopositiveException e)<BR> { System.out.println(e.toString());<BR> }<BR> }<BR>}</P> <P>
4. Class 类
Class 是java.lang包中的类,该类的实例用来封装对象运行时的状态.当一个类被加载且创建对象时,和改类相关的一个类型为Class的对象就会自动创建.Class类本身不提供构造方法,因此,不能用new运算符和构造方法创建一个Class对象.任何对象调用getClass()方法都可以获取和该对象相关的一个Class对象,这个Class对象调用如下的方法可以获取创建对象的类的有关信息,比如类的名字,类中的方法名称,成员变量的名称等.
String getName() //返回类的名字
Constructor[] getDeclaredConstructors() //返回类的全部构造方法
Field[] getDeclaredFields() //返回类的全部成员变量
Method[] getDeclaredMethods() //返回类的全部方法
执行下面的例子来演示这几个函数的作用,如
复制内容到剪贴板
代码:
<BR>import java.lang.reflect.*;<BR>class Rect <BR>{ double width,height,area;<BR> public double getArea()<BR> { area=height*width;<BR> return area;<BR> }<BR>}<BR>public class E<BR>{ public static void main(String args[])<BR> { Rect rect=new Rect();<BR> Class cs=rect.getClass();//通过getClass来获取rect这个对象<BR> String className=cs.getName();<BR> Constructor[] con=cs.getDeclaredConstructors();<BR> Field[] field=cs.getDeclaredFields() ;<BR> Method[] method=cs.getDeclaredMethods();<BR> System.out.println("类的名字:"+className);<BR> System.out.println("类中有如下的成员变量:");<BR> for(int i=0;i<field.length;i++)<BR>{ System.out.println(field[i].toString());<BR> }<BR> System.out.println("类中有如下的方法:");<BR> for(int i=0;i<method.length;i++)<BR> { System.out.println(method[i].toString());<BR> }<BR> System.out.println("类中有如下的构造方法:");<BR> for(int i=0;i<con.length;i++)<BR> { System.out.println(con[i].toString());<BR> }<BR> } <BR>}</P> <P>
创建对象最常用的方式就是使用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类必须有无参数的构造方法.
看看下面的例子,如
复制内容到剪贴板
代码:
<BR>class Rect <BR>{ double width,height,area;<BR> public double getArea()<BR> { area=height*width;<BR> return area;<BR> }<BR>}<BR>public class<BR>{ public static void main(String args[])<BR> { try{ Class cs=Class.forName("Rect");//没有通过new来创建对象,用forname()制定类的实例<BR> Rect rect=(Rect)cs.newInstance();//得到此实例即创建对象<BR> rect.width=100;<BR> rect.height=200;<BR> System.out.println("rect的面积"+rect.getArea());<BR> }<BR> catch(Exception e){} <BR> } <BR>}</P> <P>
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类的这些成员方法的使用,如
复制内容到剪贴板
代码:
<BR>public class E<BR>{ public static void main(String args[ ])<BR> { char a[]={'a','b','c','D','E','F'};<BR> for(int i=0;i<a.length;i++)<BR> { if(Character.isLowerCase(a[i]))<BR> { a[i]=Character.toUpperCase(a[i]);<BR> }<BR> else if(Character.isUpperCase(a[i]))<BR> { a[i]=Character.toLowerCase(a[i]);<BR> }<BR> }<BR> for(int i=0;i<a.length;i++) <BR>{ System.out.print(" "+a[i]);<BR> } <BR> } <BR>}</P> <P>
总结:此小节主要将了一些特殊的类的用法