面向对象基础(下)课件_第1页
面向对象基础(下)课件_第2页
面向对象基础(下)课件_第3页
面向对象基础(下)课件_第4页
面向对象基础(下)课件_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

面向对象基础(下)第4章面向对象程序设计(下)一.类的继承

1.继承机制:在面向对象编程里,可以根据已定义的类定义一个新类,从而实现代码的复用。其中,被继承的类称父类,由继承而得到的类称子类。子类具有父类的成员(属性和方法),同时也可以修改父类的属性或重写父类的方法,并增加新的属性和方法。

2.继承通过entends关键字实现。这种关系也叫做“is”关系:

classAextendsB,

A(子类)isaB(父类)

例:classEmployee{ publicStringname=“”; publicdoublesalary; publicDatebirthDate; publicStringgetDetails(){…}}

publicclassManager{publicStringname=“”;publicdoublesalary;publicDatebirthDate;publicStringdepartment;

publicStringgetDetails(){

…}}publicclassManagerextendsEmployee{ publicStringdepartment;}完整代码如下:publicclassEmployee{publicStringname;publicintage;publicEmployee(Stringname,intage){=name;

this.age=age;}publicEmployee(){}publicStringgetInfo(){System.out.println(name); System.out.println(age);}}classManagerextendsEmployee{ publicvoidmanage() { System.out.println("managing"); } publicstaticvoidmain(String[]args) { Employeep=newEmployee(); ="Employee";p.age=30; p.getInfo(); Managerm=newManager(); ="Manager";m.getInfo();m.manage(); }}

要在以前的类的基础上构造新类,必须在新类的声明中扩展以前的类,通过扩展一个超类,可以得到这个类的一个备份,并在这个基础上,添加新的属性和方法。如果对新类不作任何添加工作,那它的工作情况会与超类完全相同。新类中会含有超类所声明或继承的所有属性和方法。在类的继承中会有以下一些细节问题应注意:

(1)通过类的继承可以简化类的定义。

(2)java只支持单继承,不允许多重继承。在 java中,一个子类只能由一个父类,但一 个类可以被多个类继承。

(3)可以有多层继承,即一个类可以继承某一 个类的子类,即间接继承。如:classA{

}ClassBextendsA{}ClassCextendsB{}(4)子类继承父类的所有成员变量和成员方法,但不继承父类的构造方法,在子类的构造方法中,可以使用语句super(参数列表)调用父类的构造方法。如:我们为Manager类增加一个构造方法,在这个构造方法中用super明确指定调用父类的某个构造方法。

classManagerextendsEmployee{ publicManager(Stringname,intage,Stringcompany) { this(name,age);pany=company; } }(5)如果子类构造方法中没有显式调用父类的构造方法,也没有使用this关键字调用重载的本类的其它构造方法,则在产生子类的实例对象时,系统默认调用父类无参的构造方法。在下面的类B中,定义的构造方法中,写不写super()语句的效果是一样的。

classBextendsA{publicB(){super();}}(1)分配成员变量的存贮空间并进行默认的初始化,就是用new关键字产生对象后,对类中的成员变量按系统默认的值进行初始化赋值。3.子类对象的实例化过程

对象中的成员变量的初始化是按下述步骤进行的:(2)绑定构造方法,就是用new(实参列表)所传递进的参数赋值给构造方法中的形式参数。

(3)如果有this调用,则调用相应的重载构造方法(被调用的重载构造方法又从步骤2开始执行这些流程),被调用的重载构造方法的执行流程结束后,回到当前构造方法,当前构造方法直接跳转到(6)去执行。

(4)显式或隐式追溯调用父类的构造方法(一直到Object类为止,Object类是所有java类的最顶层父类),父类的构造方法又从步骤(2)开始对父类执行这些流程,父类的构造方法的执行流程结束后,回到当前构造方法,当前构造方法继续往下执行。(5)进行实例变量的显式初始化,也就是执行在定义成员变量时就对其进行的赋值语句,如:classManagerextendsEmployee{Stringcompany=“sun公司”;......}(6)执行当前构造方法体中的程序代码,如:classManagerextendsEmployee{Stringcompany=“sun公司”;

publicManager(Stringname,intage,Stringcompany){super(name,age);pany=company;}}4.覆盖父类的方法要求:

1.方法声明形式一致(相同的方法名称、参数列表、返回类型)2.方法权限不允许缩小

3.覆盖的方法不允许抛出比父类方法更多的异常

在子类中可以根据需要对从父类中继承来的方法进行改造,把这个过程称为覆盖(也叫重写)例:

classPerson{publicStringname;publicintage;

publicvoidgetInfo(){System.out.println(name);System.out.println(age);}}classStudentextendsPerson{Stringschool=newString();

publicvoidstudy(){ System.out.println("studding");}publicvoidgetInfo(){ super.getInfo();System.out.println(school);}

publicstaticvoidmain(String[]args)

{ Personp=newPerson();

="person";p.age=30;p.getInfo();

Students=newStudent();="student";s.age=16;s.school="清华大学";

s.getInfo();s.study();

}}

当重载方法时,在一个类中用相同的名字创建多个方法(每个方法的参数表不同);

当覆盖一个方法时,在一个类中创建的方法与超类中方法的名字和参数表相同。

重载(overloading)与覆盖(overriding)的差异:5.final关键字(1)Java中声明类、属性、方法时,可使用关键字final来修饰。(2)final标记的类不能被继承。(3)final标记的方法不能被子类重写。(4)final标记的变量即为常量,只能赋值一次。finalintX=3;X=4;//出错final标记的成员变量必须在声明的同时或在该类的构造方法中显式赋值,然后才能使用。classTest{finalintX=3;}或classTest{finalintX;Test(){X=3;}}(5)方法中定义的内置类只能访问该方法内的final类型的局部变量,用final定义的局部变量,相当于是一个常量,它的生命周期超出方法的运行周期。将一个形参定义成final也可以,这就限定了我们方法中修改形式参数的值。(6)java中的String类为final类,不能被继承。它对编译器和解释器的正常运行有很重要的作用,不能轻易改变。final类的特性保证了String类型的唯一性。

publicfinalclassStringextendsObject注意:

final标记的变量(成员变量和局部变量)即成为常量,只能赋值一次,但这个常量只能在这个类的内部使用,不能在类的外部使用。当我们用publicstaticfinal共同标记常量时,这个常量就成了全局常量。而且这样定义的常量只能在定义时赋值,即使在构造方法里也不能对其赋值。在java中定义常量,总是用publicstaticfinal组合方式进行标记。Java中的全局变量也放在一个类中定义。二.抽象类与接口Java中可以定义一些不含方法体的方法,它的方法体的实现交给该类的子类根据自己的实际情况去实现,这样的方法就是抽象方法,包含抽象方法的类就叫抽象类。一个抽象类可以有多个抽象方法。抽象方法必须用abstract修饰符来定义,任何带有抽象方法的类都必须声明为抽象类1.抽象类(1)抽象类的定义规则:抽象类与抽象方法都必须用abstract关键字来修饰;抽象类不能被实例化,也就是不能用new去参生对象;抽象方法只需声明,而不需实现;含有抽象方法的类必须被声明为抽象类,抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个类还是个抽象类。(2)抽象方法的书写格式

abstract返回类型抽象方法名(参数列表);(3)抽象类与抽象方法的例子

abstractclassA{abstractintadd(intx,inty);}注意:含有抽象方法的类肯定是抽象类,抽象类中某方法不一定是抽象的2.接口(1)接口:如果一个抽象类中的所有方法都是抽象的就可以将这个类用另外一种方式来定义,接口是抽象方法和常量的集合。是一种特殊的抽象类。提供复杂的软件对象内部与外界的交互。定义不相关类的共同行为,而不需考虑这些类之间的层次关系可以指明多个类需要实现的方法可以了解对象的编程界面,而不需了解对象所对应的类(揭示一个编程界面,而不揭示类体)通过一个接口列表实现多重继承(多重继承的伪装)(2)接口定义interface接口名[extends接口列表]{

接口体;}

声明时,public公有接口

extends类:只有一个父类

“isa”关系接口:可有多个父接口接口体:常量值,在接口中定义的常量可以被实现它的多个类共享,它默认是用publicstaticfinal标识的。

3.实现接口class类名implements接口列表{

类体;(可以使用接口中定义的常量,必须实现接口中定义的所有方法)}classFIFOQueueimplementsCollection{voidadd(Objectobj){…};voiddelete(Objectobj){…};voidfind(Objectobj){…};intcurrentCount(){…};}4.接口类型接口可以作为引用类型来使用,任何实现该接口的类的实例都可以存储在该接口类型的变量中,通过这些变量可以访问类中所实现的接口中的方法,java运行时系统会动态的确定该使用哪个类中的方法.classTest_interface{publicstaticvoidmain(Stringargs[]){Collectionc1=newFIFOQueue();Collectionc2=newStack();c1.add(obj);c2.add(obj);}}publicinterfaceRunner{intID=1;voidrun();}interfaceAnimalextendsRunner{ voidbreathe();}abstractclassLandAnimalimplementsAnimal{publicvoidbreathe(){System.out.println("LandAnimalisbreathing");}}classFishimplementsAnimal{publicvoidrun(){ System.out.println("fishisswimming");}publicvoidbreathe(){ System.out.println("fishisbubbling");}}publicclassTestFish{publicstaticvoidmain(Stringargs[]){ Fishf=newFish(); intj=0; //j=f.ID;//一般不用对象来访问 j=Runner.ID;System.out.println("j="+j);}}运行结果:三.对象的多态性1.对象类型的转换

(1)子类转换为父类子类能自动转换为父类类型注:1)引用可以点取父类中的成员(编译 时指向父类成员,运行时动态绑定 到子类中的成员)

2)不可以点取子类扩充的成员(2)父类转换为子类父类转换为子类不会自动进行,必须强制转换。classA{ publicvoidfunc1() { System.out.println("Afunc1iscalling"); } publicvoidfunc2() { func1(); }}例:classBextendsA{ publicvoidfunc1() { System.out.println("Bfunc1iscalling"); }publicvoidfunc3(){ System.out.println("Bfunc3iscalling"); }}classC{ publicstaticvoidmain(String[]args) { Bb=newB(); Aa=b; callA(a); callA(newB()); } publicstaticvoidcallA(Aa) { a.func1(); a.func2(); }}运行结果:我们把callA方法作如下修改:publicstaticvoidcallA(Aa){ Bb=(B)a; b.func1(); b.func2(); b.func3();}运行结果:classA{intaa=10;voidcallme(){System.out.println("InsideA’scallme()methoda="+aa);}}classBextendsA{Stringaa="China";voidcallme(){System.out.println("InsideB’scallme()methodaa="+aa);}}publicclassC{publicstaticvoidmain(Stringargs[]){/*父类对象创建时引用了子类的构造方法,创建的实际上是子类的对象。*/Aa=newB();/*这一行运行时,显示的是子类的callme()结果*/a.callme();System.out.println("aa="+a.aa);

System.out.println("aa="+((B)a).aa);} }上例说明:

a为A类型的变量,用new建立A类型的子类B的一个实例,并将其引用存储到a中。编译时a.callme()指向父类A的成员方法,而运行时,则动态绑定到子类B中的成员方法。故程序将调用B的callme()方法。运行的多态性,体现了面向对象程序设计的代码复用。运行结果:InsideB’scallme()methodaa=Chinaaa=10aa=China总结

原则上,所引用的对象实例,必须含有欲转换的类类型的实例,也就是说,所引用的对象实例的类类型,必须是欲转换成的类、或它的子孙类。(3)instanceof操作符

可以用判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。其语法格式为:对象instanceof类(或接口)

返回类型是布尔型:true或falsepublicstaticvoidCallA(Aa){if(ainstanceofB){Bb=newB();b.func1();b.func2();b.func3();}}2.Object类Java中有一个比较特殊的类-Object类,它就是所有类的父类。如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类就默认继承Object类,因此,Object类是所有类的最高层类。

publicclassPerson{...}

等价于:

publicclassPersonextendsObject{...}Object类中有一个equals方法,用于比较两个对象是否相等,默认返回值是false。由于类的继承性,可以在任何类中使用equals方法,但返回值总是false,比较结果就不一定正确了,所以,自定义类中必须覆equals方法。classStudent{ Stringname;intage;publicbooleanequals(Objectobj){ Studentst=null; if(objinstanceofStudent) st=(Student)obj; else returnfalse;if(==&&st.age==this.age) returntrue; elsereturnfalse;}st.CompareTo(this)publicstaticvoidmain(String[]args) { Studentp=newStudent(); Studentq=newStudent(); ="xyz"; p.age=13; ="xyz"; q.age=13; if(p.equals(q)) System.out.println("p与q相等"); else System.out.println("p与q不等"); }}运行结果:3.面向对象的多态性特点:

(1)应用程序不必为每一个派生类(子类)编写功能调用,只需对抽象基类进行处理即可。这叫“以不变应万变”,可大大提高程序的可复用性。

(2)派生类的功能可被基类的方法或引用变量调用,这叫向后兼容可以提高程序的可扩充性和可维护性。以前写的程序可被后来的程序调用不足为奇,现在写的程序可调用以后写的程序就很了不起了。4.匿名类匿名类(anonymouseclass)—内部类的一种特殊形式.本地类和匿名类最主要的区别是匿名类没有自己的名字.abstractclassA{abstractpublicvoidfun1();}publicclassOuter{publicstaticvoidmain(String[]args){

classInnerextendsA{publicvoidfun1(){System.out.println("implementforfun1");}}newOuter().callInner(newInner());}publicvoidcallInner(Aa){a.fun1();}}

运行结果:对于上面程序,可以简写publicclassOuter{publicstaticvoidmain(String[]args){newOuter().callInner(newInner(){ publicvoidfun1(){System.out.println("implementforfun1");}});}publicvoidcallInner(Aa){a.fun1();}}四.异常

异常就是在程序的运行过程中所发生的异常事件,它中断指令的正常执行。Java中提供了一种独特的处理异常的机制,通过异常来处理程序设计中出现的错误例:classExceptionDemo2{publicstaticvoidmain(Stringargs[]){ inta=0;System.out.println(5/a);}}运行结果:

因为除数不能为0,所以在程序运行的时候出现了除0溢出的异常事件。为什么有的异常在编译时出现,而有的异常是在运行时出现的?让我们继续学习java的异常处理机制。1.概述

(1)异常事件:中断程序正常执行流程的事件。

java中的异常事件:

错误Error(可处理的错误)

异常Exception(可以处理,编写代码,

不影响程序的继续执行)(2)异常类

1)ArithmeticException

例:inti=12/0;2)NullPointerException

例:Dated=null; System.out.println(d.toString());3)NegativeArraySizeException:数组大小为负数异常4)ArrayIndexOutOfBoundsException:数组越界异常5)SecurityException:安全异常,特指applet。

2.异常机制

Java具有的一般目的的错误处理系统称为异常机制(Exceptionmechanism)的特性。异常机制由两部分组成:抛出异常和捕获它们。抛出一个异常意味着发出一个错误信号,捕获它意味着捕获和处理已经抛出的错误。异常的传递规则:异常向下通过调用堆栈直到它被一个方法处理。3.异常处理

java执行过程中,出现了异常,会生成异常对象,其中包含信息有异常事件类型以及异常发生时程序的运行状态,异常对象将传递给java运行时系统,这一过程(产生和提交)叫抛出异常.异常处理就是程序中编写代码捕获异常,处理它们,使程序继续执行。

a.结构:

try{

......

}catch(ExceptionName1e){

......

}catch(ExceptionName2e){

......

}

......

}finally{

......

}

try捕获异常的第一步是用try{…}选定捕获异常的范围,由try所限定的代码块中的语句在执行过程中可能会生成异常对象并抛弃。catch每个try代码块可以伴随一个或多个catch语句,用于处理try代码块中所生成的异常事件。catch语句只需要一个形式参数指明它所能够捕获的异常类型,这个类必须是Throwable的子类,运行时系统通过参数值把被抛弃的异常对象传递给catch块。

在catch块中是对异常对象进行处理的代码,与访问其它对象一样,可以访问一个异常对象的变量或调用它的方法。

getMessage()是类Throwable所提供的方法,用来得到有关异常事件的信息,类Throwable还提供了方法printStackTrace()用来跟踪异常事件发生时执行堆栈的内容。

try{

......}catch(FileNotFoundExceptione){

System.out.println(e);

System.out.println("message:"+e.getMessage());

e.printStackTrace(System.out);}catch(IOExceptione){

System.out.println(e);}例如:catch语句的顺序:捕获异常的顺序和catch语句的顺序有关,当捕获到一个异常时,剩下的catch语句就不再进行匹配。因此,在安排catch语句的顺序时,首先应该捕获最特殊的异常,然后再逐渐一般化。也就是一般先安排子类,再安排父类。finally:捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,finally块中的语句都会被执行。finally代码块唯一不能被执行的情况是:在被保护的代码块中执行了System.exit(0).b.throws关键字

如果在一个方法中生成了一个异常,但是这一方法并不确切地知道该如何对这一异常事件进行处理,这时,一个方法就应该声明抛出异常,使得异常对象可以从调用栈向后传递,直到有合适的方法捕获它为止。例:classTest{publicintdevide(intx,inty)throws DevidedByMinusException,ArithmeticException { intresult=x/y; returnx/y; }}classDevidedByMinusExceptionextendsException{intdevisor;public

DevidedByMinusException(String

msg,int

devisor){super(msg);this.devisor=devisor;}publicintgetDevisor(){returndevisor;}}publicclassTestException{publicstaticvoidmain(String[]args){try{ //intresult=newTest().devide(3,0); intresult=newTest().devide(3,-1); //intresult=newTest().devide(3,1); System.out.println("theresultis"+result);}catch(DevidedByMinusExceptione){System.out.println("programisrunninginto"+ "DevideByMinusException"); System.out.println(e.getMessage());System.out.println("thedevisoris"+e.getDevisor());}

catch(Exceptione){System.out.println("programisrunninginto"+ "otherunknownedException");System.out.println(e.getMessage());}System.out.println("programisrunninghere,that+isnormal!");}}运行结果:c.throw关键字Java是通过throw关键字抛出异常对象的,其语法格式如下:

throw异常对象在一个方法内部使用throw关键字抛出异常对象,如果该方法内部没有用try…catch对这个抛出的异常进行处理,则此方法应声明抛出异常,由该方法的调用者进行处理。classTest{

publicintdevide(intx,inty)throws

DevidedByMinusException,ArithmeticException

{

if(y<0)

thrownewDevidedByMinusException("除数为负",y);

intresult=x/y;

returnx/y;

}}

如果要在devide函数接收到的第二个参数为负数时,向该方法的调用者抛出用户自定义的DevidedByMinusException异常对象。则应对该方法作如下修改:运行结果:五.包SUN公司的JDK,系统软件开发商,开发工具商都会提供各种用途的类,如对这些类进行分门别类的使用和存放,则使用时将极度困难和不便,同时,也极易出现类的命名冲突。Java引入包(package)机制,提供类的多层类命名空间。看看下面的例子1.Package语句及应用packageorg.it315;publicclassTestPackage{publicstaticvoidmain(String[]args){ newTest().print();}}classTest{publicvoidprint(){System.out.println("theprogramis+ demostratinghowtousingpackage!");}}编译、运行结果为:

classpath设置一定是指向顶层包名所对应的对应的目录的父目录(如:d:\myjava),而不是指向.class文件所在的目录(d:\myjava\org\it315)。即使文件名都是TestPackage.class,但其包含的类的完整路径不一定相同,如:org.it315.TestPackage.class类与com.SUN.TestPackage.class类的文件名都是TestPackage.class,但却是两个完全不同的类。同一包中的类不必位于同样的目录,如org.it315.class1与org.it315.class2,完全可以一个位于c盘的某个位置,另一个位于d盘的一个位置,只要classpath分别指向这两个位置就可以了。有了包的概念,我们就可以理解java实际上是通过classpath去寻找顶层包名的原理了。在当前目录下,创建org\it315,将TestPackage.class与Test.class文件移动到org\it315目录中,执行命令:

d:\myjava\javaorg.it315.TestPackage

我们在编译时,让javac.exe来生成与包名层次相对应的目录结构,而不必像上面那样手动去创建,运行javac命令,它有一个选项–d,用于指定编译生成的.class文件存放的位置。点(.)代表当前目录。提示:类的名称是org.it315.TestPackage,而不是 TestPackage,即使找到TestPackage.class 文件,也不可能正常运行。课堂练习1.在命令行中进入org\it315目录中,运行javaTestPackage,结果会怎么样?2.还是在org\it315目录中,运行javaorg.it315.TestPackage,

结果又会怎么样?提示:假设classpath中只包含当前目录(不考虑其 它目录)的情况下,要运行完整名称为: org.it315.TestPackage的类,JVM会在当前目录 中查找子目录org\it315中的TestPackage文 件,当然找不到了。3.将TestPackage.java源文件中的packageorg.it315;语句注释掉,重新编译,将生成的.class文件放在d:\javawork\org\it315目录下,设置classpath环境变量包含d:\javawork目录,运行

javaorg.it315.TestPackage

结果又会怎么样?提示:不要认为把一个类放在某个目录下,这个目录就是该类的包名,不是有了目录结构就有了包名,包名必须在程序中通过package语句指定,而不是靠目录结构指定,是先要有包名后,才需要相应的目录结构。虽然d:\javawork目录中也包含org\it315子目录,但生成的文件中并不包含完整名为:org.it315.TestPackage的类。

有了包的概念,下来我们看不同包中的类是如何调用的。将刚才的TestPackage.java中的两个类放在不同的包中,用两个单独的.java源文件容纳这两个类,程序如下:程序一(源文件名为:TestPackage.java):

packageorg.it315;publicclassTestPackage{ publicstaticvoidmain(String[]args) { neworg.it315.example.Test().print(); }}2.import语句及应用程序二(源文件名为:Test.java):packageorg.it315.example;publicclassTest{publicvoidprint(){System.out.println("Programis"+

"

demostratinghowtousepackage!");}}编译、运行结果为:

每次用到类名是都要加前缀,如:

neworg.it315.example.Test()

显然有点繁琐。在java中使用import来简化这个问题。我们修改TestPackage.java源文件的代码如下所示,重新编译、运行,一切顺利。packageorg.it315;importorg.it315.example.*;publicclassTestPackage{publicstaticvoidmain(String[]args){ newTest().print();}}六.数组(一).一维数组1.声明数组数组是最简单的一种复合数据类型,其中每个元素具有相同的数据类型,包括复合数据类型和基本数据类型。

Pointp[];charc[];

inta[];=int[]a;

int[]a,b;≠inta[],b;

2.创建数组

用关键字new来创建:c=newchar[5];

(字符数组,5个字符型数据)c

0x1234

0000

0000

0000

0000

0000

5int[]x=newint[100];p=newPoint[3];

(Point类型数组,3个变量元素)

0x1245p[0]p[1]p[2]nullnull3nullp0,0nullnullp[2]=newPoint();0,0

对于类类型,每个元素并没有指向一个

具体的Point对象,还必须分别创建:0,00x1245p[0]p[1]p[2]3

pp[0]=newPoint();p[1]=newPoint();null0x2464

nullnull0x24660x2468声明、创建一步完成:

inta[]=newint[3];

a0x45670003a[0]a[1]a[2]length声明、创建一步完成:

inta[]=newint[3];

a0x45670003a[0]a[1]a[2]length3.初始化数组

当创建一个数组时,每个元素都已自动初始化.

手工初始化的方法是:inta[]={1,2,3,4,5};或:

inta[]=newint[]{

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论