版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章继承与接口4.1继承 4.2接口4.3特殊类4.1继承4.1.1继承的含义4.1.2子类的继承性的访问控制4.1.3子类对象的构造过程4.1.4子类的内存分布4.1.5子类对象的成员初始化4.1.6成员变量的隐藏4.1.7方法的重载与方法的覆盖4.1.8this关键字4.1.9super关键字4.1.10对象的上、下转型对象4.1.1继承的含义类之间的继承关系是客观事物之间遗传关系的直接模拟,它反映了类之间的内在联系以及对属性和方法的共享,即子类可以沿用父类(被继承类)的某些特征。当然,子类也可以具有自己独立的属性和操作。例如,飞机、汽车和火车属于交通工具类,汽车类可以继承交通工具类某些属性和方法。4.1.1继承的含义Java中继承实际上是一种基于已有的类创建新类的机制,是软件代码复用的一种形式。利用继承,我们首先创建一个共有属性和方法的一般类(父类或超类),然后基于该一般类再创建具有特殊属性和方法的新类(子类),新类继承一般类的状态和方法,并根据需要增加它自己的新的状态和行为。父类可以是自己编写的类也可以是java类库中的类。Java不支持多重继承,即子类只能有一个父类。4.1.1继承的含义如果要声明类B继承类A,则必须满足两个条件:(1)类A非final;(2)类A是public或类B与类A同包。如果这两个条件满足则可按照以下的语法声明类B:classBextendsA{…..}
这两声明表明B是A的子类,A是B的父类。4.1.1继承的含义People{ floatheight,weight,age;//身高,体重,年龄
……}classStudentsextendsPeople{ Stringstdno;//学号……}说明:本实例中,类Students是类People的子类。classAnimal{publicfloatweight;publicvoideat(){…}}classMammalextendsAnimal{publicint
heartRate;publicvoidbreath(){…}}classCatextendsMammal{
boolean
longHair;publicvoidpurr(){…}}说明:本实例中,类Mammal是类Animal的子类,类Cat又是类Mammal的子类。4.1.2子类的继承性的访问控制子类是基于父类创建的新类,它继承了父类的某些属性和方法,同时可以增添新的属性和方法。Java中子类不能访问父类的private成员,但可以访问其父类的public成员。父类的属性或方法使用其他访问控制符修饰时,子类对父类的属性或方法的继承将受到一定的限制。4.1.2子类的继承性的访问控制1.子类和父类在同一包中的继承性当子类和父类处在同一个包中时,子类可继承了其父类中不是private的成员变量和方法。继承的成员变量以及方法的访问权限保持不变。2.子类和父类不在同一包中的继承性当子类和父类不在同一个包中时,子类只能继承父类的protected、public成员变量和方法,不能继承父类的友好变量和友好方法。继承的成员或方法的访问权限不变。3.子类对父类私有属性或方法的访问子类不能直接访问从父类中继承的私有属性及方法,但可以使用公有(及保护)方法进行访问。classA{publicinta=4;privateintb=5;protectedintc=6;publicintoutputB(){returnb;}}publicclassBextendsA{ publicintd; publicstaticvoidmain(Stringargs[]){Bb=newB(); ba.testVisitControl(); } publicvoidtestVisitControl(){System.out.println(a);//允许System.out.println(b);//不允许System.out.println(outputB());//允许System.out.println(c);//允许}}说明:(1)子类B和父类A在同一包中;(2)子类B能继承父类的public型属性a和protected属性c,因此操作System.out.println(a);和System.out.println(c);是符合逻辑的。(3)子类B不能继承父类的private型属性b,因此对在B中未作任何申明的变量b的操作System.out.println(b);是不允许的。(4)子类B不能继承父类的private型属性b,但可以通过公共方法对b进行访问,System.out.println(outputB());是符合逻辑的。4.1.3子类对象的构造过程Java语言中,使用构造方法来构造并初始化对象。当用子类的构造方法创建一个子类的对象时,子类构造函数总是先调用(显式的或隐式地)其父类的某个构造函数,以创建和初始化子类的父类成员。如果子类的构造方法没有指明使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法。然后执行子类构造函数。4.1.3子类对象的构造过程子类对象的构造过程为:(1)将子类中声明的成员变量或方法做为子类对象的成员变量或方法。(2)将从父类继承的父类的成员变量或方法做为子类对象的成员变量或方法。值得指出的是,尽管子类对象的构造过程中,子类只继承了父类的部分成员变量或方法。但在分配内存空间时,所有父类的成员都分配了内存空间。4.1.4子类的内存分布在JVM中类被表示为一块内存区域,分别存放类名和类的静态成员,可以用如图4-1(a)表示:【实例4-5】classA{staticintsvar1=10;staticintsvar2=20;staticvoidsfun1(){…}
intvar1=1;
intvar2=2;voidfun1(){…}}类A的内存映像如图4-1(b)ClassNamestaticvar1staticfun1……staticvarNstaticfunM类名属性区方法区……图4-1类的内存映像示意图Asvar2sfun120…………svar110(a)(b)4.1.4子类的内存分布在JVM中对象也被表示为一块内存区域,分别存放到对象所属类的引用和对象的成员,可以用图4-2(a)表示:【实例4-6】Aref1=newA();Aref2=ref1;对象ref1和ref2的内存映像如图4-2(b)所示。:ClassRefvar1fun1……varPfunQ类的引用属性区方法区……图4-2对象的内存映像示意图ref1ref2A:Avar2fun12…………var11(a)(b)4.1.4子类的内存分布【实例4-7】classBextendsA{staticintsvar2=30;
intvar2=3;voidfun1(){…}}Aref1=newA();Bref2=newB();ref1=ref2;对象ref1和ref2的内存映像如图4-3所示。ref1ref2BA/svar2sfun120…………A/svar110B/svar230AA/svar2sfun120…………A/svar110:BA/var2fun12…………A/var11B/var23:Avar2fun12…………var11图4-3对象的内存映像示意图4.1.5子类对象的成员初始化初始化规定及分类子类对象的成员初始化之前必须完成父类或祖先类对象的成员的初始化,初始化的方式有两种:隐式初始化和显式初始化。1.隐式初始化当父类提供了默认的构造函数,且子类的构造函数中没有显式调用父类的其它构造函数,则在执行子类的构造函数之前会自动执行父类的构造函数,直到执行完Object的构造函数后才执行子类的构造函数。4.1.5子类对象的成员初始化【实例4-8】classA{
intx;A(){x=1;}}classBextendsA{
inty;B(){y=-1;}}Brb=newB();子类对象rb的隐式初始化过程如图4-4所示。ConstructorsinSubclassesnewB()AObjectx=1;……y=-1;y=0;x=0;调用A()调用Object()返回返回图4-4子类对象的隐式初始化4.1.5子类对象的成员初始化2.显式初始化可以在子类构造函数的第一条语句通过super()或super(…)调用父类的默认构造函数或特定签名的构造函数。当父类没有提供默认构造函数时,即父类定义的构造函数都是有参的,则必须在子类构造函数第一条语句通过super(…)完成父类对象成员的初始化工作。4.1.5子类对象的成员初始化【实例4-9】classpoint{privateintx,y;
point(intx,inty){
this.x=x;this.y=y;}}classcircleextendspoint{
intradius;
circle(intr){ radius=r;}}4.1.5子类对象的成员初始化说明:在本实例中,构造方法circle(intr)存在错误,可作如下改正。classcircleextendspoint{
intradius;
circle(intr,intx,inty){
super(x,y); radius=r;}}4.1.6成员变量的隐藏当在子类中定义与父类中同名的成员变量时,子类就隐藏了继承的成员变量,即子类对象以及子类自己声明定义的方法操作与父类同名的成员变量。【实例4-10】classA{protecteddoubley=2.13;}classBextendsA{inty=0;voidg(){ y=y+10; System.out.printf("y=%d\n",y);}}classExample{publicstaticvoidmain(Stringargs[]){Bb=newB();b.y=-20;b.g();}}4.1.6成员变量的隐藏说明:在本实例中,子类B定义了整型成员变量y,隐藏了从父类A继承的double型变量y。该程序的运行结果如下:y=-104.1.7方法的重载与方法的覆盖1.方法重载方法重载是在一个类中定义二个或多个同名的方法,但方法的参数个数或类型不完全相同;例如:【实例4-11】classpoint{
intx,y;
point(inta,intb){x=a;y=b; } point(){ x=-1;y=-1;}}4.1.7方法的重载与方法的覆盖说明:在本实例中,定义了两个名称均为point的构造方法,在需要使用point构造方法时,可通过参数个数来识别不同的构造方法。注意事项:方法重载的一个误区是靠返回值区别重载,即定义多个方法,它们的名称和形参类型完全相同,但返回值不同,这是不允许的。【实例4-12】classA{
intx,y;
int
show(int
a){a=a*2;returna; } doubleshow(int
b){b=b*4;returnb; }}publicclassreloadingExample{ publicstaticvoidmain(Stringargs[]){ Aa=newA();
inti=1; doubled=1.0;
System.out.println("intshow()="+a.show(i));
System.out.println("doubleshow()="+a.show(i));}}4.1.7方法的重载与方法的覆盖4.1.7方法的重载与方法的覆盖2.方法覆盖方法的覆盖发生在父类和子类之间,若子类中定义的某个方法的特征,与父类中定义的某个方法的特征完全一样,那么就说子类中的这个方法覆盖了父类对应的那个方法。
3.方法重载与方法覆盖的区别重载可以出现在一个类中,也可以出现在父类与子类的继承关系中,并且重载方法的特征一定不完全相同。覆盖则要求子类中的方法特征与父类定义的对应方法的特征完全一样,即这个方法的名字、返回类型、参数个数和类型与从父类继承的方法完全相同。例如:【实例4-13】classpoint{
intx,y; point(){ this(0,0); }
point(intx,inty){
this.x=x;
this.y=y; } doublearea(){ return0; }}
classcircleextendspoint{
intradius;
circle(intr,intx,inty){
super(x,y); radius=r; }doublearea(){ returnMath.PI*radius*radius; }}4.1.7方法的重载与方法的覆盖说明:在本实例中,子类circle中的方法area()和父类point中的方法area()的特征相同,故子类的方法覆盖父类的方法。【实例4-14】classpoint{
intx,y; point(){ this(0,0); }
point(intx,inty){
this.x=x;
this.y=y; } doublearea(){ return0; }}
classcircleextendspoint{
intradius;
circle(intr,intx,inty){
super(x,y); radius=r; }doublearea(floatz){ returnMath.PI*radius*radius; }}4.1.7方法的重载与方法的覆盖说明:在本实例中,子类circle中的方法area()和父类point中的方法area()的特征不相同,父类point中的方法area()含参数z,故子类的方法未能覆盖父类的方法,这时子类就出现两个方法具有相同的名字。4.1.8this关键字基本使用说明:this只能用于与实例有关的代码块中,如实例方法、构造方法、实例初始化代码块或实例变量的初始化代码块等,this就代表当前或者正在创建的实例对象的引用,通常可以利用这一关键字实现与局部变量同名的实例变量的调用。在构造方法中还可以用this来代表要显式调用的其它构造方法。除此以外,使用this关键字都将引发编译时错误。4.1.8this关键字1.在类的构造方法中使用this关键字在构造方法内部使用this,代表使用该构造方法所创建的对象。【实例4-15】classTom{
intn;
Tom(intx){
this.show(); n=x;
this.show();}voidshow(){
System.out.println("n="+n);}publicstaticvoidmain(String
args[]){Tomtom=newTom(10);}}4.1.8this关键字说明:在本实例中,构造方法Tom(intx)中出现了this,表示该对象在构造自己时调用了方法show()。运行结果为:n=0n=104.1.8this关键字此外,在构造方法内部使用this,可用于指代另外一个构造函数,但不能指代非构造函数。例如:【实例4-16】classpoint{
intx,y; point(){ this(-1,-1); }
point(inta,intb){ x=a; y=b; }}说明:在本实例中,构造方法point()中的 this指代构造方法point(inta,intb)。4.1.8this关键字2.在类的实例方法中使用this关键字在实例方法内部使用this,代表使用该方法的当前对象。【实例4-17】classA{
intx; voidfun(){
this.x=10;
this.g(this.x); } voidg(intx){
System.out.println("x="+x);}}classex1{publicstaticvoidmain(String
args[]){ Aa=newA();
a.fun();}}4.1.8this关键字说明:在本实例中,实例方法fun中出现了this,this就代表使用fun的当前对象。因此,this.x表示当前对象的变量x,将10赋给该对象的变量x。this.g表示当前对象的方法g时,传递参数为this.x。通常情况下,可以省略成员变量(或方法)名字前面的“this.”。4.1.8this关键字3.使用this区分成员变量和局部变量如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。这时如果想在该方法内使用成员变量,成员变量前面的“this.”就不可以省略,如:【实例4-18】classpoint{
intx,y; voidinit(intx,inty){
this.x=x;
this.y=y; }}说明:在本实例中,this.x和this.y是指类point的属性变量x和y,语句“this.x=x;”和“this.y=y;”等号右边的x和y则是和方法init()的形参x和y。4.1.9super关键字super只能用于与实例有关的代码块中,如实例方法、构造方法、实例初始化代码块或实例变量的初始化代码块等,super代表当前或者正在创建的实例对象的父类,通常可以利用这一关键字实现对父类同名属性或方法的调用。在构造方法中还可以用super来代表要调用的父类构造方法,以实现构造方法链的初始化。由于Object类为Java语言的根类,已经没有父类,因此,如果在Object类中使用了关键字super,将引发编译时错误。4.1.9super关键字1.使用super调用父类的构造方法子类不继承父类的构造方法,因此,子类如果想使用父类的构造方法,必须在子类的构造方法中使用并且必须使用关键字super来表示,而且super必须是子类构造方法中的第一条语句。这点在子类对象的构造过程一节已举例说明,在此不在赘述。2.使用super操作被隐藏的成员变量和方法如果在子类中想使用被子类隐藏的成员变量或方法就可以使用关键字super。【实例4-19】classA{
intx=2,y=3;doubleadd(){returnx+y;}}classBextendsA{
intx=20,y=30; doubleadd(){returnsuper.x+super.y;} doubleaddB(){returnx+y;} doubleaddA(){returnsuper.add();}}【实例4-19】classex2{publicstaticvoidmain(String
args[]){Aa=newA();Bb=newB();
System.out.println("b.add="+b.addB());
System.out.println("a.add="+a.add());
System.out.println("a.add="+b.addA());}}4.1.9super关键字说明:在本实例中,子类B使用super.x和super.y调用父类A被隐藏的成员变量x和y,使用super.add()调用父类A被隐藏的方法add()。其结果如下:b.add=50a.add=5a.add=54.1.10对象的上、下转型对象1.向上转型向上转型是指将子类类型的引用赋值给其父类或祖先类类型的引用,赋值操作中包含了隐式的类型转换。Objectobj1=newString(“good”);//对象的上转型Objectobj2=newInteger(100);//对象的上转型例如,类B是类A的子类。Aa;Bb=newB();a=b;4.1.10对象的上、下转型对象此时称对象a是子类对象b的上转型对象,对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。上转型对象不能操作子类声明定义的成员变量;也不能使用子类声明定义的方法。上转型对象可以操作子类继承的成员变量和隐藏的成员变量,也可以使用子类继承的或重写的方法。上转型对象不能操作子类新增的方法和成员变量。将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类所有属性和功能。4.1.10对象的上、下转型对象2.向下转型向下转换是指将某类类型的引用赋值给其子类类型的引用,赋值操作必须进行显式(强制)的类型转换。Stringstr1=(String)obj1;//对象的下转型Integerint1=(Integer)obj2;//对象的下转型4.2接口4.2.1abstract类4.2.2接口的含义4.2.3接口回调4.2.4接口与抽象类的异同4.2.1abstract类用关键字abstract修饰类称为abstract类(抽象类)。如:
abstractclassA{……}abstract类不能用new运算符创建对象,必须产生其子类,由子类创建对象。若abstract类的类体中有abstract方法,只允许声明,而不允许实现,而该类的子类必须实现abstract方法,即重写父类的abstract方法。一个abstract类只关心子类是否具有某种功能,不关心功能的具体实现。具体实现由子类负责。因此,抽象类的唯一目的是为子类提供公有信息,它是用来被继承的,抽象类不能创建对象。4.2.2接口的含义Java不支持多继承性,即一个类只能有一个父类。单继承性使得Java简单,易于管理程序。为了克服单继承的缺点,Java使用了接口,一个类可以实现多个接口。使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口的声明和接口体。4.2.2接口的含义1.接口的声明声明接口的语法如下:<修饰符>interface<接口名>//接口声明{…接口体…}接口名的命名规范与类相同,接口也可以指定所属的包。接口的修饰符可以有以下几种:(1)public:与类的public修饰符相同;
(2)abstract:通常被省略,因为接口中的方法都是抽象的;(3)strictfp:通常并不能限制接口中方法的实现,一般不使用。4.2.2接口的含义2.接口体 接口体中包含常量定义和方法定义两部分。(1)接口中的成员都是public的,不能指定其它的访问控制修饰符。(2)常量定义。接口中属性的域默认是staticfinal的,必须显式初始化。(3)方法。只能提供方法头声明,不能提供实现,且除abstract外,不能使用其它修饰符。接口中的方法被默认是public和abstract的,接口在声明方法时可以省略方法前面的public和abstract关键字,但是,类在实现接口方法时,一定要用public来修饰。(4)嵌套类和嵌套接口;4.2.2接口的含义3.接口的多继承接口支持多亲继承,可以在关键字extends后面跟多个接口的列表,中间用逗号隔开,如:publicinterfaceSerializableRunnableextends,Runnable{……}子接口拥有所有父接口中声明的方法。子接口中的域将隐藏父接口中声明的同名域,被隐藏的父接口中的域必须通过父接口名访问。子接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要。实现接口的类也必须实现此接口的父接口。4.2.2接口的含义4.接口的使用一个类通过使用关键字implements声明自己实现一个或多个接口。如果实现多个接口,用逗号隔开接口名,如:classAimplementsPrintable,Addable如果一个类实现某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。类实现的接口方法以及接口中的常量可以被类的对象调用。如果父类实现了某个接口,则其子类也就自然实现这个接口。接口也可以被继承,即可以通过关键字extends声明一个接口是另一个接口的子接口。以下例子给出了类是如何实现接口的。【实例4-21】interfaceC{publicabstractint
fun(int
x,inty);}classAimplementsC{publicint
fun(int
x,inty){return2*(x+y);}}classBimplementsC{publicint
fun(int
x,int
y){returnx*y;}}publicclassExample{publicstaticvoidmain(String
args[]){Aa=newA();Bb=newB();System.out.println("长方形周长="+a.fun(12,8));System.out.println("长方形面积="+b.fun(12,8));}}4.2.2接口的含义说明:在本实例中,接口C中方法fun()分别在类A和B中实现。类A方法fun()功能是计算长方形的周长。类B方法fun()功能是计算长方形的面积。4.2.3接口回调接口回调是指把使用某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类实现的接口中的方法,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称作对象功能的接口回调。不同的类在使用同一接口时,可能具有不同的功能体现,即接口的方法体不必相同,因此,接口回调可能产生不同的行为。【实例4-22】interfaceShowMessage{voidshow(Strings);//接口中的方法默认都是public}classCarimplementsShowMessage{ publicvoidshow(Strings){//在使用接口的类中要显示表示public
System.out.println("Car="+s); }}classBicycleimplementsShowMessage{ publicvoidshow(Strings){//在使用接口的类中要显示表示public
System.out.println("Bicycle="+s); }}【实例4-22】publicclassinterfacecallbackExample{publicstaticvoidmain(String
args[]){
ShowMessagedm;//声明接口变量 dm=newCar();//接口变量中存放对象的引用
dm.show("奔驰");//接口回调 dm=newBicycle();//接口变量中存放对象的引用
dm.show("捷安特");//接口回调 }}4.2.3接口回调运行结果为:Car=奔驰Bicycle=捷安特说明:在本实例中,(1)ShowMessage为接口,类Car和Bicycle使用接口ShowMessage,分别实现接口中的方法show。(2)类interfacecallbackExample中,语句执行“dm=newCar();”或“dm=newBicycle();”后将对对象的引用存放在接口变量dm中。4.2.4接口与抽象类的异同接口和抽象类的相同点:(1)都有空的方法,都必须在子类中实现这些方法。(2)都不能用new关键字来创建这两种类型的对象。(3)都可以具有继承关系。(4)接口和类一样可以具有public属性。4.2.4接口与抽象类的异同接口和抽象类的不同点:(1)在抽象类中,空的方法必须加abstract关键字,而在接口中不需要。(2)在抽象类中,除空的方法外,可以定义实例变量和非空的方法,而在接口中,只能定义常量和空的方法。(3)接口允许多继承,类仅支持单继承。4.3特殊类4.3.1final类 1314.3.2内部类 1324.3.1final类final类不能被继承,即不能有子类,如:
finalclassA{…}将一个类声明为final类一般是由于安全性考虑。声明ChessAlgorithm类为final类finalclassChessAlgorithm{...}4.3.1final类如果写下如下程序:classBetterChessAlgorithmextend
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 孤残儿童护理员安全生产基础知识模拟考核试卷含答案
- 苏教版科学一年级下册第1课捡石头教学设计
- 中药露剂工安全宣传模拟考核试卷含答案
- 平版制版员安全风险评优考核试卷含答案
- 抗生素酶裂解工班组安全测试考核试卷含答案
- 2025年模具设计培训课件
- 2025年辽宁省公需课学习-体育强国建设纲要解读737
- 八纲辨证护理在内科的应用
- 2026年红十字会事业发展中心招聘笔试试题及答案
- 护理岗位的专业发展
- 微型消防站物资器材配置一览表
- 提名辽宁自然科学奖
- 刑法学(上册)马工程课件 第2章 刑法的基本原则
- GB/T 26955-2011金属材料焊缝破坏性试验焊缝宏观和微观检验
- GB/T 1508-2002锰矿石全铁含量的测定重铬酸钾滴定法和邻菲啰啉分光光度法
- 大学物理绪论
- 1财政与金融-财政学导论
- 国内外渔人码头案例分析
- 化工企业安全标准化管理制度
- 人音版初中音乐☆游击队歌课件
- 义务教育(数学)新课程标准(2022年修订版)
评论
0/150
提交评论