黑马程序员——内部类, 异常

------- android培训java培训、期待与您交流! ----------

 

内部类, 异常

 

内部类

1.      内部类是在一个类的内部再声明一个类,这个类能访问所在外部类的成员变量, 声明内部类的方法有两种,一种是在成员位置上, 另一种是在方法内

2.      声明在成员位置

1)      static内部类

语法格式代码示例

package com.itcast.review;

public class ExtTest {
	public static void main(String[] args) {
		A.B ab = new A().new B(); // 直接创建内部类对象的
		ab.show();

		A a = new A();
		a.printInner(); // 通过外部类对象的方法调用内部类
	}
}

class A {
	int c = 5;

	// 声明一个非静态的内部类
	class B {
		int c = 10;

		void show() {
			int c = 20;
			System.out.println(c); // 内部类方法访问方法内部的变量
			System.out.println(this.c); // 内部类访问内部类的成员变量
			System.out.println(A.this.c); // 内部类访问所在外部类的成员变量
		}
	}

	// 访问内部类对象
	void printInner() {
		B b = new B(); // 创建内部类对象
		b.show();
	}

}


 

注意:在其它类中穿件内部类对象格式是 OuterClass.InnerClass in = new OuterClass().new InnerClass();当外部类的成员属性和内部类的成员属性重名时, 访问外部类的格式是 Outer.this.属性;

 

1)      static内部类

语法格式代码示例

package com.itcast.review;

public class ExtTest {
	public static void main(String[] args) {
		A.B ab = new A.B(); // 直接创建内部类对象的
		ab.show();

		A a = new A();
		a.printInner(); // 通过外部类对象的方法调用内部类
	}
}

class A {
	static int c = 5;

	// 声明一个非静态的内部类
	static class B {
		static int c = 10;

		void show() {
			int c = 20;
			System.out.println(c); // 内部类方法访问方法内部的变量
			System.out.println(this.c); // 内部类访问内部类的成员变量
			System.out.println(A.c); // 内部类访问所在外部类的成员变量
		}
	}

	// 访问内部类对象
	void printInner() {
		B b = new B(); // 创建内部类对象
		b.show();
	}
}


 

注意: 关于内部类声明在成员位置上时它的static修饰的问题

1)      如果内部类使用static修饰,在内部类中就不能直接访问外部类的非static成员

2)      如果内部类中有static成员,内部类必须使用static修饰

3)      如果内部类使用static修饰,那内部类的成员可以是static,也可以不是.

 

 

1.      声明在方法内

声明在方法内的内部类可以访问所在外部类的成员属性,访问所在方法内的变量必须是final修饰的,因为方法内的变量在使用完就消失了, final修饰的是常量,声明周期跟类一样

方法内的内部类对象只在方法内声明有效

语法格式代码示例

package com.itcast.review;

public class InnerClassTest {
	public static void main(String[] args) {
		// 创建一个Outer对象
		Outer o = new Outer();
		// 调用Outer对象的show方法
		o.show();
	}
}

// 定义一个外部类
class Outer {
	int d = 20;

	// 创建一个包含内部类的方法
	void show() {
		final int a = 10; // 内部类只能访问方法内用final修饰的局部变量
		class Inner {
			int b = d; // 内部类的成员属性

			void getSum() { // 内部类中的方法
				int sum = a + b;
				System.out.println(sum);
			}
		}
		Inner in = new Inner();
		in.getSum();
	}
}


 

匿名内部类

1.      内部类的一种简化写法

2.      格式

new 类名|接口名([参数]){

           //属性-------->很少使用

           //方法-------->可以是自定义方法但是绝大多数情况下都是重写的方法。

};

 

new 代表创建一个匿名内部类对象

类名|接口名 代表的是匿名内部类继承的父类或实现的接口

{} 它代表的是匿名内部类的内容.

 

3.      笔试题

           Objectobj=new Object(){

                   

                    publicvoid show(){

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

                    }

           };

           obj.show();//父类引用指向子类对象不能调用子类特有的方法

 

 

           newObject(){

                   

                    publicvoid show(){

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

                    }

           }.show();//子类对象调用自己的方法

 

匿名内部类一般都是将其做为一个参数进行传递

 

异常

 

1.      异常就是程序中存在的问题,这种问题我们可以解决

下面这段代码访问了数组中不存在的位置,编译时没有出现问题, 运行时会产生一个ArrayIndexOutOfBoundsException异常

public class Test {

         public static voidmain(String[] args) {

                   int[] arr ={1, 4, 5, 6, 7, 8};                

                   int a =arr[arr.length];

                   System.out.println(a);

         }       

}

运行结果

Exception in thread "main"java.lang.ArrayIndexOutOfBoundsException: 6

         atcom.itcast.review.Test.main(Test.java:7)

 

1.      程序中遇到的问题分为两种

Exception(异常):我们必须处理的异常

Error(错误):我们不处理

这两个类都是Throwable的子类

2.      Exception下面有一个RuntimeException

RuntimeException以及其所有子类都是运行异常,除了RuntimeException及其子类外的所有类都是编译异常

3.      对于异常的处理方式

1)      捕获  try-catch-finally 2.

语法格式

try {

   可能抛出异常的语句

}

catch (Exception e) {

   处理异常语句或者抛出一个新异常

}

2)      抛出 throws

当方法中出现异常可以在方法名后面用这个关键字将异常抛出

语法

public void method() throws Exception {

   可能抛出异常的代码

}

无论是什么异常都可以使用上述两种行为人对其进行操作

但是对于编译异常, 在代码上就强制要求必须对其进行处理, 而对于运行异常,我们在代码上没有强制要求,可以不用处理

4.      throwsthrow关键字

1)      这两个关键字都是用来抛出异常

2)      throwthrows区别

throws 它是用来标识一个方法是否抛出异常

throw 它的作用是抛出一个异常对象

a)      throws写在方法的后面

throw 写在方法中

b)      throws后面写的异常类的名称

throw 后面写的是一个异常对象  new XxxExcetpion();

c)      throws后面可以加多个异常名称

throw后面只能有一个异常对象.

5.      自定义异常:只要定义一个类继承Excption就可以

6.      在进行重写时异常的注意事项

1)      对于重写的方法来说,父类中的方法如果抛出了异常, 那么子类可以不抛出,如果要抛出只能与父类一样的异常或父类异常的子集

2)      如果父类中方法没有抛出异常,子类重写方法中产生了异常, 好么只能在重写的方法内捕获,而不能抛出

7.      Finally关键字

无论try块中是否产生异常, finally中的内容永远会被执行到, finally块中在实际开发中一般完成关闭动

例如: 在进行IO读写操作的时候,需要打开设备的读入和写出的通道, 如果不关闭会消耗很多资源,所以将关闭IO的操作放到finally语句块中,无论读写时是否出现异常, 关闭IO的语句都会执行

8.      一个try{}可以对应多个catch () {}, 对于try块产生的可能是不同的异常, catch每次只能处理一个异常,这个时候就可以多定义几个catch语句用于处理try内产生的不同的异常

 

异常代码示例

一个课上的小练习, 老师的电脑出现了蓝屏, 冒烟的异常


 

/*
	分析: 1. 实体: 老师, 电脑
		  2. 电脑不正常的情况: 蓝屏, 冒烟
		  3. 蓝屏异常, 重启可解决, 冒烟, 彻底报废, 不可解决
		  4. 蓝屏异常重启解决, 冒烟需要换老师上课
 */

class TeachTest {
	public static void main(String[] args) {
		// 创建电脑的对象
		Computer computer = new Computer();
		// 创建老师的对象
		Teacher teacher = new Teacher();

		// 老师操作电脑, 捕获异常
		try {
			teacher.operate(computer);
		} catch (ChangeException e) {
			System.out.println(e.getMessage() + " 换个老师来上课");
		}
	}
}

// 定义一个老师的实体类
class Teacher {
	// 老师的属性
	String name = "张三";

	// 老师操作电脑的方法
	void operate(Computer p) throws ChangeException {
		System.out.println(name + "老师将要用电脑上课");
		try {
			p.run();
		}
		// 捕获蓝屏异常
		catch (BuleScreenException e) {
			System.out.println(e.getMessage() + name + " 老师可以解决");
			// 重新启动
			p.restart();
			operate(p);
		}
		// 捕获冒烟异常
		catch (MaoYanException e) {
			System.out.println(e.getMessage() + name + "老师无法解决这个问题");
			throw new ChangeException(e.getMessage() + name + "老师无法上课了");
		}
	}
}

// 定义一个电脑的实体
class Computer {
	// 电脑的状态
	int state = 1;

	// 电脑启动方法
	void run() throws BuleScreenException, MaoYanException {
		System.out.println("老师启动电脑");
		// 状态是0, 正常启动
		if (state == 0) {
			System.out.println("电脑正常启动");
		}
		// 状态是1, 抛出蓝屏异常
		if (state == 1) {
			throw new BuleScreenException("电脑蓝屏了");
		}
		// 状态是2, 抛出冒烟异常
		if (state == 2) {
			throw new MaoYanException("电脑冒烟了");
		}

	}

	// 重新启动方法
	void restart() {
		System.out.println("电脑被重启");
		// 状态重置为0
		state = 0;
	}
}

// 定义一个蓝屏的异常
class BuleScreenException extends Exception {
	// 重写构造方法
	public BuleScreenException(String message) {
		super(message);
	}
}

// 定义一个冒烟的异常
class MaoYanException extends Exception {
	// 重写构造方法
	public MaoYanException(String message) {
		super(message);
	}
}

// 定义一个老师无法上课的异常
class ChangeException extends Exception {
	public ChangeException(String message) {
		super(message);
	}
}


 

1.      Java中的包为类提供了多层命名空间,是用来管理类的

2.      语法格式

package com.xxx.xxx;

一般是把公司的域名反转, 包名都是小写的, 必须写在第一行,并且只能写一句

3.      在访问其它包的类时,应该先将那个类的包导入, 语法是import包名.类名,或者使用时类的前面加上包名, 语法是包名.类名

 

访问权限(重点)

1.      Java中的4中访问权限

                            同一类内         同一包内        包外子类         不同包中

private               ok

默认                   ok                        ok

protected          ok                        ok                        ok

public                 ok                        ok                        ok                        ok

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值