- Java面向对象编程知识点总结。
一:内部类。
将一个类定义在另一个类的里面,就称该类为内部类。
1.内部类的特点:1.内部类可以直接访问外部类的成员,包括私有成员。
2.而外部类要访问内部类要建立内部类的对象才能访问。
3.之所以能直接访问外部类中的成员是因为内部类持有一个外部类的引用。格式为(外部类.this)。
4.当内部类定义在外部类的成员位置上而且非私有,可以在外部类中直接建立对内部类的对象对其成员进行访问。书写格式为:
外部类名.内部类名 变量名 =new外部类对象().内部类对象()。
5.当内部类在成员位置上,就可以被成员修饰符修饰。
比如:private将内部类在外部类中进行封装。Static:内部类就具有了静态特性。当内部类被static修饰后只能直接访问外部类中的静态成员。并且当内部类定义了静态成员,则内部类也为静态成员。
6.内部类的使用,当描述的事物,在事物的内部还有事物,该内部事物就用内部类来描述。因为内部事物在使用外部事物的内容,
7.局部内部类(放在外部类成员函数中的内部类)不能用static修饰。不可以被成员修饰符修饰。
8.可以直接访问外部类中的成员,持有外部类的引用,当是不可以直接访问它所在的成员方法中的变量,只能访问被final修饰的局部变量。
二:匿名内部类。
匿名内部类其实就是内部类的简写格式。
1. 定义匿名内部类的前提:1.匿名内部类必须是继承一个类或者是实现自接口。2.匿名内部类的演变过程及书写格式:
父类或接口(){定义子类内容}.子类中的方法();
未使用内部匿名类的示例:
abstract class Father
{
public int age= 54;
abstract publicvoid eat();
}
class Outer
{
int age = 10;
class Inner extends Father//使用匿名的前提是继承或实现。
{
publicvoid eat()
{
System.out.println("letme eat something"+age);
}
}
public voidfun()//在外部类中建立内部类的对象调用内部类的方法。
{
new Inner().eat();
Father f = new Father()//多态写法。
//没有名字的继承自父类使用父类的名字
{
public void eat()
{
System.out.println("let me eat something"+age);
}
}.eat();//匿名内部类部分可以替代红色字体部分。完成的步骤有:
1.先继承自父类但没有名字(使用父名)。2.大括号中重写父类方法或增加自己的方法。3.通过“.”调用匿名内部类的方法。
}
}
class InnerClassDemo
{
public staticvoid main(String[] args)
{
newOuter().fun();//1.调用外部类的fun()>>2.在fun中建立内部类的对象并访问其eat()方法。3.>>执行方法。
}
}
3.其实匿名内部类就是一个匿名子类对象,是把定义类和建立对象封装为一体的一个表现形式。可以理解为带内容的对象。5.定义方法不要超过三个为好。
三:异常概述。
异常就是程序在运行时出现的不正常情况。异常的由来:问题在生活中是一个具体的事物,也可以通过类的形式进行描述,并封装成对象。
1.Java中对于问题的划分:1.非常严重问题(error)。2.严重问题(Exception)。
2.对于问题的处理:1Java中对于非常严重的问题通过error类进行描述。对于error一般不编写针对性的代码对其进行处理。2.对于严重的问题,Java通过exception类进行描述。对于Exception可以使用针对性的处理方式进行处理。
Throwable接口
|--Error类。
|--Exception类。
Publicstatic int fun(int a)
{ intb =2;
return a/b;
}
public static void main(String[] args)
{
int x = fun(0);//当被除数为0时抛出异常。
}
3.异常处理:Java提供了特殊的语句进行处理。格式为:
try
{
需要被检测的代码
}
catch(异常类变量1)
{
处理异常代码1(即处理方式)
}
catch(异常类变量2)
{
处理异常代码2(即处理方式)
}
finally
{
一定会执行的语句
}
4.throw和throws的用法:
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
当函数内有throw抛出异常对象,并未进行try处理。必须要在函数上声明,两者都在编译失败。RuntimeException除外函数内如果抛出的RuntimeExcpetion异常,函数上可以不用声明。
5.对捕获到的异常对象进行处理的两种方法:
String e.getMessage();//返回异常类的信息为字符串。
String e.toString();获取异常名称,异常信息。
e.printStackTrace();异常名称,异常信息,异常出现位置。
6.异常的分类:
1.编译时被检测异常该异常在编译时,如果没有处理(没有抛也没有try),编译失败。该异常被标识,代表这可以被处理。
7.异常的出现。
当在编程过程中,某些函数或语句可能出现异常的状况,比如当a/b,b为0时,这种算法是不被允许的,那么该处就是程序的一个运行隐患,那么此时我们就要把它标示出来。标示的方法是:
1.在该语句的后边通过throw newException()标示,throw是异常类特有的程序跳转关键字,throw用在函数的内部,new Exception()是在跳转时传递的异常对象(异常类中封装了各种异常对象,其各显示功能也不同)。
2.当函数内出现了异常的标示,这时就必须在函数上也进行标示,标示的方法是在函数的参数列表后边通过throws Exception进行标示。
3.当程序中包含了标示安全隐患的异常抛出语句后,程序就不再像以前那种编程不管它有没有安全隐患,都可以被编译被执行的程序了。也就是说你标示出了存在安全隐患的函数或语句后,你标示的目的就更明确了。那目的是什么,就是既然你把它标示出来了,你只是知道有安全隐患是没有任何价值的,你需要处理它,需要为安全隐患写预案,当出现除数为0时,程序应该怎么这么办,当数组的下标越界后,程序应该怎么这么做。
也就是强制处理。这时的程序在你不写预案的情况下,会告诉你:程序抛出异常,需要通过throws或try的方式处理才能够编译通过。
总结就是:假如你不理它,还是以前的那样像一条船有一个小洞,不去管它船也不会沉。你是可以出海的(编译通过的)。假如家人很关心打渔人,提醒了他(标示了),你就要必须不违背家人的意愿处理它,否则家人是不让你出海(通不过编译)(RuntimeException除外)。
4.标示后(抛出异常后),想通过编译的两种方法:1.异常处理不了或不想处理,就在主函数上也抛出,这里会把异常抛出给虚拟机的默认处理,就可以通过编译了。2.通过catch捕获异常,也就是你写了预案。就可以通过写的预案处理异常,可以通过编译了。
例如:
int div(int a,int b)throwsAritchmeticException
{
returna/b;
}
try
{//1.执行函数如果发生异常抛出异常给2跳转到2。3不执行
intx =div(4,0);new AritchmeticException()
3.System.out.println(x);
}
//2.接受异常的对象。显示处理结果
catch(Exceptione)Exception e = new AritchmeticException()
{
System.out.println(“除零”);
return;//当处理中有return时,4不会被执行。
}
//4.执行异常处理后的代码。
System.out.println(“over”);
5.多异常处理。
在出现多个异常的函数后写上throws异常1,异常2。抛出几个异常就写几个catch(解决方案)。如果多个catch中存在异常的继承关系,父类的catch块要放在最后执行。
class Demo
{intdiv(inta,intb)throws
ArithmeticException,ArrayIndexoutofException
{
int arr[] = new int[a];
printlnI(arr[4]);
return a/b;
}
}
class Test
{
publicstatic void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(5,0);
println(x);
}
catch(ArithmeticException e)
{
prinln(e.toString());
}
catch(ArrayIndexoutofException e)
{
println(e.toString());
}
catch(Exception e)//Exception异常是父类要放在最后处理。
{
println(e.toString());
}
}
}
6.自定义异常。
因为项目中会出现特有的问题,这些问题并未被java所描述,所以对于这些问题可以按照java的对问题封装的思想,将特有的问题进行自定义的异常封装。
自定义异常的实现:
1. 首先定义自定义类并继承Exception。
2. 调用父类的构造函数将自定义的异常信息传递给父类。
3. 在函数内通过throw手动抛出自定义异常对象。
4.当在函数内使用手动抛出异常时:要不在内部使用try解决,要不就在函数上进行throws抛出给函数的调用者进行跳转。一般情况下在函数内出现异常都要在函数上进行抛出。抛出后就与throws的处理方式相同,要么throws给虚拟机,要么try。
class FuShu Exceptionextends Exception
{ priavte String msg;
FuShu(String msg)
{ //将异常信息传递给父类的构造函数,达到显示自定义异常的作用。
super(msg);
}
}
class Demo
{
int div(int a, int b)throws FuShuException
{//throw是手动抛出异常关键字抛出一个自定义异常对象。
if(b<0)throw FuShuException(“the numis fault”);
}
}
class test
{ public static void main(String[] args)
{
try
{
int x = new Demo().div(4,-1);
println(x);
}
catch(FuShu Exception e)
{
println(e.toString()+e.getMessage()+e.printStackTrace());
}
}
}
7.异常体系:
因为异常类和异常对象都要被抛出,它们都具备可抛性。这个可抛性是Throwable这个体系独有的特点,只有这个类中的体系或者对象才能被throw和throws操作。
8.Runtime异常。
如果在函数内抛出该异常,函数上可以不用声明,编译一样可以通过。如果在函数上声明了该异常,调用者可以不处理也可以编译通过。之所以不用在函数上声明该异常,异常发生时,希望程序停止,因为在运行时出现了无法继续运算的情况,希望停止修正。Runtime抛出的是不能解决的问题,需要修改代码,而Exception是可以处理的问题,就去写预案,比如:人造卫星的对接,在对接过程中可能会出现多种外界因素干扰,当有小行星撞击怎么办,你可以躲,当太阳能电池没有存满电可以等。但在对接时,你的对接设备和另一个卫星的对接设备不兼容,这个是被Runtime标示为解决不了的问题,那还是让卫星返回地球,重新设计对接设备吧。这就是Runtime类是在编译时不用检测的,你也不用写预案,因为检查到也处理不了,就让对接任务停止了(程序停止)。是自身出了问题,需要程序员对其内部程序进行修改满足运行条件。Exception则是在编译时检测,就是在制造卫星时就要考虑好的问题。写好预案,在对接时便可以顺利完成任务。
9.Try...catch...finally的使用。
如果catch语句中出现了return语句,这时程序会在执行完finally后跳出函数,不再执行finally后边的语句,如下:
public void demo ()
{
catch(Exception e)
{
println(“a”);1
return//使用return程序会执行完2后跳出函数不执行3
}
finally
{
println(“b”);2
}
println(“c”);3
}
输出:a,b。
异常在子父类覆盖中的体现;
1,子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
2,如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。
class AException extends Exception
{
}
class BException extends AException
{
}
class CException extends Exception
{
}
Exception
|--AException
|--BException
|--CException
class Fu
{
voidshow()throws AException
{
}
}
class Test
{
voidfunction(Fu f)
{
try
{
f.show();
}
catch(AException e)
{
}
}
}
class Zi extends Fu
{//父类中没有c异常,这里的重写方法只能try,下面书写不正确。
voidshow()throws CException
{
}
}
class
{
publicstatic void main(String[] args)
{
Testt = new Test();
t.function(newZi());
}
}
10.异常练习;
有一个圆形和长方形。
都可以获取面积。对于面积如果出现非法的数值,视为是获取面积出现问题。问题通过异常来表示。现有对这个程序进行基本设计。
Exception的写法:
//创建自定义异常
class FaultException extends Exception
{privateString msg;
FaultException(Stringmsg)
{
super(msg);
}
}
class GetSquare
{privateint r;
privatefinal float PI =3.14f;
privateint h;
privateint l;
publicvoid yuan (int r)throws FaultException
{ if(r <0)
thrownew FaultException("传入的半径值为负数");
floatseq;
seq= r*PI;
System.out.println("圆面积:"+seq);
}
publicvoid fang(int h,int l)throws FaultException
{ if(h<0||l<0)
thrownew FaultException("传入的长宽高为负数");
floatseq = h*l;
System.out.println("方面积:"+seq);
}
}
class ExecptionDemo
{
publicstatic void main(String[] args)
{
try
{
//newGetSquare().yuan(-10);
newGetSquare().fang(-10,10);
}
catch(Exception f)
{
System.out.println(f.toString());
}
}
}
RuntimeException类的写法:
class FaultException extendsRuntimeException
{
FaultException(Stringmsg)
{
super(msg);
}
}
class GetSquare
{privateint r;
privatefinal float PI =3.14f;
privateint h;
privateint l;
publicvoid yuan (int r)
{ if(r <0)
thrownew FaultException("传入的半径值为负数");
floatseq;
seq= r*PI;
System.out.println("圆面积:"+seq);
}
publicvoid fang(int h,int l)
{ if(h<0||l<0)
thrownew FaultException("传入的长宽高为负数");
floatseq = h*l;
System.out.println("方面积:"+seq);
}
}
class ExecptionDemo
{
publicstatic void main(String[] args)
{
//newGetSquare().yuan(-10);
newGetSquare().fang(-10,10);
}
}
11.包(package)
用于存放具有相似功能的类。
1. 对类文件进行分类管理。
2. 给类提供多层命名空间。
3. 写在程序文件第一行。
4. 类名的全称是报名加类名。
5. 包也是一种封装形式。
6. 包的使用:
1. 写在程序第一行,使用关键字package声明,书写为全部小写。
package pack;
class A{}
打包A类到pack包中,要通过控制台操作。
javac –d空格.空格 文件名.java打包A类到当前目录下的pack包中。
package pack;
class DM
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
7. 包与包之间的功能调用。
1. 包与包之间访问类:1.导入包中的类:import pack.DM;
DM packClass = new DM();
2. 也可以写出包的全称使用: Pack.DMpackClass = new Pack.DM();
3.
被访问的其他包中的类必须被public修饰才可以访问,而且一个文件中只能有一个被public修饰的公共类。如果导入的包与包之间有重名类,那这时必须写全称。公共类的方法也必须是共有的否则其他包中的类无法访问。
8. jar包。
jar包是java的压缩包。打包的方式是:java –cf xx.jar package1... packagen.把package1...packagen压缩到xx.jar中。