Day01:
一、内部类(inner class)
1、定义
在一个类中,定义另一个类的代码结构,通常定义在类内部的类称为 “内部类” ,外面的类称为“外部类” , 在逻辑关系上 内部类与外部类是从属关系,比如 一个People类 存在收货地址类(收货人,收货联系方式)
2、分类
2.1、 普通内部类(inner class),一个类A中定义另一个类B,其中类B就是类A的内部类,也是类A的一部分
public class People {
private String pname="张三";
public void sayHello(){
System.out.println("Let us say Hello");
// 知识点1 :外部类的方法中,可以使用内部类的属性、方法
Address address = new Address();
address.addressName ="湖北武汉";
address.contentName="张某某";
address.showAddressInfo();
}
/**
* 定义普通内部类 收货地址
*/
class Address{
private String addressName;// 收货地址
private String contentName;// 联系人
public void showAddressInfo(){
System.out.println("联系人:"+contentName + "--收货地址:"+addressName);
// 内部类的方法 可以直接访问外部类的属性 (由于通常情况属性的访问必须通过对象才可以使用,而)
System.out.println("访问外部类的属性:"+pname);
}
}
}
注意两点
- 外部类的方法中,可以直接访问内部类的所有成员(包括私有)
- 内部类的方法中,也可以直接方法外部类的所有成员,当外部和内部的成员名相同时,就近原则访问成员,或者引入外部类的对象访问
2.2、 静态内部类(static inner class): 在普通内部类基础上,增加“static”关键字,与静态方法相似,满足静态的要求
public class People{
/**
* 2、定义静态内部类
* 卡信息
*/
static class Card{
private static String cardNo="4200018888000022";
private String cardName="身份证";
// 定义静态方法
public static void showCard(){
System.out.println("身份证号:"+ cardNo);
}
// 定义非静态方法
public void showCard2(){
System.out.println("cardName:"+cardName + "----"+ cardNo);
}
}
// 外部类的方法
public void method2(){
Card card = new Card();
// 对于静态方法可以直接类名.方法名
// 对于非静态方法,需要创建Card类的对象访问
card.showCard2();
}
}
使用:
// 2 创建静态内部类的对象
People.Card.showCard();
// 创建静态内部类的对象
People.Card card = new People.Card();
card.showCard2();
2.3、方法内部类: 在一个方法中定义的类,其中这个类只属于该方法,也只能在该方法中使用
/**
* 3、方法内部类 (将一个类定义在方法里面)
*/
public void method3(){
int score = 98;
// 在这里定义一个类
class MyClass{
String subject="Java";
public void getSubjectScore(){
//方法内部类中 也可以使用方法的属性
System.out.println(pname+"的"+subject+":"+score);
}
}
//调用方法里面的类
MyClass mycls = new MyClass();
mycls.getSubjectScore();
}
People people = new People();
// 3 调用方法
people.method3();
注意:内部类剩的class文件 命名 外部类$内部类名.class
2.4 匿名内部类: 定义一个没有类名,只有对方法的具体实现。通常它依赖于实现关系(接口)或继承关系(父类)
a、基于实现关系
public interface MyInterface {
// 学习
public void study();
// 工作
public void work();
}
// 创建一个匿名类(让接口的引用 指向匿名类的对象)
MyInterface person = new MyInterface() {
@Override
public void study() {
System.out.println("这个人也好好学习");
}
@Override
public void work() {
System.out.println("这个人也好好工作");
}
};
person.study();
person.work();
b、基于继承关系
public class MyClass {
public void service(){
System.out.println("提供服务的方法。");
}
}
// 父类 new 一个 匿名类,这个匿名类是它的子类
MyClass cls = new MyClass(){
@Override //匿名类重写父类的方法 service
public void service() {
System.out.println("这是子类的方法");
}
};
cls.service();
二、异常
1、异常的概述
异常定义: 在程序中,发生“不正常”的事件,导致程序无法正常运行,并使JVM中断,称为异常
生活中的异常: 早上起床上课,平时骑车20分钟可以到达教室,由于天气原因或者闹钟响了自动关闭,不能按时到达教室上课,迟到了,此时就属于异常现象 。
捕获异常: 当程序在运行时,发生了异常 ,为了让程序正常执行,需要对异常捕获(catch),称之为捕获异常
Java是面向对象的语言, 异常本身就是一个类(Exception),当发生异常时会创建异常对象,捕获的就是该对象。
System.out.println("请输入一个数字");
Scanner sc = new Scanner(System.in);
// 对可能发生的异常 进行处理
int num = sc.nextInt();
if(num%2==0){
System.out.println("这个数是偶数");
}
异常代码可能发生异常, 当用户输入非数字时, 导致程序抛出一个异常对象 :
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
2、异常关键字 以及层次关系
a、try: 试一试 ,将可能发生的代码使用try包裹 ,try不能单独出现
b、catch : 捕获异常, 当发生指定的异常对象时,执行catch代码
System.out.println("请输入一个数字");
Scanner sc = new Scanner(System.in);
// 对可能发生的异常 进行处理
try {
int num = sc.nextInt(); // 发生异常后,try里面的代码不再执行
if (num % 2 == 0) {
System.out.println("这个数是偶数");
}
System.out.println("结束");
}catch(Exception ee){
// 对应的异常类 来捕获对应的异常对象 ,不能确定异常类,可以使用父类Exception
System.out.println("你的输入不正确");
}
System.out.println("程序继续运行直到结束。。。。");
一个try + 多个catch
// 抛出的异常 不能被catch捕获,会发生什么?
try {
int[] num = {
1, 2, 3};
System.out.println(num[1]); // 没有捕获该异常对象,JVM依然终止运行
System.out.println(10/0);
}catch(NullPointerException ee){
System.out.println("这是空指针异常");
}catch(ArrayIndexOutOfBoundsException ee){
System.out.println("数组下标越界异常");
}catch(Exception ee){
// 输出异常 堆栈消息 方便程序员排错(尽可能避免用户看见)
ee.printStackTrace();
System.out.println("系统繁忙!"+ee.getMessage());
}
System.out.println("程序结束");
c: finally : 异常之后的最终处理 (无法是否发生异常,程序都执行 )
try… finally 结构
try{
System.out.println("请输入两个数 ,计算两个数相除");
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
double s = num1/num2; // 可能出错
System.out.println(" try里面结束,结果:"+s);
}finally{
System.out.println("无论是否发生异常,都会执行这个语句块,一般用于资源回收");
}
try… catch…finally 结构
try {
System.out.println("请输入两个数 ,计算两个数相除");
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
double s = num1 / num2; // 可能出错
System.out.println(" try里面结束,结果:" + s);
}catch(ArithmeticException ee){
ee.printStackTrace();
System.out.println("除数不能为0 !!");
}catch(Exception ee){
ee.printStackTrace();
System.out.println("系统繁忙!!!");
}finally {
System.out.println("用于资源回收。");
}
3、捕获异常
try…catch…finally
4、抛出异常
/**
* 根据下标访问数组元素
* @param array
* @param index
* @return
*/
public static int getEleByIndex(int [] array , int index){
// 抛出异常: 可以在异常发生时 或发生之前 创建一个异常对象并抛出
// 手动抛出一个异常 throw new 异常类([异常消息]);
if(index <0 || index > array.length-1){
//抛出异常
throw new ArrayIndexOutOfBoundsException("你的下标越界了");
}
int n = array[index];
return n;
}
public static void main(String[] args) {
//数组
int [] array = {
2,1,4,5};
int index=4;
// 定义方法访问下标的元素 此时会产生异常 并抛出给方法的调用者
try {
int num = getEleByIndex(array, index);
System.out.println("访问的元素:" + num);
}catch(ArrayIndexOutOfBoundsException ee){
System.out.println(ee.getMessage());
}
System.out.println("结束。。。");
}
5、异常分类
由于有些异常是不能直接抛出的 ,需要先声明才可以抛出,异常可以分为两大类:
1、 编译期异常(check 异常或者检查异常):在编译期间检查异常,如果没有处理异常,则编译出错。
//创建一个文件类的对象
File file = new File("d:/aaa.txt");
// 在写代码(编译之前)时 一定要处理的异常(try..catch 或者 throws),就是编译时异常
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
这里的IOException 就是 编译期异常,需要手动处理的
2、运行期异常(runtime 异常或者运行异常):在运行期间检查异常, 编译期可以不处理异常。
// 在运行期间抛出异常 不需要事先处理的 NullPointException是运行异常
String str=null;
System.out.println(str.length());
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fRktwjhF-1