一:内部类
类可以有两种重要的成员,成员变量和方法,实际上java还有另一种类:内部类;
1.内部类和外嵌类之间的关系
——1内部类的外嵌类的成员变量在内部类中仍然有效,
内部类的方法也可以调用外嵌类的方法
——2内部类中的类体不可以声明类变量和类方法,
外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员
——3内部类仅供他的外嵌类使用,其他类不可以用某个类的内部类声明对象
*内部类的外嵌类的成员变量在内部类中有效,使得内部类和外嵌类的交互更加方便
例子:
某类型的农场饲养了一种特殊种类的牛
但是不希望其他农场饲养这种特殊种类的牛
那么这种类型的农场就可以将创建这种特殊的牛作为自己的内部类。
class RedCowForm {
static String formName;
RedCow cow; //内部类声明对象
RedCowForm() {
}
RedCowForm(String s) {
cow = new RedCow(150,112,5000);
formName = s;
}
public void showCowMess() {
cow.speak();
}
class RedCow { //内部类的声明
String cowName = "红牛";
int height,weight,price;
RedCow(int h,int w,int p){
height = h;
weight = w;
price = p;
}
void speak() {
System.out.println("偶是"+cowName+",身高:"+height+"cm 体重:"+
weight+"kg,生活在"+formName);
}
} //内部类结束
}
public class Example6_1 {
public static void main(String args[]) {
RedCowForm form = new RedCowForm("红牛农场");
form.showCowMess();
form.cow.speak();
}
}
二:匿名类
1. 和子类有关的匿名类(匿名子类)
——1.假如没有显示地定义一个类的子类,而又想用子类创建一个对象,可以用匿名类去实现
——2.java允许我们直接使用一个类的子类的类体创建一个子类对象;
也就是说创建子类对象时,除了使用父类的构造方法还有类体
此类体可以被认为是一个子类去掉类体之后的子类;
——3假如是类,那么下面代码就是用Bank的一个子类(匿名类)创建对象;
new Bank(){
匿名类的类体
}
例子:
abstract class Speak {
public abstract void speakHello();
}
class Student {
void f(Speak sp) {
sp.speakHello();
}
}
public class Example6_2 {
public static void main(String args[]) {
Speak speak=new Speak() {
public void speakHello() {
System.out.println("大家好,祝工作顺利!");
}
};
speak.speakHello();
Student st=new Student();
st.f(new Speak() {
public void speakHello() {
System.out.println("I am a student,how are you");
}
});
}
}
2.与接口有关的匿名类
假设Computable是一个接口,那么java允许直接用接口名和一个类体创建一个匿名对象。
此类体被认为是实现了Computable接口的类去掉声明后的类体,称作匿名类
例如:
new Computer(){
实现接口的匿名类的类体
};
三:Lambda表达式
1.Lambda表达式主要目的是在使用单接口(只含有一个方法的接口)匿名类的时,让代码更加简洁。
2.Lambda就是一个匿名方法
通常的方法是
int f(int a,int b){
return a+b;
}
Lambda表达式
(int a,int b)→{
return a+b;
}
*由于Lambda过于简化,因此必须在特殊的上下文
编译器才能推断出到底是那个方法
因此java中的Lambda主要用于单接口(只含有一个方法的)
interface Cubic {
double getCubic(double x);
}
class A {
void f(Cubic cubic) {
double result=cubic.getCubic(3);
System.out.println("result="+result);
}
}
public class Example6_4 {
public static void main(String args[]) {
Cubic cu=new Cubic() { //和接口有关的匿名类
public double getCubic(double x) {
return x*x*x;
}
};
System.out.println(cu.getCubic(5));
cu= (double x)->{ //使用Lambada表达式简化代码
return x*x*x;
};
System.out.println(cu.getCubic(2));
A a=new A();
a.f((double x)-> { //使用Lambada表达式简化代码
return x*x*x;
});
}
}
四:异常类
*所谓异常类就是程序运行时可能出现一些错误,比如试图打开一个根本不存在的文件
*异常处理将会改变程序的控制流程,让程序有机会对错误进行处理
*即把可能存在bug的语句放到语句中,使程序能正常运行。
1.try catch语句
try{
可能包含异常的语句
即可能throw关键字抛出了异常对象(抛出Exception子类对象)
}
catch(ExceptionSubClass e){
。。。。。。。
}
catch(ExceptionSubClass2 e){
。。。。。
}
例子:
public class Example6_5 {
public static void main(String args[ ]) {
int n=0,m=0,t=6666;
try{ m=Integer.parseInt("8888");
n=Integer.parseInt("ab85"); //发生异常,转向catch
t=9999; //t没有机会赋值
}
catch(NumberFormatException e) {
System.out.println("发生异常:"+e.getMessage());
n=123;
}
System.out.println("n="+n+",m="+m+",t="+t);
}
}
例子:
public class Example6_6 {
public static void main(String args[]) {
People wang=new People(),
zhang=new People();
try{ wang.setAge(180);
System.out.println(wang.getAge());
}
catch(IntegerException e) {
System.out.println(e.toString());
}
try { zhang.setAge(37);
System.out.println(zhang.getAge());
}
catch(IntegerException e) {
System.out.println(e.toString());
}
}
}
class IntegerException extends Exception {
String message;
public IntegerException(int m) {
message="年龄"+m+"不合理";
}
public String toString() {
return message;
}
} class People {
private int age=1;
public void setAge(int age) throws IntegerException {
if(age>=160||age<=0) {
throw new IntegerException(age); //方法抛出异常,导致方法结束
}
else {
this.age=age;
}
}
public int getAge() {
System.out.println("年龄"+age+"合理");
return age;
}
}
代码解读:
用People类建立set,get方法,并在set方法中就规定如果age不在一定范围内,就会显示方法异常,就会被抛出,进入主类中的catch中,从而无法调用getage的方法,进入catch中去去调用IntegerException的toSpring方法。
2.finally子语句是try catch语句的可选部分
格式如下:
try{
。。。
}
catch{
。。。
}
finally{
。。。
}
其执行机制是,在执行try catch语句后,执行finally子语句,也就是说无论try部分是否发生过异常,finally子语句都会被执行。
例如:
class CargoBoat {
int realContent; //装载的重量
int maxContent; //最大装载量
public void setMaxContent(int c) {
maxContent = c;
}
public void loading(int m) throws DangerException {
realContent += m;
if(realContent>maxContent) {
throw new DangerException();
}
System.out.println("目前装载了"+realContent+"吨货物");
}
}class DangerException extends Exception {
final String message = "超重";
public String warnMess() {
return message;
}
} public class Example6_7 {
public static void main(String args[]) {
CargoBoat ship = new CargoBoat();
ship.setMaxContent(1000);
int m = 600;
try{
ship.loading(m);
m = 400;
ship.loading(m);
m = 367;
ship.loading(m);
m = 555;
ship.loading(m);
}
catch(DangerException e) {
System.out.println(e.warnMess());
System.out.println("无法再装载重量是"+m+"吨的集装箱");
}
finally {
System.out.printf("货船将正点启航");
}
}
}
输出如下:
目前装载了600吨货物
目前装载了1000吨货物
超重
无法再装载重量是367吨的集装箱
货船将正点启航
进程已结束,退出代码0
附:throw和throws区别
throw和throws作为Java中两种异常抛出关键字,虽然两个长的很像,但是却有着很大的区别。
throws:
跟在方法声明后面,后面跟的是异常类名
throw:
用在方法体内,后面跟的是异常类对象名
public static void method() throws ArithmeticException {// 跟在方法声明后面,后面跟的是异常类名
int a=10;
int b=0;
if(b==0) {
throw new ArithmeticException();用在方法体内,后面跟的是异常类对象名
}else {
System.out.println(a/b);
}
}
}
throws:
可以跟多个异常类名,用逗号隔开
throw:
只能抛出一个异常对象名
public static void method() throws ArithmeticException,Exception {//跟多个异常类名,用逗号隔开
int a=10;
int b=0;
if(b==0) {
throw new ArithmeticException();// 只能抛出一个异常对象名
}else {
System.out.println(a/b);
}
}
}
throws:
表示抛出异常,由该方法的调用者来处理
throw:
表示抛出异常,由该方法体内的语句来处理
public class throwandthrows {
public static void main(String[] args) {
try {
method();//由该方法的调用者来处理
}catch (ArithmeticException e) {
e.printStackTrace();
}
}
public static void method() throws ArithmeticException {
int a=10;
int b=0;
if(b==0) {
throw new ArithmeticException();//由该方法体内的语句来处理
}else {
System.out.println(a/b);
}
}
}
throws:
throws表示有出现异常的可能性,并不一定出现这些异常
throw:
throw则是抛出了异常,执行throw一定出现了某种异常
我们向上面例子代码里throws一个IndexOutOfBoundsException异常,编译发现并没有报错,这就体现了throws表示有出现异常的可能性
public class throwandthrows {
public static void main(String[] args) {
try {
method();
}catch (ArithmeticException e) {
e.printStackTrace();
}
}
public static void method() throws ArithmeticException,IndexOutOfBoundsException {
int a=10;
int b=0;
if(b==0) {
throw new ArithmeticException();
}else {
System.out.println(a/b);
}
}
}