1、内部类
1.1何时:
事物的内部还有事物,就用内部类(人体和心脏举例)
方法:
(1)内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类名.this
(2)外部类要访问内部类,必须建立内部类对象
格式:
(1)当内部类定义在外部类的成员位置上,且非私有,可以在外部其他类中,可以直接创建内部类对象
Outer.Inner out=new Outer().new Inner();
(2)当内部类在成员位置上时,就可以被成员内部类修饰符所修饰。
private,static等,当内部类被静态修饰后,只能访问外部类中的static成员
当内部类中定义了静态成员,该类必须是静态
当外部类中的静态方法访问内部类时,内部类必须为静态。(静态不建实例已存在)
面试:
在外部其他类,如何访问static内部类的非静态成员?
new Outer.Inner().function();
在外部其他类,如何访问static内部类的静态成员
Outer.Inner.function();
1 package learn; 2 class Outer{ 3 private int x=3; 4 class Inner{//内部类 5 int x=4; 6 void function(){ 7 int x=5; 8 System.out.println("inner"+x); 9 System.out.println("inner"+this.x); 10 System.out.println("inner"+Outer.this.x); 11 } 12 } 13 void method(){ 14 Inner in=new Inner(); 15 in.function(); 16 } 17 } 18 public class InnerClassDemo { 19 public static void main(String[] args) { 20 Outer out=new Outer(); 21 out.method(); 22 //内部类非私有时可如下访问 23 Outer.Inner Inn=new Outer().new Inner(); 24 Inn.function(); 25 } 26 }
1.2.内部类定义在局部时
不可以被成员修饰符修饰(static)
(1)可以直接访问外部类中的成员,因为还持有外部类中的引用
package learn; class Outer{ int x=3; void method(){ class Inner{ void function(){ //内部类调用外部类的成员变量 System.out.println(Outer.this.x); } } //非静态类,没对象不运行 new Inner().function(); } } public class InnerClassDemo3 { public static void main(String[] args) { new Outer().method(); } }
(2)但是不可访问他所在的局部中的变量,只能访问被final修饰的局部变量
1 package learn; 2 3 class Outer3{ 4 int x=3; 5 void method(){ 6 final int y=4; 7 class Inner{ 8 void function(){ 9 //内部类访问它所在的局部中的变量,必须为final 10 System.out.println(y); 11 } 12 } 13 //非静态类,没对象不运行 14 new Inner().function(); 15 } 16 } 17 public class InnerClassDemo3 { 18 public static void main(String[] args) { 19 new Outer3().method(); 20 } 21 }
1.3、匿名内部类
就是内部类的简写
前提:内部类必须继承一个类或者实现一个接口
何时:使用过的方法的参数是匿名内部类,且其中方法不超过3个
如:public static void show(Inner in)可换成如下:
show(new Inter
{
public void method(){
System.out.println("method show run");
}
});
格式:new父类/接口(){定义子类的内容}
其实匿名内部类就是匿名子类对象,可以理解为带内容的对象
匿名对象调用方法只可调用一次,且不可调用自己的方法,最好别超过3个
1 package learn; 2 3 abstract class AbsDemo{ 4 abstract void show(); 5 } 6 7 class Outer4{ 8 int x=3; 9 // class Inner4 extends AbsDemo{ 10 // void show(){ 11 // System.out.println("show"+x); 12 // } 13 // } 14 // public void function(){ 15 // new Inner4().show(); 16 // } 17 // 18 public void function2(){ 19 //AbsDemo d=new AbsDemo()也可以 20 new AbsDemo(){ 21 void show(){ 22 System.out.println("show"+x); 23 } 24 25 }.show(); 26 27 } 28 } 29 30 public class InnerClassDemo4 { 31 public static void main(String[] args) { 32 // new Outer4().function(); 33 new Outer4().function2(); 34 } 35 }
1 package learn; 2 interface Inter{ 3 void method(); 4 } 5 class Test{ 6 static class Inner implements Inter{ 7 public void method(){ 8 System.out.println("1"); 9 } 10 } 11 static Inter function(){ 12 // return new Inner();//内部类 13 //匿名内部类 14 return new Inter(){ 15 public void method(){ 16 System.out.println("1"); 17 } 18 }; 19 } 20 } 21 public class InnerClassDemo5 { 22 public static void main(String[] args) { 23 //倒推 24 Test.function().method(); 25 //Test类中有个静态方法function, 26 //.method:function方法运算后的结果是一个对象,而且是一个Inner类型的对象 27 //因为只有Inner类型的对象,才可以调用method方法 28 } 29 30 }
2、异常
异常也是一类对象,表示现实生活中的具体的事物
问题分为严重和非严重
严重的是Error类
error不编写针对性的代码对其进行处理
非严重的是Exception类描述
编写针对性的代码
好处:
(1)将问题进行封装
(2)将正确流程代码和问题代码相分离,便于阅读
2.1处理过程:
try{
需要被检测的代码
}
catch(异常类 变量){
处理异常的代码
}
finally{
一定会执行的语句
}
对捕获到的异常对象的常见方法操作
1 package learn; 2 class Demo{ 3 int div(int a,int b) 4 { 5 return a/b; 6 } 7 } 8 9 public class ExceptionDemo { 10 public static void main(String[] args) { 11 Demo d=new Demo(); 12 try 13 { 14 int x=d.div(4, 0); //new Exception() 15 System.out.println("x="+x); 16 } 17 catch(Exception e)//Exception e=new Exception() 18 { 19 System.out.println("除零了"); 20 System.out.println(e.getMessage());// /byzero详细消息的字符串 21 System.out.println(e.toString());//异常名称:异常信息 22 e.printStackTrace();//打印堆栈中的跟踪信息,异常名称,异常信息,异常出现的位置 23 //其实jvm默认的异常处理机制就是在调用printStackTrace方法 24 } 25 } 26 }
2.2、异常声明方法,throws Exception
一开始声明,告诉这里可能会出错,便于提高安全性,让调用出进行处理,不处理编译失败。内部解决了(有catch)可以不声明
1 class Demo{ 2 int div(int a,int b)throws Exception//在功能上通过throws关键字声明了该功能可能出现问题 3 { 4 return a/b; 5 } 6 }
2.3、多异常处理
(1)、声明异常时,建议声明更为具体的异常,这样处理的可以更具体
(2)、对方声明几个异常,对应有几个catch块
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面(不然它会解决所有能解决的问题,使问题笼统为一个名字)
(3)、一定要定义具体处理方式,别定义e.printStackTrace();也别书写一条输出语句
2.4、自定义异常
为了显示出异常信息,自定义类继承Exception,因为父类中把异常信息的操作都完成了,所以子类在构造时,将传递给父类通过super语句。
就可以直接通过父类的getMessage方法获取自定义的异常信息了。
继承Exception是因为异常体系的一个特点,异常类和异常对象都被抛出,他们具备可抛性,这个可抛性是Throwable这个体系中独有特点,只有这个体系的类和对象才可被throw和throws操作
1 package learn; 2 class FuShuException extends Exception{ 3 private int value; 4 FuShuException(){ 5 super(); 6 } 7 FuShuException(String msg,int value){ 8 super(msg); 9 this.value=value; 10 } 11 public int getValue(){ 12 return value; 13 } 14 } 15 class Demo3{ 16 int div(int a,int b)throws Exception{//函数上 17 if(b<0) 18 //函数内 19 throw new FuShuException("出现了除数是负数的情况,",b);//手动通过throw关键字抛出一个自定义异常 20 return a/b; 21 } 22 } 23 24 class ExceptionDemo3{ 25 public static void main(String[] args){ 26 Demo3 d=new Demo3(); 27 try 28 { 29 int x=d.div(4, -1); 30 System.out.println("x="+x); 31 } 32 catch(Exception e) 33 { 34 System.out.println(e.toString()); 35 System.out.println("除数变负数"); 36 } 37 System.out.println("over"); 38 } 39 } 40 41 //// 1,2推出3, 42 //class Throwable{ 43 // private String message; //3 44 // Throwable(String message) 45 // { 46 // this.message=message; //2 47 // } 48 // public String getMessage(){ 49 // return message; //1 50 // } 51 //} 52 // 53 //class Exception extends Throwable{ 54 // Exception(String message) 55 // { 56 // super(message); 57 // } 58 //}
2.5、throws和throw
throws使用在函数上,后面跟的异常类。可以跟多个。用逗号隔开 //int div(int a,int b)throws FuShuException{
throw使用在函数内,后面跟的是异常对象
2.6、特殊的异常RuntimeException
函数内抛出异常,函数上不用声明
函数上声明异常,调用者可以不处理
因为希望程序停止,被修改,问题不被隐藏
自定义异常时,如果该异常发生,无法再继续进行运算,就让自定义异常继承RuntimeException
总结:
异常分两种
(1)、编译时被检测的异常,必须声明
(2)、编译时不被检测的异常(运行时异常,RuntimeException以及其子类)
2.7、finally
执行一定要做的动作,一般用于关闭资源
try+catch(可多个catch); try+catch+finally; try+finally
只有当系统执行到System.exit(0);finally才不会执行
2.8、异常在子父类覆盖中的表现:
(1)子类在覆盖父类时,如果父类抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者异常的子类
(2)如果父类方法抛出多个异常,那么在子类覆盖该方法时,只能抛出父类异常的子集。
(3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常
如果子类方法发生了异常,就必须要进行try处理,绝对不能抛
PS:视频123练习四※
3、包
封装的体现
让java和class文件分离存放
javac -d . PackageDemo.java//在当前路径下创建包并把class文件放进去
set classpath=包的父目录,不需进入包
3.1、包与包之间
类,被访问的成员,都要public
不同包中子类,还可以访问父类中被protected权限修饰的成员
包与包之间可以使用的权限:
public> protected> default> private
同一个类中 ok ok ok ok
同一个包中 ok ok ok
子类 ok ok
不同包中 ok
一个java文件中不能出现两个以上的共有类或接口
3.2、导入import
导入的是路径下的文件,不包含目录中文件下的的文件
建议用url定义包名
java pack.PackageDemo//需指定包