01面向对象(内部类访问规则)
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)
/*
内部类的访问规则:
1,内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this System.out.println("innner :"+Outer.this.x);
2,外部类要访问内部类,必须建立内部类对象。
*/
- class Outer
- {
- private int x = 3; //外部成员
- private class Inner//内部类 可以被私有修饰,当内部类在外部类的成员位置上时机可以
- {
- //int x = 4; // 内部成员
- void function()
- {
- //int x = 6; //内部局部成员
- System.out.println("innner :"+Outer.this.x); //x是3
- //System.out.println("innner :"+x); // x是6 内部有的不出去找
- //System.out.println("innner :"+this.x); // x是4
- }
- }
- /**/
- void method()
- {
- Inner in = new Inner(); //外部访问内部
- in.function();
- }
- }
- class InnerClassDemo
- {
- public static void main(String[] args)
- {
- Outer out = new Outer();
- out.method();
- //直接访问内部类中的成员。
- // Outer.Inner in = new Outer().new Inner();
- // in.function();
- }
- }
02面向对象(静态内部类)
访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式
外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();
2,当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
如果类中数据几乎都静态,他也静态,不涉及特有数据,全是共享数据
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function(); new一个内部类对象调用function方法
在外部其他类中,如何直接访问static内部类的静态成员呢?
outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的。
当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事务在使用外部事物的内容。
*/
- class Outer
- {
- private static int x = 3;
- static class Inner//静态内部类
- {
- static void function()
- {
- System.out.println("innner :"+x);
- }
- }
- static class Inner2
- {
- void show()
- {
- System.out.println("inner2 show");
- }
- }
- public static void method()
- {
- //Inner.function();
- new Inner2().show();
- }
- }
- class InnerClassDemo2
- {
- public static void main(String[] args)
- {
- Outer.method();
- //Outer.Inner.function();
- //new Outer.Inner().function();
- //直接访问内部类中的成员。
- // Outer.Inner in = new Outer().new Inner();
- // in.function();
- }
- }
03面向对象(内部类定义原则)
当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事务在使用外部事物的内容。
class Body 一般用于程序设计上
{
private class XinZang
{
}
public void show()
{
new XinZang().
}
}
当这类事物直接访问外部事物中的内容时,就把这个事物定义在里边,这样定义,代码的设计是最优的。
04面向对象(匿名内部类)
内部类可以写在类的任意位置上 成员也包括局部
/*
内部类定义在局部时,
1,不可以被成员修饰符修饰 局部内部类不可以定义静态成员
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
*/
- class Outer
- {
- int x = 3;
- void method(final int a)
- {
- final int y = 4; //但是不可以访问它所在的局部中的变量。
- class Inner // 局部内部类
- {
- void function() //非静态,没对象,不运行。
- {
- System.out.println(y);
- }
- }
- new Inner().function(); // 建立对象后才能运行
- }
- }
- class InnerClassDemo3
- {
- public static void main(String[] args)
- {
- //new Outer().method();
- Outer out = new Outer();
- out.method(7);
- out.method(8);
- //当调用method方法,就进栈了,一进栈,栈里边有一个a,把7赋给a,就锁住了,7一直为a。method方法执行完,就出栈释放了,再调用就又进栈了,就是一个新的a
- }
- }
/*
匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。不包含3,最好是两个或一个
方法多 搞一个类继承一下,用类进行封装,下面建立类的对象进行调用
弊端:不能直接调用自己的方法;不能进行强制转换动作;方法过多不要使用匿名内部类(会导致阅读性非常差)
- class Inner extends AbsDemo
- {
- void show()
- {
- System.out.println("show :"+x);
- }
- }
下面是上面的简化格式
- public void function()
- {
- //new Inner().show();
- new AbsDemo() // absdemo的匿名子类对象 其实就是将上面一句话中的Inner()给替换了
- {
- void show()
- {
- System.out.println("x="+x);
- }
- }.show(); // 所以可以直接.show()进行调用 ( absdemo的匿名子类对象)
- }
- class Inner extends AbsDemo // 继承了一个类
- {
- int num = 90;
- void show() /进行了覆写
- {
- System.out.println("show :"+num);
- }
- void abc()
- {
- System.out.println("hehe");
- }
- }
- public void function()
- {
- //new Inner().show(); //创建对象 进行调用
- //AbsDemo a = new Inner();
- // Inner in = new Inner();
- // in.show();
- // in.abc();
分析:内部类都做了什么事情
继承了一个类
进行了覆写
创建对象
进行调用
匿名内部类
下面的是absdemo的子类对象(因为只有子类才能覆写absdemo类中的抽象方法)
AbsDemo d = new AbsDemo() //后面跟{}表示将AbsDemo中的方法实现了
// 父类引用指向子类对象(多态)
{
int num = 9; //成员变量
// 一般不会在匿名内部类中写太复杂,是因为匿名内部类是为了简化而存在的,你写太复杂 就失去意义了
void show()
{
System.out.println("num==="+num);
}
void abc()
{
System.out.println("haha");
}
};
d.show(); //只能使用父类方法
//d.abc();//编译失败; 父类中没定义过 abc是子类方法
匿名对象对方法只能调用一次
写匿名函数是为了简化书写,覆盖方法
05面向对象(异常概述)
异常的由来:用面向对象的思想把问题进行描述,并对其进行了对象的封装
把问题封装成对象就是异常
异常的体系
Throwable
Error
通常出现重大问题如:运行的类不存在或者内存溢出等
Exception
在运行时运行出现的一些情况,可以通过try catch finally
Exception和Error的子类名都是以父类名作为后缀
Java在设计异常体系时,将容易出现的情况都封装成了对象。
/*
异常:就是程序在运行时出现不正常情况。
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。
其实就是java对不正常情况进行描述后的对象体现。
对于问题的划分:两种:一种是严重的问题,一种非严重的问题。
对于严重的,java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。
对与非严重的,java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容。
比如:不正常情况的信息,引发原因等。
Throwable
|--Error
|--Exception
在使用一个体系时:原则,看父类定义建立子类对象
06面向对象(异常try-catch)
异常的处理
java 提供了特有的语句进行处理。
try
{
需要被检测的代码;
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}
对捕获到的异常对象进行常见方法操作。
String getMessage():获取异常信息。
*/
- class Demo
- {
- int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。
- {
- return a/b;
- }
- }
- class ExceptionDemo1
- {
- public static void main(String[] args) //throws Exception
- {
- Demo d = new Demo();
- try
- {
- int x = d.div(4,0);
- System.out.println("x="+x);
- }
- catch (Exception e) //Exception e = new ArithmeticException(); 多态
- {
- System.out.println("除零啦");
- System.out.println(e.getMessage()); //by zero
- System.out.println(e.toString()); //异常名称:异常信息
- }
- e.printStackTrace();//异常名称,异常信息,异常出现的位置
- //其实jvm默认的异常处理机制,就是在调用printStackTrace方法,打印异常的堆栈的跟踪信息。
- System.out.println("over");
- }
- }
07面向对象(异常声明throws)
异常的基本处理方式
在函数上声明异常。
便于提高安全性,让调用者进行处理。不处理编译失败。
当调用了一个有问题的功能时有几种处理方式: 要么捕捉,要么抛出去!
有问题时要给出预先处理方式
08面向对象(多异常处理)
对多异常的处理。
1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
建议在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句 e.printStackTrace(),
也不要简单的就书写一条输出语句。
*/
- class Demo
- {
- int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现问题。
- {
- int[] arr = new int[a];
- System.out.println(arr[4]);
- return a/b;
- }
- }
- //声明几个异常,就要有几个针对性处理
- class ExceptionDemo2
- {
- public static void main(String[] args) //throws Exception
- {
- Demo d = new Demo();
- try
- {
- int x = d.div(5,0);
- System.out.println("x="+x);
- }
- catch(Exception e)
- {
- System.out.println("hahah:"+e.toString())//;它全能干的原因是多态性:不管你抛什么异常,都是我小弟,都能帮你搞定,但是,处理没有针对性。所以在写try catch时要写针对性处理,向下面那样
- }
- catch (ArithmeticException e)
- {
- System.out.println(e.toString());
- System.out.println("被零除了!!");
- }
- catch (ArrayIndexOutOfBoundsException e)
- {
- System.out.println(e.toString());
- System.out.println("角标越界啦!!");
- }
- //异常不能同时发生:函数中只要有异常发生,这个函数就已经结束了。异常一产生,就被try检测到了,然后找到对应的catch进行了处理
- <pre class="java" name="code">System.out.println("over");
- }
- }
- </pre>
- <pre></pre>
- <p>当发生两个异常以外的异常时,你如果又写了catch(Exception e),1.你的处理并不具体,也就是说你自己都不知道具体发生什么了,你就把这个问题给处理了,相当于将问题隐藏,而程序还在继续运行。如果出现了对方指定的问题以外的情况,这时应该做的是程序停掉。让我们能看到这个问题,以致导致的现象,才能把代码进行修正,将问题解决掉,或者将问题在功能上标示一下,让对方有更针对性的处理。2.如果你将catch(Exception e)写在所有的catch最上面,程序第一个执行它,下面的就不执行了。在真出现异常时,我们是不打印的。把这个问题用一个硬盘文件记录下来
- ,称之为异常日志文件(每天都会产生的文件,记录着程序每天运行的状况),管理人员或者网站的维护人员会经常去看日志,然后进行调试</p>
- <p><strong><span style="color:#ff0000">09面向对象(自定义异常)</span></strong>/*因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。所以对于这些特有的问题可以按照java的对问题封装的思想。将特有的问题。进行自定义的异常封装。</p>
- <p>自定义异常。</p>
- <p>需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的。那么就需要对这个问题进行自定义的描述。*/</p>
- <pre class="java" name="code">class FuShuException extends Exception //getMessage();
- {
- private int value;
- FuShuException()
- {
- super();
- }
- FuShuException(String msg,int value)
- {
- super(msg);
- this.value = value;
- }
- public int getValue()
- {
- return value;
- }
- }
- class Demo
- {
- int div(int a,int b)throws FuShuException
- {
- if(b<0)
- throw new FuShuException("出现了除数是负数的情况------ / by fushu",b);//手动通过throw关键字抛出一个自定义异常对象。
- return a/b;
- }
- }
- class ExceptionDemo3
- {
- public static void main(String[] args)
- {
- Demo d = new Demo();
- try
- {
- int x = d.div(4,-9);
- System.out.println("x="+x);
- }
- catch (FuShuException e)
- {
- System.out.println(e.toString());
- //System.out.println("除数出现负数了");
- System.out.println("错误的负数是:"+e.getValue());
- }
- System.out.println("over");
- }
- }
- </pre>
- <p><br>
- </p>
- <p>/*<br>
- 当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。<br>
- 要么在内部try catch处理。<br>
- 要么在函数上声明让调用者处理。</p>
- <p>一般情况下,函数内出现异常,函数上需要声明。</p>
- <p><br>
- 发现打印的结果中只有异常的名称,却没有异常的信息。<br>
- 因为自定义的异常并未定义信息。</p>
- <p>如何定义异常信息呢?<br>
- 因为父类中已经把异常信息的操作都完成了。<br>
- 所以子类只要在构造时,将异常信息传递给父类通过super语句。<br>
- 那么就可以直接通过getMessage方法获取自定义的异常信息。</p>
- <p> </p>
- <p><strong>自定义异常:</strong><br>
- 必须是自定义类继承Exception。</p>
- <p><br>
- <strong>继承Exception原因:</strong><br>
- 异常体系有一个特点:因为异常类和异常对象都被抛出。<br>
- 他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。</p>
- <p>只有这个体系中的类和对象才可以被throws和throw操作。</p>
- <p>父类中的写法:<br>
- </p>
- <pre class="java" name="code">class Throwable
- {
- private String message;
- Throwable(String message)
- {
- this.message = message;
- }
- public String getMessage()
- {
- return message;
- }
- }
- class Exception extends Throwable
- {
- Exception(String message)
- {
- super(message);
- }
- }
- </pre>
- <p><br>
- <br>
- 父类当中已经定义了构造函数可以接收一个信息,并通过方法获取信息,那么毫无疑问,里边必须要有一个变量来记录这个信息(String message)。那么,父类把这些信息都做完了,子类在继承时就不用再进行这些动作了,只要将信息传给父类(super(message;)),然后子类new Exception("haha").getMessage();就可以获取这些信息。</p>
- <pre class="java" name="code">class Person
- {
- String name;
- Person(String name)
- {
- this.name = name;
- }
- public String getName()
- {
- return name;
- }
- }
- class Student extends Person
- {
- Student (String name)
- {
- super(name);
- }
- }
- new Sttdent("lisi").getName();
- </pre>
- <p><br>
- </p>
- <p> </p>
- <p><br>
- <strong><span style="color:#ff0000">10面向对象(throw和throws的区别)</span></strong></p>
- <p>throws和throw的区别<br>
- throws使用在函数上。<br>
- throw使用在函数内。</p>
- <p>throws后面跟的异常类。可以跟多个。用逗号隔开。<br>
- throw后跟的是异常对象。<br>
- <strong><span style="color:#ff0000">11面向对象(runtimeException)</span></strong><br>
- <br>
- Exceptoin中有一个特殊的子类异常RuntimeException 运行时异常。</p>
- <p>如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。</p>
- <p>如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;</p>
- <p>之所以不用在函数声明,是因为不需要让调用者处理。<br>
- 当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,<br>
- 对代码进行修正。</p>
- <p> </p>
- <p><br>
- <strong>自定义异常时:</strong>如果该异常的发生,无法在继续进行运算,<br>
- 就让自定义异常继承RuntimeException。</p>
- <p>RuntimeException的出现会引发程序停止<br>
- 对于异常分两种:<br>
- <strong>1,编译时被检测的异常。</strong><br>
- 在javac编译时,会去检测如果方法当中抛出了非RuntimeException以及其子类(因为这些异常时可处理的,要标示出去,让调用者去处理),那么在函数上没标示就视为有安全隐患<br>
- 如果函数上标示了异常,调用者也必须要有相对应的处理方式:要么抛,要么try<br>
- <strong>2,编译时不被检测的异常</strong>(运行时异常。RuntimeException以及其子类)<br>
- 里边抛,外面不用声明:凡是RuntimeException以及其子类,它会判断一下,如果是这个类型,就不管<br>
- </p>
- <p> </p>
- <p>12面向对象(异常练习)</p>
- <p>/*<br>
- 毕老师用电脑上课。</p>
- <p>开始思考上课中出现的问题。</p>
- <p><br>
- 比如问题是<br>
- 电脑蓝屏。<br>
- 电脑冒烟。</p>
- <p>要对问题进行描述,封装成对象。</p>
- <p><br>
- 可是当冒烟发生后,出现讲课进度无法继续。</p>
- <p>出现了讲师的问题:课时计划无法完成。</p>
- <p><br>
- */</p>
- <pre class="java" name="code">class LanPingException extends Exception
- {
- LanPingException(String message)
- {
- super(message);
- }
- }
- class MaoYanException extends Exception
- {
- MaoYanException(String message)
- {
- super(message);
- }
- }
- class NoPlanException extends Exception
- {
- NoPlanException(String msg)
- {
- super(msg);
- }
- }
- class Computer
- {
- private int state = 3;
- public void run()throws LanPingException,MaoYanException
- {
- if(state==2)
- throw new LanPingException("蓝屏了");
- if(state==3)
- throw new MaoYanException("冒烟了");
- System.out.println("电脑运行");
- }
- public void reset()
- {
- state = 1;
- System.out.println("电脑重启");
- }
- }
- class Teacher
- {
- private String name;
- private Computer cmpt;
- Teacher(String name)
- {
- this.name = name;
- cmpt = new Computer();
- }
- public void prelect()throws NoPlanException
- {
- try
- {
- cmpt.run();
- }
- catch (LanPingException e)
- {
- cmpt.reset();
- }
- catch (MaoYanException e)
- {
- test();
- throw new NoPlanException("课时无法继续"+e.getMessage());
- throw单独存在时,下面不要写语句,因为它就是函数的结束标示(return)
- 所以test();要放在throw上面
- }
- System.out.println("讲课");
- }
- public void test()
- {
- System.out.println("练习");
- }
- }
- class ExceptionTest
- {
- public static void main(String[] args)
- {
- Teacher t = new Teacher("毕老师");
- try
- {
- t.prelect();
- }
- catch (NoPlanException e)
- {
- System.out.println(e.toString());
- System.out.println("换老师或者放假");
- }
- }
- }
- </pre>
- <p><br>
- <br>
- </p>
- <p align="left"> </p>
- <p align="center"><span style="font-size:14px">-------</span><a href="http://www.itheima.com/" target="_blank"><strong>android培训</strong></a><strong>、</strong><a href="http://www.itheima.com/" target="_blank"><strong>java培训</strong></a><strong>、期待与您交流-------</strong></p>
- <pre></pre>
- <pre></pre>