黑马程序员--- 学习笔记(第九天)

 —————————— ASP.Net+Android+IOS开发.Net培训、期待与您交流!——————————
内部类:
将一个类定义在一个类里面,对里面的那个类称为
内部类(内置类 ,嵌套类);
内部类访问规则:
1.内部类可以直接访问外部类中的成员,包括私有
2.外部类要访问内部类,必须先建立内部类对象


之所以直接访问内部类中的成员,是因为内部类中持有一个
外部类的引用,格式:外部类.this


访问格式:
1.当内部类定义在外部类的成员位置时,而且非私有,可以在外部
其它类中,可以直接建立内部类对象
格式:
外部类名.内部类名 变量名=new 外部类名().new 内部类名();


2.当内部类定义在外部类成员位置上就可以被成员修饰所修饰,
比如
private: 将内部类进行封装
static: 内部类就具备static的特性


在内部类中被static修饰后,只能访问外部类的static成员,
出现访问权限
  
在外部其它类中,如何直接访问static内部类的非静态成员?
new 外部类名.内部类名().非静态成员;


在外部其它类中,如何直接访问static内部类中的静态成员呢?
new 外部类名.内部类名.静态成员;


注意:
1.当在内部类中定义了静态成员,该内部类必须是static的
2.在外部类中的静态方法访问内部类时,内部类也必须是static的


/*
成员内部类	测试
*/
class Demo1 
{
	public static void main(String[] args) 
	{
		  // new Outer1().show();调用非静态内部类
		  //new Outer1().show1();调用静态内部类

		  //非静态内部类  外部其它类 调用格式
		 // Outer1.Inner1 i=new Outer1().new Inner1();
			//  i.method();
			  //静态内部类  外部其它类 调用格式
		  //Outer1.Inner1 i=new Outer1.Inner1();
			// i.method();
			
	}
}
class Outer1
{
	private  int n=5;//inner 有外部类的引用 Outer1.this.n
	
	/*成员内部类可以使用成员修饰符*/
	/*内部类被static修饰时,外部类访问必须为静态方法,
		内部类中可以没有静态方法
	*/
	static class Inner1
	{
		
		int n=50;//有个隐式的this

		/*当内部类中有静态方法时,内部类必须为static修饰*/
		
		//为static所修饰,只能访问外部类static成员
	
		//public static void method(){
		public static void method (){
			int n=10;	 //就近原则
			System.out.println("method_inner"+n); //10
			//System.out.println("method_inner"+this.n);//50
			//System.out.println("method_inner"+Outer1.this.n);//5
		}
	}
	
	
	/*同过方法new 内部类进行调用*/
	public void show(){
		new Inner1().method();
	}


	/*静态成员函数只能调用静态内部类*/ 
	public static void show1(){
		Inner1.method();
	 }	 
}		 



什么时候使用内部类?
当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为
内部类事物在使用外部事物的内容.

/*
当事物的描述内部还有事物,该事物用内部类描述,
因为内部类事物在使用外部类的内容
*/
class Demo2 
{
	public static void main(String[] args) 
	{
		new Body().show();
	}
}
/*人体和心脏*/
class Body
{
	/*对器官进行封装,不是任何人都能访问的*/
	private class XinZang
	{
		private String left="左心房";
		private String right="右心房";
		public String getLeft(){
			return left;
		}
		public String getRight(){
			return right;
		}
	}
	/*
	对外提供方法 显示心脏
	*/
	public void show(){
		//继续判断 自己是否生病等  增加代码的健壮性

		String message=new XinZang().getLeft();
		System.out.println(message);
	}

}




当内部类定义在局部时:
1.不可以被成员修饰符修饰
2.可以直接访问内部类的成员,因为持有外部类的引用,
但是不能访问他所在的局部中的变量,只能访问被final修饰
的局部变量


匿名内部类:
1.匿名内部类其实就是内部类的简写格式
2.定义匿名内部类的前提:
内部类必须继承一个类或者实现接口


3.匿名内部类的格式:
   new 父类或接口(){定义子类的内容}


4.其实匿名内部类就是一个匿名子类对象.而且这个有点胖,
也可以理解为带内容的对象


5.匿名内部类中定义的方法最好不要超过3个,不包括三个.

/*
局部内部类   匿名内部类
*/
class Demo3
{
	public static void main(String []args){
		/*
		Outer2 o=new Outer2();
		o.show(15);	 //每次方法结束,将释放
		o.show(150);
		*/

		new Outer3().show();
	}
	
}

class Outer2
{	 
	/*
	//局部内部   ------------------
	// int n=15;
	public void show(final int n){ //内部类访问必须局部变量声明为final
		//final int n=11;//内部类访问局部变量必须声明为final
		
		//局部内部类不能使用成员修饰符
		 class Inner2
		{
			//int n=13;
			public void show(){
				//System.out.println(Outer2.this.n);
				//System.out.println(this.n);
				System.out.println(n);
			}
		}

		//只能在下面调用 内部类
		new Inner2().show();
	} 
	*/
}
abstract class Test
{
	public abstract void eat();
}
class Outer3
{	 
	/*匿名内部类
	前提:必须继承或者实现
	*/
	class Inner3 extends Test
	{
		public void eat(){
			System.out.println("还没吃早餐恩 -----非匿名");
		}
	}
	public void show(){
		//new Inner3().eat();	//调用
		//以上步骤  简化之后
		new Test(){
			public void eat(){
			 System.out.println("还没吃早餐---------匿名");
			}
		}.eat();
	}
}



/*
练习  匿名内部类

切记, 一个匿名类实现的方法最好不要超过3个,不包含三个


补全一下代码 匿名内部类实现
*/
class Demo4 
{
	public static void main(String[] args) 
	{
		Test1.function().method();
		//分析 function返回的对象 而且是静态的

		//可以使用Object new匿名内部类
		//忘了说,匿名内部可以赋值给引用
		Object b=new Object(){
			public void s(){
				System.out.println("object");
			}
		};

		//b.s(); //错误,object类中没有该方法,所以匿名内部类有局限
		System.out.print(b.hashCode());
		//编译看左边  运行看右边
	}
}
interface Inner
{
	public abstract void method();
}
class Test1
{
	 static Inner function(){
		 return new Inner(){
		 	public void method(){
				System.out.println("method");
			}
		 };
	 }
}




异常
   就是程序在运行时出现的不正常情况.


  1.异常的由来:
问题也是生活中一个具体的事物,也可以通过java的类形式进行
描述,并封装成对象,其实java有对不正常情况运行描述后的对象体现.


对于问题的划分两种:
1.严重的问题
2.非严重的问题


对于严重的java通过Error类进行描述
对于非严重的java通过Exception类进行描述


对于Error一般不编写针对性的代码对其进行处理
对于Exception可以使用针对性的出来方式进行处理


无论Error还是Exception都是一些类中的共性内容,
比如:不正常信息, 引发原因等


Throwable 有两个子类: Error 或者Exception


2.异常处理
java提供了特有语句进行处理
try{
       要检测的代码;
}catch(异常类 变量名){
       处理语句;
}finally{
一定执行的语句;
}
  
3.对捕获到异常对象对象进行常用方法操作:
getMessage() //获取异常信息
toString()   //异常名称+异常信息
printStackTrace() //异常名称+异常信息+异常出现位置


其实java默认异常处理机制,就是在调用printStrackTrace打印异常
在堆栈中的跟踪信息.


4.在功能上通过throws的关键字声明该功能可能会出现问题,
不处理编译就失败


对多异常处理:
1.声明异常时,建议声明更为具体的异常,这样处理的可以更具体
2.声明几个就对应有几个catch块,如果多个catch块中的异常
出现继承关系,父类的catch块放在最下面


建议在catch处理时,catch一定要有定义的具体处理方法
不要简单的定义一句printStackTrace 也不要简单的输出语句



自定义异常


因为项目中会出现特有的问题,而这些问题并未被java所描述并封装
对象,所以对于这些特有的问题,可以按照java的对问题封装思想
将特有的问题进行自定义的异常封装




当在函数内出现throw,那么就必须做出对应的处理动作,
要么在内部try catch 要么在函数上throws让调用者处理


一般情况下,函数内出现异常,函数上需要声明


如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了,所以子类只要构造
时,把异常信息传递给父类通过super语句,那么就可以直接通过
把getMessage方法获取自定义异常信息


自定义异常:
必须继承throwable后者其子类


为什么要继承Exception?
异常体系有一个特点,因为异常类和异常对象都需要抛出
他们都具备可抛性,这个可抛性是throwable这个体系的
独有特点,只有这个体系的类和对象才能被throws和throw操作


throws 和throw的区别:
throws 使用在函数上
throw  使用在函数内
throws 后面跟的是异常类,多个用逗号隔开
throw  后面跟的是异常对象


RuntimeException(Exception特殊的子类 运行时异常)
如果在函数内抛出该异常,调用者可以不用声明,编译一样通过
如果在函数上声明的异常,调用者可以不进行处理,编译一样通过
之所以在函数上声明,是因为不需要让调用者处理,当该异常发生
希望程序停止.是因为在运行时,出现了无法继续运算的情况,希望
可以停止后,让程序员进行修正..


自定义异常时:
如果异常的发生,无法继续进行运算,就让自定义异常继承RuntimeException

/*
异常 测试类
*/
class Demo5 
{
	/*
	jvm的默认处理异常方式是
	printStackTrace()
	
	public static void main(String[] args)throws ArithmeticException,FuShuException
	{
		Div d=new Div();
		/*
		//第一种处理方法
		try
		{
			int n=d.div(4,-10);
			System.out.println("运算结果是:"+n);
		}
		catch (ArithmeticException e)
		{	
			//常用的三种处理方式,但是不推荐使用
			//要代码进行处理,不是简单的输出打印
			//1.打印异常信息
			//System.out.println(e.getMessage());
			//2.打印异常名称+信息
			//System.out.println(e.toString());
			//3.打印异常名称+信息+堆栈追踪信息
			//e.printStackTrace();

			System.out.println("除零了,引发异常");
		}catch(FuShuException e){
			System.out.println(e.getMessage());
		}
		catch(Exception e){
			System.out.println("多个异常,有继承关系..父类放在下面");
		}
		*/
		 /*
	//	 第二种 在函数上声明 抛出去给调用者处理
		 
		 int n=d.div(4,-15);  //必须捕获或者声明抛出去
		 System.out.println("运算结果是:"+n);

	}
	*/
	  public static void main(String []args){
		   	Div d=new Div();
			int n=d.div(4,-50);
			System.out.println(n);
	  }
}
/*继承Exception */
class FuShuException extends Exception
{
	public FuShuException(){
	
	}
	public FuShuException (String message){
		super(message);
	}
}
/*继承RuntimeException*/
class 	FS_RuntimeException extends RuntimeException
{
	public FS_RuntimeException(){
	
	}
	public FS_RuntimeException(String mes){
	 super(mes);
	}
}
class Div
{
	/*
	在函数内throw 函数上必须throws 
	public int div(int a,int b)throws FuShuException//函数上声明,让调用者处理
	{
		if(b<0)
			//这里抛出  函数上必须声明
			throw new FuShuException("被除数为复数异常");
		return  a/b;
	}
	*/
	/*一个特殊的例子  函数内throw 调用者不用处理
	编译会通过,但出现异常程序会停止运行,让程序员改正
	*/
	public int div(int a,int b)
	{
		if(b<0)
			throw new FS_RuntimeException("被除数为复数异常");
		return  a/b;
	}
}




对于异常分两种:
1.编译时期被检测的异常

2.运行时异常(RuntimeException和其子类)



/*
异常练习

员工在流水线工作

假设可能引发两个异常:
1.烧保险丝了,工作得先暂停会
2.全公司停电,这个要通知专门部门,发电机发电
*/

 //纯属个人理解的练习 , 有错莫怪

/*烧保险丝异常*/
class BurningFuseException extends Exception
{
	public BurningFuseException(String message){
		super(message);
	}
}
/*停电异常*/
class  BlackoutException extends Exception
{
	public BlackoutException(String message){
		super(message);
	}
}
/*停电无法处理,反馈给上级*/
class TiDianException extends Exception
{
	public TiDianException(){
	
	}
   public TiDianException(String ms){
		super(ms);
	}
}
/*员工类*/
class Employee
{
	private String name;
	private int age;
	//省略了setter  getter
	private int status=3;//状态
	public void setStatus(int status){
		this.status=status;
	}
	public Employee(){
	
	}
	public Employee(String name, int age){
		this.name=name;
		this.age=age;
	}
	/*员工工作方法*/
	public void work()throws BurningFuseException,BlackoutException{
		 if(status==1)
		   System.out.println("工作");
		 else if(status==2)
			throw new BurningFuseException("保险丝烧了");
		 else if(status==3)
			 throw new BlackoutException("停电了");	
	}

}
 /*Demo6 为流水线*/
class Demo6 
{
	public static void main(String[] args)throws BlackoutException,BurningFuseException,TiDianException 
	{
		Employee em=new Employee("张三",15);
		try
		{
			em.work();
		}
		catch (BurningFuseException e)
		{
			//System.out.println(e.getMessage());
			//假设烧保险丝了,流水线可以处理 换保险丝]
			em.setStatus(1);
			em.work();	//还是继续工作
		}catch(BlackoutException e){
			System.out.println(e.getMessage());
			//假设停电了 流水线就要请示上级 用发电机发电继续进行生产

			throw new TiDianException("流水线无法处理,请用发电机发电,");
		}catch(Exception e){
			System.out.println(e.getMessage());
		}


	}
}


 —————————— ASP.Net+Android+IOS开发.Net培训、期待与您交流!——————————

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值