《B04继承与接口-1课件.ppt》由会员分享,可在线阅读,更多相关《B04继承与接口-1课件.ppt(80页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第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.8 this关键字4.1.9 super关键字4.1.10 对象的上、下转型对象4.1.1 继承的含义继承的含义类之间的继承关系是客观事物之间遗传关系的直类之间的继承关系是客观事物之间遗传关系的直接模拟,它反映了类之间的内在联系以及对属性接模拟,它反映了类之间的内在联系以及对属性和方法的共享,即子类可
2、以沿用父类(被继承类)和方法的共享,即子类可以沿用父类(被继承类)的某些特征。当然,子类也可以具有自己独立的的某些特征。当然,子类也可以具有自己独立的属性和操作。例如,飞机、汽车和火车属于交通属性和操作。例如,飞机、汽车和火车属于交通工具类,汽车类可以继承交通工具类某些属性和工具类,汽车类可以继承交通工具类某些属性和方法。方法。4.1.1 继承的含义继承的含义JavaJava中继承实际上是一种基于已有的类创建新类的机制,中继承实际上是一种基于已有的类创建新类的机制,是软件代码复用的一种形式。利用继承,我们首先创建一是软件代码复用的一种形式。利用继承,我们首先创建一个共有属性和方法的一般类(父类
3、或超类),然后基于该个共有属性和方法的一般类(父类或超类),然后基于该一般类再创建具有特殊属性和方法的新类(子类),新类一般类再创建具有特殊属性和方法的新类(子类),新类继承一般类的状态和方法,并根据需要增加它自己的新的继承一般类的状态和方法,并根据需要增加它自己的新的状态和行为。状态和行为。父类可以是自己编写的类也可以是父类可以是自己编写的类也可以是javajava类库中的类。类库中的类。JavaJava不支持多重继承,即子类只能有一个父类。不支持多重继承,即子类只能有一个父类。4.1.1 继承的含义继承的含义如果要声明类如果要声明类B B继承类继承类A A,则必须满足两个条件:,则必须满足
4、两个条件:(1) (1) 类类A A非非final final ;(2) (2) 类类A A是是publicpublic或类或类B B与类与类A A同包。如果这同包。如果这两个条件满足则可按照以下的语法声明类两个条件满足则可按照以下的语法声明类B B:class B extends A class B extends A . . 这两声明表明这两声明表明B B是是A A的子类,的子类,A A是是B B的父类。的父类。4.1.1 继承的含义继承的含义People People float height,weight,age; /float height,weight,age; /身高,体重,年龄
5、身高,体重,年龄 class Students extends Peopleclass Students extends PeopleString stdno; /String stdno; /学号学号 说明:本实例中,类说明:本实例中,类StudentsStudents是类是类PeoplePeople的子类。的子类。class Animalclass Animal public float weight; public float weight; public void eat() public void eat() class Mammal extends Animalclass Mamm
6、al extends Animal public int heartRate; public int heartRate; public void breath() public void breath() class Cat extends Mammalclass Cat extends Mammal boolean longHair; boolean longHair; public void purr() public void purr() 说明:本实例中,类说明:本实例中,类MammalMammal是类是类AnimalAnimal的子类,类的子类,类CatCat又是类又是类Mamma
7、lMammal的子类。的子类。4.1.2 子类的继承性的访问控制子类的继承性的访问控制子类是基于父类创建的新类,它继承了父类的某子类是基于父类创建的新类,它继承了父类的某些属性和方法,同时可以增添新的属性和方法。些属性和方法,同时可以增添新的属性和方法。JavaJava中子类不能访问父类的中子类不能访问父类的privateprivate成员,但可成员,但可以访问其父类的以访问其父类的publicpublic成员。父类的属性或方法成员。父类的属性或方法使用其他访问控制符修饰时,子类对父类的属性使用其他访问控制符修饰时,子类对父类的属性或方法的继承将受到一定的限制或方法的继承将受到一定的限制。4.
8、1.2 子类的继承性的访问控制子类的继承性的访问控制1子类和父类在同一包中的继承性当子类和父类处在同一个包中时,子类可继承了其父类中不是当子类和父类处在同一个包中时,子类可继承了其父类中不是privateprivate的成员变量和方法。继承的成员变量以及方法的访问权限的成员变量和方法。继承的成员变量以及方法的访问权限保持不变。保持不变。2子类和父类不在同一包中的继承性当子类和父类不在同一个包中时,子类只能继承父类的当子类和父类不在同一个包中时,子类只能继承父类的protectedprotected、publicpublic成员变量和方法,不能继承父类的友好变量成员变量和方法,不能继承父类的友好
9、变量和友好方法。继承的成员或方法的访问权限不变。和友好方法。继承的成员或方法的访问权限不变。3子类对父类私有属性或方法的访问子类不能直接访问从父类中继承的私有属性及方法,但可以使用子类不能直接访问从父类中继承的私有属性及方法,但可以使用公有(及保护)方法进行访问。公有(及保护)方法进行访问。class A public int a = 4; private int b = 5; protected int c = 6; public int outputB() return b; public class B extends A public int d; public static void
10、 main (String args ) B b=new B();ba. testVisitControl ();public void testVisitControl () 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.pr
11、intln(c);是符合逻辑的。(3)子类B不能继承父类的private型属性b,因此对在B中未作任何申明的变量b的操作System.out.println(b);是不允许的。(4)子类B不能继承父类的private型属性b,但可以通过公共方法对b进行访问,System.out.println(outputB();是符合逻辑的。4.1.3 子类对象的构造过程子类对象的构造过程Java语言中,使用构造方法来构造并初始化对象。当用子类的构造方法创建一个子类的对象时,子类构造函数总是先调用(显式的或隐式地)其父类的某个构造函数,以创建和初始化子类的父类成员。如果子类的构造方法没有指明使用父类的哪个构
12、造方法,子类就调用父类的不带参数的构造方法。然后执行子类构造函数。4.1.3 子类对象的构造过程子类对象的构造过程子类对象的构造过程为:(1 1)将子类中声明的成员变量或方法做为子类对象的)将子类中声明的成员变量或方法做为子类对象的成员变量或方法。成员变量或方法。 (2 2)将从父类继承的父类的成员变量或方法做为子类)将从父类继承的父类的成员变量或方法做为子类对象的成员变量或方法。对象的成员变量或方法。值得指出的是,尽管子类对象的构造过程中,子类只值得指出的是,尽管子类对象的构造过程中,子类只继承了父类的部分成员变量或方法。但在分配内存空继承了父类的部分成员变量或方法。但在分配内存空间时,所有
13、父类的成员都分配了内存空间。间时,所有父类的成员都分配了内存空间。4.1.4 子类的内存分布子类的内存分布在在JVMJVM中类被表示为一块内存区域,分别存放类名和类的静态成员,中类被表示为一块内存区域,分别存放类名和类的静态成员,可以用如图可以用如图4-1(a)4-1(a)表示:表示:【实例实例4-54-5】class Aclass A static int svar1=10; static int svar1=10; static int svar2=20; static int svar2=20; static void sfun1() static void sfun1() int va
14、r1=1;int var1=1; int var2=2;int var2=2;void fun1()void fun1() 1.1.类类A A的内存映像如图的内存映像如图4-1(b)4-1(b)ClassNamestatic var1static fun1static varNstatic funM类名类名属属性性区区方方法法区区图图4-1 类的内存映像示意图类的内存映像示意图Asvar2sfun120svar110(a)(b)4.1.4 子类的内存分布子类的内存分布在在JVMJVM中对象也被表示为一块内存区域,分别存放到对象中对象也被表示为一块内存区域,分别存放到对象所属类的引用和对象的成员
15、,可以用图所属类的引用和对象的成员,可以用图4-2(a)4-2(a)表示:表示:【实例实例4-64-6】A ref1=new A();A ref1=new A();A ref2= ref 1;A ref2= ref 1;1.1.对象对象ref1ref1和和ref2ref2的内存映像如图的内存映像如图4-2(b)4-2(b)所示。所示。:ClassRefvar1fun1varPfunQ类的引用类的引用属属性性区区方方法法区区图图4-2 对象的内存映像示意图对象的内存映像示意图ref1ref2A:Avar2fun12var11(a)(b)4.1.4 子类的内存分布子类的内存分布【实例实例4-74-
16、7】class B extends Aclass B extends A static int svar2=30; static int svar2=30; int var2=3; int var2=3; void fun1() void fun1() A ref1=new A();A ref1=new A();B ref2=new B();B ref2=new B();ref1=ref2;ref1=ref2;1.1.对象对象ref1ref1和和ref2ref2的内存映像如图的内存映像如图4-34-3所示。所示。ref1ref2BA/svar2sfun120A/svar110B/svar230
17、AA/svar2sfun120A/svar110:BA/var2fun12A/var11B/var23:Avar2fun12var11图图4-3 对象的内存映像示意图对象的内存映像示意图4.1.5 子类对象的成员初始化子类对象的成员初始化初始化规定及分类子类对象的成员初始化之前必须完成父类或祖先类对子类对象的成员初始化之前必须完成父类或祖先类对象的成员的初始化,初始化的方式有两种:隐式初始象的成员的初始化,初始化的方式有两种:隐式初始化和显式初始化。化和显式初始化。1隐式初始化当父类提供了默认的构造函数,且子类的构造函数中当父类提供了默认的构造函数,且子类的构造函数中没有显式调用父类的其它构造
18、函数,则在执行子类的没有显式调用父类的其它构造函数,则在执行子类的构造函数之前会自动执行父类的构造函数,直到执行构造函数之前会自动执行父类的构造函数,直到执行完完ObjectObject的构造函数后才执行子类的构造函数。的构造函数后才执行子类的构造函数。4.1.5 子类对象的成员初始化子类对象的成员初始化【实例4-8】class A int x; A() x=1; class B extends A int y; B() y=-1; B rb=new B();1.子类对象rb的隐式初始化过程如图4-4所示。Constructors in Subclassesnew B()AObjectx=1;
19、y=-1;y=0;x=0;调用调用A()调用调用Object()返回返回返回返回图图4-4 子类对象的隐式初始化子类对象的隐式初始化4.1.5 子类对象的成员初始化子类对象的成员初始化2显式初始化可以在子类构造函数的第一条语句通过可以在子类构造函数的第一条语句通过super()super()或或super()super()调用父类的默认构造函数或特定签名的构造调用父类的默认构造函数或特定签名的构造函数。函数。当父类没有提供默认构造函数时,即父类定义的构造当父类没有提供默认构造函数时,即父类定义的构造函数都是有参的,则必须在子类构造函数第一条语句函数都是有参的,则必须在子类构造函数第一条语句通过
20、通过super()super()完成父类对象成员的初始化工作。完成父类对象成员的初始化工作。4.1.5 子类对象的成员初始化子类对象的成员初始化【实例4-9】class point private int x, y; point(int x, int y) this.x=x; this.y=y; class circle extends point int radius; circle(int r) radius=r; 1.4.1.5 子类对象的成员初始化子类对象的成员初始化说明:在本实例中,构造方法circle(int r)存在错误,可作如下改正。class circle extends p
21、oint int radius; circle(int r, int x, int y) super(x, y); radius=r; 1.4.1.6 成员变量的隐藏成员变量的隐藏当在子类中定义与父类中同名的成员变量时,子类就隐藏了继承的成员变量,即子类对象以及子类自己声明定义的方法操作与父类同名的成员变量。【实例4-10】class A protected double y=2.13;class B extends A int y=0; void g() y=y+10; System.out.printf(y=%dn,y); class Example public static void
22、main(String args ) B b=new B(); b.y=-20; b.g(); 1. 4.1.6 成员变量的隐藏成员变量的隐藏说明:在本实例中,子类在本实例中,子类B B定义了整型成员变量定义了整型成员变量y y,隐藏了从,隐藏了从父类父类A A继承的继承的doubledouble型变量型变量y y。该程序的运行结果如下:。该程序的运行结果如下:y y10104.1.7 方法的重载与方法的覆盖方法的重载与方法的覆盖1方法重载 方法重载是在一个类中定义二个或多个同名的方法,方法重载是在一个类中定义二个或多个同名的方法,但方法的参数个数或类型不完全相同;例如:但方法的参数个数或类型
23、不完全相同;例如:【实例4-11】class point int x, y; point(int a, int b) x=a; y=b; point( )x=-1; y=-1; 1.4.1.7 方法的重载与方法的覆盖方法的重载与方法的覆盖说明: 在本实例中,定义了两个名称均为在本实例中,定义了两个名称均为pointpoint的构造方法,的构造方法,在需要使用在需要使用pointpoint构造方法时,可通过参数个数来识构造方法时,可通过参数个数来识别不同的构造方法。别不同的构造方法。注意事项: 方法重载的一个误区是靠返回值区别重载,即定义多方法重载的一个误区是靠返回值区别重载,即定义多个方法,它
24、们的名称和形参类型完全相同,但返回值个方法,它们的名称和形参类型完全相同,但返回值不同,这是不允许的。不同,这是不允许的。【实例4-12】class A int x, y; int show(int a)a=a*2;return a; double show(int b)b=b*4;return b; public class reloadingExample public static void main (String args ) A a=new A();int i=1;double d=1.0;System.out.println(int show()=+a.show(i);Syste
25、m.out.println(double show()=+a.show(i); 1.4.1.7 方法的重载与方法的覆盖方法的重载与方法的覆盖4.1.7 方法的重载与方法的覆盖方法的重载与方法的覆盖 2方法覆盖 方法的覆盖发生在父类和子类之间,若子类中定义的某个方法的方法的覆盖发生在父类和子类之间,若子类中定义的某个方法的特征,与父类中定义的某个方法的特征完全一样,那么就说子类特征,与父类中定义的某个方法的特征完全一样,那么就说子类中的这个方法覆盖了父类对应的那个方法。中的这个方法覆盖了父类对应的那个方法。 3方法重载与方法覆盖的区别 重载可以出现在一个类中,也可以出现在父类与子类的继承关系重载
26、可以出现在一个类中,也可以出现在父类与子类的继承关系中,并且重载方法的特征一定不完全相同。中,并且重载方法的特征一定不完全相同。 覆盖则要求子类中的方法特征与父类定义的对应方法的特征完全覆盖则要求子类中的方法特征与父类定义的对应方法的特征完全一样,即这个方法的名字、返回类型、参数个数和类型与从父类一样,即这个方法的名字、返回类型、参数个数和类型与从父类继承的方法完全相同。例如:继承的方法完全相同。例如: 【实例4-13】class point int x, y; point( )this(0,0); point(int x, int y)this.x=x;this.y=y; double ar
27、ea( )return 0; 1. class circle extends point int radius; circle(int r, int x, int y)super(x, y);radius=r; double area( ) return Math.PI*radius*radius ; 4.1.7 方法的重载与方法的覆盖方法的重载与方法的覆盖 说明: 在本实例中,子类在本实例中,子类circlecircle中的方法中的方法area( )area( )和父类和父类pointpoint中的方法中的方法area( )area( )的特征相同,故子类的方法覆的特征相同,故子类的方法覆盖
28、父类的方法。盖父类的方法。 【实例4-14】class point int x, y; point( )this(0,0); point(int x, int y)this.x=x; this.y=y; double area( )return 0; 1. class circle extends point int radius; circle(int r, int x, int y)super(x, y);radius=r; double area(float z )return Math.PI*radius*radius ; 4.1.7 方法的重载与方法的覆盖方法的重载与方法的覆盖说明:
29、 在本实例中,子类在本实例中,子类circlecircle中的方法中的方法area( )area( )和父类和父类pointpoint中的方法中的方法area( )area( )的特征不相同,父类的特征不相同,父类pointpoint中中的方法的方法area( )area( )含参数含参数z z,故子类的方法未能覆盖父类,故子类的方法未能覆盖父类的方法,这时子类就出现两个方法具有相同的名字的方法,这时子类就出现两个方法具有相同的名字 。4.1.8 this关键字关键字基本使用说明:thisthis只能用于与实例有关的代码块中,如实例方法、只能用于与实例有关的代码块中,如实例方法、构造方法、实例
30、初始化代码块或实例变量的初始化代构造方法、实例初始化代码块或实例变量的初始化代码块等,码块等,thisthis就代表当前或者正在创建的实例对象的就代表当前或者正在创建的实例对象的引用,通常可以利用这一关键字实现与局部变量同名引用,通常可以利用这一关键字实现与局部变量同名的实例变量的调用。在构造方法中还可以用的实例变量的调用。在构造方法中还可以用thisthis来代来代表要显式调用的其它构造方法。除此以外,使用表要显式调用的其它构造方法。除此以外,使用thisthis关键字都将引发编译时错误。关键字都将引发编译时错误。4.1.8 this关键字关键字1在类的构造方法中使用this关键字在构造方法
31、内部使用在构造方法内部使用thisthis,代表使用该构造方法所创,代表使用该构造方法所创建的对象。建的对象。 【实例4-15】class Tom int n; Tom(int x) this.show(); n=x; this.show(); void show() System.out.println(n+n); public static void main(String args) Tom tom=new Tom(10); 1.4.1.8 this关键字关键字说明:在本实例中,构造方法在本实例中,构造方法TomTom(int xint x)中出现了)中出现了thisthis,表示该对象
32、在构造自己时调用了方法表示该对象在构造自己时调用了方法showshow()。运行()。运行结果为:结果为:n n0 0n n10104.1.8 this关键字关键字此外,在构造方法内部使用this,可用于指代另外一个构造函数,但不能指代非构造函数。例如:【实例4-16】 class point class point int x, y; int x, y; point( )point( )this(-1,-1);this(-1,-1); point(int a, int b) point(int a, int b) x=a;x=a;y=b;y=b; 说明:在本实例中,构造方法point( )中
33、的 this指代构造方法point(int a, int b)。4.1.8 this关键字关键字2在类的实例方法中使用this关键字 在实例方法内部使用在实例方法内部使用thisthis,代表使用该方法的当前对,代表使用该方法的当前对象。象。 【实例4-17】class A int x;void fun() this.x=10;this.g(this.x); void g(int x) System.out.println(x=+x); class ex1 public static void main(String args )A a=new A();a.fun(); 1. 4.1.8 th
34、is关键字关键字说明: 在本实例中,实例方法在本实例中,实例方法funfun中出现了中出现了thisthis,thisthis就代就代表使用表使用funfun的当前对象。因此,的当前对象。因此,this.xthis.x表示当前对象表示当前对象的变量的变量x x,将,将1010赋给该对象的变量赋给该对象的变量x x。 this.g this.g表示当表示当前对象的方法前对象的方法g g时,传递参数为时,传递参数为this.xthis.x。通常情况下,。通常情况下,可以省略成员变量(或方法)名字前面的可以省略成员变量(或方法)名字前面的“this.”“this.”。4.1.8 this关键字关键字
35、3使用this区分成员变量和局部变量 如果局部变量的名字与成员变量的名字相同,则成员如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即这个成员变量在这个方法内暂时失效。变量被隐藏,即这个成员变量在这个方法内暂时失效。这时如果想在该方法内使用成员变量,成员变量前面这时如果想在该方法内使用成员变量,成员变量前面的的“this.”this.”就不可以省略,如:就不可以省略,如:【实例4-18】 class point class point int x , y; int x , y; void init(int x, int y )void init(int x, int y )this.
36、x=x;this.x=x;this.y=y;this.y=y; 1.说明:在本实例中,在本实例中,this.xthis.x和和this.ythis.y是指类是指类pointpoint的属性的属性变量变量x x和和y y,语句,语句“this.x=x;”this.x=x;”和和“this.y=y;”this.y=y;”等号右等号右边的边的x x和和y y则是和方法则是和方法initinit()的形参()的形参x x和和y y。4.1.9 super关键字关键字supersuper只能用于与实例有关的代码块中,如实例方法、构只能用于与实例有关的代码块中,如实例方法、构造方法、实例初始化代码块或实例
37、变量的初始化代码块等,造方法、实例初始化代码块或实例变量的初始化代码块等,supersuper代表当前或者正在创建的实例对象的父类,通常可代表当前或者正在创建的实例对象的父类,通常可以利用这一关键字实现对父类同名属性或方法的调用。在以利用这一关键字实现对父类同名属性或方法的调用。在构造方法中还可以用构造方法中还可以用supersuper来代表要调用的父类构造方法,来代表要调用的父类构造方法,以实现构造方法链的初始化。由于以实现构造方法链的初始化。由于ObjectObject类为类为JavaJava语言的语言的根类,已经没有父类,因此,如果在根类,已经没有父类,因此,如果在ObjectObjec
38、t类中使用了关类中使用了关键字键字supersuper,将引发编译时错误。,将引发编译时错误。4.1.9 super关键字关键字1 1使用使用supersuper调用父类的构造方法调用父类的构造方法子类不继承父类的构造方法,因此,子类如果想使用父类的构造子类不继承父类的构造方法,因此,子类如果想使用父类的构造方法,必须在子类的构造方法中使用并且必须使用关键字方法,必须在子类的构造方法中使用并且必须使用关键字supersuper来来表示,而且表示,而且supersuper必须是子类构造方法中的第一条语句。这点在子必须是子类构造方法中的第一条语句。这点在子类对象的构造过程一节已举例说明,在此不在赘
39、述。类对象的构造过程一节已举例说明,在此不在赘述。2 2使用使用supersuper操作被隐藏的成员变量和方法操作被隐藏的成员变量和方法如果在子类中想使用被子类隐藏的成员变量或方法就可以使用关如果在子类中想使用被子类隐藏的成员变量或方法就可以使用关键字键字supersuper。 【实例4-19】class A int x=2, y=3; double add() return x+y; class B extends A int x=20,y=30;double add() return super.x+super.y ; double addB() return x+y ; double a
40、ddA() return super.add();1. 【实例4-19】class ex2 public static void main(String args ) A a=new A(); B b=new B(); System.out.println(b.add=+b.addB(); System.out.println(a.add=+a.add();System.out.println(a.add=+b.addA(); 11. 4.1.9 super关键字关键字说明:说明:在本实例中,子类在本实例中,子类B B使用使用super.xsuper.x和和super.ysuper.y调用父类
41、调用父类A A被隐藏的成员变量被隐藏的成员变量x x和和y y,使用,使用super.addsuper.add()调用父类()调用父类A A被隐藏的方法被隐藏的方法addadd()。()。 其结果如下:其结果如下:b.add=50b.add=50a.add=5a.add=5a.add=5a.add=54.1.10 对象的上、下转型对象对象的上、下转型对象1向上转型向上转型是指将子类类型的引用赋值给其父类或祖先向上转型是指将子类类型的引用赋值给其父类或祖先类类型的引用,赋值操作中包含了隐式的类型转换。类类型的引用,赋值操作中包含了隐式的类型转换。Object obj1=new String(“g
42、ood”); /Object obj1=new String(“good”); /对象的上转对象的上转型型Object obj2=new Integer(100); /Object obj2=new Integer(100); /对象的上转型对象的上转型例如,类例如,类B B是类是类A A的子类。的子类。A aA a;B b=new BB b=new B()(); ;a=b;a=b;4.1.10 对象的上、下转型对象对象的上、下转型对象此时称对象此时称对象a a是子类对象是子类对象b b的上转型对象,对象的上转型对的上转型对象,对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象象
43、的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。上转型对象不能操作子类声明定义的的一些属性和功能。上转型对象不能操作子类声明定义的成员变量;也不能使用子类声明定义的方法。上转型对象成员变量;也不能使用子类声明定义的方法。上转型对象可以操作子类继承的成员变量和隐藏的成员变量,也可以可以操作子类继承的成员变量和隐藏的成员变量,也可以使用子类继承的或重写的方法。上转型对象不能操作子类使用子类继承的或重写的方法。上转型对象不能操作子类新增的方法和成员变量。将对象的上转型对象再强制转换新增的方法和成员变量。将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类所有属到
44、一个子类对象,这时,该子类对象又具备了子类所有属性和功能。性和功能。4.1.10 对象的上、下转型对象对象的上、下转型对象2 2向下转型向下转型向下转换是指将某类类型的引用赋值给其子类类型的引用,赋值操作必须进行显式(强制)的类型转换。String str1=(String)obj1; /对象的下转型Integer int1=(Integer)obj2; /对象的下转型4.2 接口接口4.2.1 abstract类4.2.2 接口的含义4.2.3 接口回调4.2.4 接口与抽象类的异同4.2.1 abstract类类用关键字abstract修饰类称为abstract类(抽象类) 。如:abst
45、ract class A abstract类不能用new运算符创建对象,必须产生其子类,由子类创建对象。若abstract类的类体中有abstract方法,只允许声明,而不允许实现,而该类的子类必须实现abstract方法,即重写父类的abstract方法。一个abstract类只关心子类是否具有某种功能,不关心功能的具体实现。具体实现由子类负责。因此,抽象类的唯一目的是为子类提供公有信息,它是用来被继承的,抽象类不能创建对象。4.2.2 接口的含义接口的含义Java不支持多继承性,即一个类只能有一个父类。单继承性使得Java简单,易于管理程序。为了克服单继承的缺点,Java使用了接口,一个类
46、可以实现多个接口。使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口的声明和接口体。4.2.2 接口的含义接口的含义1接口的声明声明接口的语法如下: interface interface / /接口声明接口声明 接口体接口体 接口名的命名规范与类相同,接口也可以指定所属的包。接口的修饰符可以有以下几种: (1) public(1) public:与类的:与类的publicpublic修饰符相同;修饰符相同; (2) abstract(2) abstract:通常被省略,因为接口中的方法都是抽象的;:通常被省略,因为接口中的方法都是抽象的; (3) strictf
47、p (3) strictfp:通常并不能限制接口中方法的实现,一般不使用。:通常并不能限制接口中方法的实现,一般不使用。4.2.2 接口的含义接口的含义2接口体接口体中包含常量定义和方法定义两部分。(1) (1) 接口中的成员都是接口中的成员都是publicpublic的,不能指定其它的访问控制修饰的,不能指定其它的访问控制修饰符。符。(2) (2) 常量定义。接口中属性的域默认是常量定义。接口中属性的域默认是static finalstatic final的,必须显的,必须显式初始化。式初始化。(3) (3) 方法。只能提供方法头声明,不能提供实现,且除方法。只能提供方法头声明,不能提供实现
48、,且除abstractabstract外,不能使用其它修饰符。接口中的方法被默认是外,不能使用其它修饰符。接口中的方法被默认是publicpublic和和abstractabstract的,接口在声明方法时可以省略方法前面的的,接口在声明方法时可以省略方法前面的publicpublic和和abstractabstract关键字,但是,类在实现接口方法时,一定要用关键字,但是,类在实现接口方法时,一定要用publicpublic来修饰。来修饰。(4) (4) 嵌套类和嵌套接口;嵌套类和嵌套接口;4.2.2 接口的含义接口的含义3接口的多继承接口支持多亲继承,可以在关键字接口支持多亲继承,可以在关
49、键字extendsextends后面跟多个接口的列表,后面跟多个接口的列表,中间用逗号隔开,如:中间用逗号隔开,如:public interface SerializableRunnable extends , Runnablepublic interface SerializableRunnable extends , Runnable 子接口拥有所有父接口中声明的方法。子接口中的域将隐藏父接子接口拥有所有父接口中声明的方法。子接口中的域将隐藏父接口中声明的同名域,被隐藏的父接口中的域必须通过父接口名访口中声明的同名域,被隐藏的父接口中的域必须通过父接口名访问。问。子接口不仅可以保有父接口的
50、成员,同时也可加入新成员以满足子接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要。实现接口的类也必须实现此接口的父接口。实际问题的需要。实现接口的类也必须实现此接口的父接口。4.2.2 接口的含义接口的含义4接口的使用一个类通过使用关键字一个类通过使用关键字implements implements 声明自己实现一个或多个接声明自己实现一个或多个接口。如果实现多个接口,用逗号隔开接口名,如:口。如果实现多个接口,用逗号隔开接口名,如: class A implements Printable class A implements Printable,AddableAddab