我们已经知道,类可以有两种重要成员:成员变量和方法,实际上,Java还允许类可以又一种成员:内部类。
Java支持在一个类中定义另一个类,这样的类称作内部类,而包含内部类的类称为内部类的外嵌类。
内部类和外嵌类之间的重要关系如下:
1、内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。
2、内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。
3、内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象。
下面我们举个例子吧:
RedCowForm 类:
package Example20;
public class RedCowForm {
static String formName;
RedCow cow;// 内部类声明对象
RedCowForm() {
}
RedCowForm(String s){
cow = new RedCow(150,112,5000);
formName = s;
}
public void ShowMessage(){
cow.speak();
}
/**
* 声明内部类
* @author 10497
*
*/
class RedCow{
String cowName = "红牛";
int height,weight,price;
RedCow(int h,int w,int p) {
this.height =h;
this.weight =w;
this.price = p;
}
void speak(){
System.out.println("我是" + cowName + ",身高:" + height
+ "cm,体重:" + weight + "kg,生活在:" + formName);
}
}//内部类结束
}
主函数调用:
package Example20;
public class Application {
public static void main(String[] args) {
RedCowForm form = new RedCowForm("红牛农场");
form.ShowMessage();
form.cow.speak();
}
}
内部类和外嵌类可以相互调用方法。
关于匿名类
和子类有关的匿名类
首先,我们讨论一下,假如没有显示地声明一个类的子类,而又想用子类创建一个对象,那么该如何实现这样的目的呢?Java允许我们直接使用一个类的子类的类体创建一个子类对象,也就算说,创建子类对象时,除了允许使用父类的构造方法之外还有类体,此类体被认为是一个子类去掉类声明对后的类体,称作匿名类。匿名类就是一个子类,由于无名可用,所以不可能用匿名类声明对象,但却可以直接用匿名类创建一个对象。
匿名类有一下特点:
1、匿名类可以继承父类的方法也可以重写父类的方法。
2、使用匿名类时,必然是在某个类中直接使用匿名类创建对象,因此匿名类一定是内部类。
3、匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static成员变量和static方法。
4、由于匿名类是一个子类,但没有类名,所以在用匿名类创建对象时,要直接使用父类的构造方法。
下面我们举个例子吧:
抽象父类:
package Example21;
abstract class OutputAlphabat {
public abstract void output();
}
子类:
package Example21;
public class OutputEnglish extends OutputAlphabat {
//输出英文字母的子类
@Override
public void output() {
for(char c = 'a';c<'z';c++ ){
System.out.printf("%3c",c);
}
}
}
显示类:
package Example21;
public class ShowBoard {
void ShowMess(OutputAlphabat show){
//参数show是OutputAlphabat类型的对象
show.output();
}
}
主函数调用:
package Example21;
public class Application {
public static void main(String[] args) {
ShowBoard board = new ShowBoard();
board.ShowMess(new OutputEnglish());//想参数传递OutputAlphabet的子类
//OutputEnglish的对象
board.ShowMess(new OutputAlphabat() {//向参数传递OutputAlphabet的匿名子类的对象
public void output() {
for(char c = 'α';c<= 'ω';c++){
System.out.printf("%3c",c);
}
}//重写子类
});
}
}
调试结果
a b c d e f g h i j k l m n o p q r s t u v w x y α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ? σ τ υ φ χ ψ ω
关于和接口有关的匿名类:
先举个例子吧:
接口:
package Example22;
interface SpeakHello {
void speak();
}
调用接口参数类:
package Example22;
class HelloMachine {
public void turnOn(SpeakHello hello){
hello.speak();
}
}
主函数调用:
package Example22;
public class Application {
public static void main(String[] args) {
HelloMachine helloMachine = new HelloMachine();
helloMachine.turnOn(new SpeakHello() {
public void speak() {
System.out.println("hello,you are welcome!");
}
});
helloMachine.turnOn(new SpeakHello() {
public void speak() {
System.out.println("你好");
}
});
}
}
调试结果:
hello,you are welcome!
你好
这个例子中,在主函数中分别使用匿名类,重写父接口的方法。
关于异常类:
首先,我们先讨论一下什么是异常类呢?所谓的异常类就是程序运行时可能出现的一些错误,比如师徒打开一个根本不存在的文件,比如把0当成被除数等等等等,让程序有机会对错误做出处理。
具体的用法如下:
1、try-catch语句
Java经常会使用try-catch语句来处理异常,将可能出现的异常操作放在try-catch语句的try部分中,假设这部分有异常,程序还是会运行下去,try部分会立即结束,转向catch部分运行。格式入下:
try {
可能发生异常的语句
} catch (Exception e) {
}
各个catch参数中的异常类都是Exception的某个子类,表明try部分可能发生异常,这些子类之间不能有斧子关系,否则保留一个含有父类参数的catch即可。
下面举个具体的例子:
主函数;
package Try_Catch;
public class Application {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 0,m =0,t=100;
try {
m = Integer.parseInt("8888");
n = Integer.parseInt("ab89");//发生异常,转向catch
t = 7777;//t 没有机会赋值
} catch (Exception e) {
System.out.println("发生异常:" + e.getMessage());
}
System.out.println("n=" + n + ",m="+ m+ ",t=" + t);
try {
System.out.println("故意抛出I/O异常!");
throw new java.io.IOException("我是故意的");//故意抛出异常
} catch (Exception e) {
System.out.println("发生异常:" + e.getMessage() );
}
}
}
调试结果:
发生异常:For input string: "ab89"
n=0,m=8888,t=100
故意抛出I/O异常!
发生异常:我是故意的
throw是抛出异常的关键字,和throws是不一样的。
下面介绍自定义异常类:
在编写程序时可以扩展Exception类定义自己的异常类,然后根据程序的需要来规定哪些方法产生这样的异常。
下面我们举个例子
自定义BankException类继承Exception类重写方法:
package Example23;
public class BankException extends Exception {
/**
*
*/
String message;
public BankException(int m,int n) {
message = "入账资金" + m + "是负数或者支出" + n + "是正数,不符合系统要求.";
}
public String warnMess(){
return message;
}
}
Bank类:
package Example23;
public class Bank {
private int money;
public void income(int in,int out) throws BankException{
if(in<=0||out>=0||in+out<=0){
throw new BankException(in,out);
//方法抛出异常,导致方法结束
}
int netIncome = in + out;
System.out.printf("本次计算出的纯收入是:%d元\n" + netIncome);
money = money + netIncome;
}
public int getMoney(){
return money;
}
}
主函数调用:
package Example23;
public class Application {
public static void main(String[] args) {
Bank bank = new Bank();
try {
bank.income(200, -100);
bank.income(300, -100);
bank.income(400, -100);
System.out.printf("银行目前有%d元\n",bank.getMoney());
bank.income(200, 100);
bank.income(99999, -100);
} catch (BankException e) {
System.out.println("计算收益的过程中出现入下问题:");
System.out.println(e.warnMess());
}
System.out.printf("银行目前有%d元\n",bank.getMoney());
}
}
知识点总结:
1、Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类称为内部类的外嵌类。
2、和某类有关的匿名类就是该类的一个子类,该子类没有明显的用类声明来定义,所以称为匿名类。
3、和某接口有关的匿名类就实现该接口的一个类,该子类没有明显地用类声明来定义,所以称作匿名类。
4、java的异常可以出现在方法调试中,即在方法调用过程中抛出异常对象,导致程序运行出现异常,并且等待处理。java 使用Try-catch语句来处理异常,将可能出现的异常操作放在try部分,当try的某个方法发生一场之后,try部分将立即结束执行,转向相应的catch语句部分。