《Java类、接口、包2(ch).ppt》由会员分享,可在线阅读,更多相关《Java类、接口、包2(ch).ppt(40页珍藏版)》请在三一办公上搜索。
1、主要内容,5.3 类的继承5.4 抽象类、接口与包,5.3 类的继承,5.3.1 综述 运用抽象的原则舍弃对象的特殊性,抽取其共同性,则可得到一个适应于一批对象的类,这就是一般类;而那些具有特殊性的类称为特殊类。即:如果类B具有类A的全部/部分属性和方法,而且又具有自己特有的某些属性和方法,则把类A称作一般类,把类B叫做类A的特殊类。特殊类的对象拥有其一般类的全部或部分属性与方法,称作特殊类对一般类的继承。被继承的类A为基类、父类或超类,而称继承类B为A的派生类或子类。继承避免了对一般类和特殊类之间共同特征进行的重复描述。,图 5.1,在Java中,所有的类都是通过直接或间接地继承java.l
2、ang.Object类得到的,如图5.1所示。,注意:Java与C+不同,不支持多重继承,但可以通过接口实现多重继承。,5.3.2 子类的创建class subclassName extends superclassName/类体/如:class Rectangle extends Shape.说明:新定义的子类可以从父类那里继承所有非private的属性和方法作为自己的成员。实际上,在定义一个类而不给出extends关键字及父类名时,默认这个类是系统类java.lang.object的子类。,public class Circle/定义圆类 double radius;public void
3、 setRadius(double r)radius=r;public double getRadius()return radius;public double perimeter()return 2*Math.PI*radius;public double area()return Math.PI*radius*radius;,class Cylinder extends Circleprivate double height;public void setHeight(double h)height=h;public double getHeight()return height;pub
4、lic double volume()return area()*height;,public class CylinderTestpublic static void main(String args)Cylinder cylin=new Cylinder();cylin.setRadius(10);cylin.setHeight(20);System.out.printf(The perimeter=%8.2f%n,cylin.perimeter();System.out.printf(The floor area=%8.2f%n,cylin.area();System.out.print
5、f(The volume=%8.2f,cylin.volume();,1.成员变量的隐藏 是指:在子类中重新定义一个与父类中已定义的数据成员名完全相同的数据成员(成员变量),即子类拥有了两个相同名字的数据成员,一个是继承父类的,另一个是自己定义的。当子类引用这个同名的数据成员时,默认操作是引用它自己定义的数据成员,而把从父类那里继承来的数据成员“隐藏”起来。当子类要引用继承自父类的同名数据成员时,可使用关键字super引导*(后面介绍)。举例:c5_7.java,2.成员方法继承与覆盖(OverRiding)子类可以继承父类的非私有成员方法。(例:c5_8.java)子类可以重新定义与父类同名
6、的成员方法,实现对父类方法的覆盖。(c5_9.java)class a1 int x=0,y=1;void Myp()System.out.println(x=+x+y=+y);private void Printm()System.out.println(x=+x+y=+y);public class c5_8 extends a1 public static void main(String args)c5_8 p1=new c5_8();p1.Myp();/p1.Printme();,例:c5_9.javaclass a1 int x=10;int y=31;public void pr
7、intme()System.out.println(x=+x+y=+y);public class c5_9 extends a1 int z=35;public void printme()System.out.println(z=+z);public static void main(String arg)a1 p2=new a1();c5_9 p1=new c5_9();p1.Printme();p2.Printme();,运行结果是:z=35 x=10 y=31,注意:子类在重新定义父类已有的方法时,应保持与父类完全相同的方法名、返回值类型和参数列表,否则就不是方法的覆盖,而是子类定义
8、自己特有的方法,与父类的方法无关。,5.3.3 this和super 1.this 代表当前对象的一个引用,可将其理解为当前对象的另一个名字,通过这个名字可以访问对象,修改对象的数据成员,调用对象的方法。在一些容易混淆的场合,例如,当成员方法的形参名与数据成员名相同,或者成员方法的局部变量名与数据成员名相同时,在方法内借助this来明确表示引用的是类的数据成员,而不是形参或局部变量,从而提高程序的可读性。this的使用场合:(1)用来访问当前对象的数据成员,其使用形式如下:this.数据成员 举例(见下页):c5_11.java(2)用来访问当前对象的成员方法,其使用形式如下:this.成员方
9、法(参数)举例(见下页)c5_12.java(3)当有重载的构造方法时,用来引用同一个类的其它构造方法,其使用形式如下:(见下节构造方法的重载、继承)this(参数),class classArea double x,y;double area(double x,double y)double s;this.x=x;y=y;s=this.x*y;/不能用this.y,因为上一句没这么写 return s;public class c5_11 extends classArea public static void main(String args)double a=2.2,b=3.1,z;c5
10、_11 ss=new c5_11();z=ss.area(a,b);System.out.println(z=+z);运行结果是:z=6.820000000000001,public class c5_12 public static void main(String args)double x;circle cir=new circle(5.0);x=cir.area();System.out.println(圆的面积=+x);x=cir.perimeter();System.out.println(圆的周长=+x);,class circle double r;public circle(
11、double r)this.r=r;double area()return PI*r*r;double perimeter()return 2*(this.area()/r);/调用当前对象的方法。,2Super的使用场合 super表示的是当前对象的直接父类对象,是当前对象的直接父类对象的引用。若子类的数据成员或成员方法名与父类的数据成员或成员方法名相同,当要调用父类的同名方法或使用父类的同名数据成员时,可用关键字super来指明父类的数据成员和方法。super的使用方法有三种(1)用来访问直接父类隐藏的数据成员,其使用形式如下:super.数据成员(2)用来调用直接父类中被覆盖的成员方法,
12、其使用形式如下:super.成员方法(参数)(3)用来调用直接父类的构造方法(构造方法继承),其使用形式 super(参数)(见下节构造方法的重载、继承)例:c5_13.java,class a1 int x=4;int y=1;public void Printme()System.out.println(x=+x+y=+y);System.out.println(class name:+this.getClass().getName();,public class c5_13 extends a1 int x;public void Printme()int z=super.x+6;/访问
13、隐藏的变量 super.Printme();/访问被覆盖的方法 System.out.println(I am an+this.getClass().getName();x=5;System.out.println(z=+z+x=+x);public static void main(String arg)int k;a1 p1=new a1();c5_13 p2=new c5_13();p1.Printme();p2.Printme();,运行结果:X=4 y=1Class name:a1X=4 y=1Class name:c5_13I am an c5_13Z=10 x=5,5.3.4 构
14、造方法的重载、继承及调用过程1、重载:一个类若干个构造方法之间可以相互调用,可使用this.this(参数)举例:c5_14.java2、继承:子类可以继承父类的构造方法,遵循以下原则:(1)子类无条件地继承父类的不含参数的构造方法。(2)如果子类自己没有构造方法,则它将继承父类的无参数构造方法,并将这些方法作为自己的构造方法;如果子类自己定义了构造方法,则在创建新对象时,它将先执行继承自父类的无参数构造方法,然后再执行自己的构造方法。(3)对于父类的含参数构造方法,子类可以通过在自己的构造方法中使用super关键字来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句。super(参数
15、)举例:c5_15.java(下页),例:class addclass public int x=0,y=0;addclass(int x)this.x=x;addclass(int x,int y)this.x=x;this.y=y;public int add()return x+y;,public class c5_15 extends addclass int a=0,b=0;c5_15(int x)super(x);/子类 可重载的构造方法1 a=x+7;c5_15(int x,int y)super(x,y);/子类可重载的构造方法2 a=x+5;b=y+5;public int
16、add()System.out.println(super:x+y=+super.add();return a+b;public static void main(String args)c5_15 p2=new c5_15(10,20);c5_15 p3=new c5_15(1);System.out.println(a+b=+p2.add();System.out.println(a=+p3.add();,运行结果:Super;x+y=30a+b=40Super:x+y=1a=8,上机:P163 29,31 补充:编写主类,求两数的最大公约数;写子类,求两数的最小公倍数。(要求利用重写父类
17、的方法来实现),3、构造方法的调用过程,class Person String name;int age;public Person()public Person(String name,int age)/this.name=name;this.age=age;System.out.println(In Person(String,int);/class Student extends Person String major;public Student()this(null,0,null);/System.out.println(In Student();/,public Student(S
18、tring name,int age,String major)super(name,age);/this.major=major;System.out.println(In Student(String,int,String);/class Graduate extends Student String direction;public Graduate()/System.out.println(In Graduate();/public class PersonTest public static void main(String args)Graduate g=new Graduate(
19、);,5.3.5 父类与子类对象的转换 1、基本类型的转换 int j=10;double d=j;/自动类型转换 double d=3.14;int j=(int)d;/强制类型转换 2、子类对象和超类对象之间的转换(或称作对象造型casting)可分为自动转换和强制转换。1)自动转换(替代原则)由于子类继承了超类的数据和行为,因此子类对象可以作为超类对象使用,即有下面的替代原则。替代原则:凡是需要使用超类对象的地方都可以用子类对象代替。含义是,假设parent是一个超类对象,child是一个子类(直接或间接)对象,则赋值语句parent=child;是合法的,而child=parent;是
20、不合法的。例:CastDemo.java,2)强制类型转换 可以将一个超类对象转换成子类对象,这时需要使用强制类型转换。强制类型转换需要使用造型运算符“()”,例如上面代码中的语句:cylin=(Cylinder)circle;注意:不是任何情况都可以进行强制类型转换,下面代码:Circle circle=new Circle();Cylinder cylin=(Cylinder)circle;上述代码是要将超类对象转换为子类对象,代码编译时没有错误,但运行时会抛出ClassCastException异常。*将超类对象转换为子类对象,必须要求超类对象是用子类构造方法生成的对象,这样转换才正确。
21、*转换只发生在有继承关系的类之间。,5.3.6 instanceof 运算符1、String s=“I AM an Object!”;boolean isObject=s instanceof Object;/结果为true2、为了保证在将超类对象正确地造型为子类对象,可以在造型(转换)前用instanceof运算符来检验类型,如果对象是某类型的实例,才可以将其造型为该类型。见下页例。,例:一个处理账单的系统,其中有三个类:public class Bill/省略细节public class PhoneBill extends Bill/省略细节public class GasBill ext
22、ends Bill/省略细节在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断:public double calculate(Bill bill)if(bill instanceof PhoneBill)/计算电话账单 if(bill instanceof GasBill)/计算燃气账单.这样就可以用一个方法处理两种子类。,然而,上述做法通常被认为是没有很好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象编程应有的做法,避免回到结构化编程模式。只要
23、提供两个名字和返回值都相同,接受参数类型不同的方法就可以了:public double calculate(PhoneBill bill)/计算电话账单 public double calculate(GasBill bill)/计算燃气账单所以,使用instanceof在绝大多数情况下并不是推荐的做法,应当好好利用多态。,5.3.7 多态性与动态绑定1、多态 多态性是面向对象的一个重要特征。多态就是多种形式,它是指Java程序中一个类或多个类中可以定义多个同名方法,这多个同名方法名称相同,完成的操作不同,这就是多态。多态性是指在运行时系统判断应该执行哪个方法的代码的能力。Java语言支持两种
24、类型的多态:(1)静态多态:也叫编译时多态,它是通过方法重载实现的,即一个类可以定义多个同名的方法,这些方法要么参数个数不同、要么参数类型不同。(2)动态多态:也叫运行时多态,它是通过方法覆盖实现的,即在子类中定义与超类中方法名、返回值、参数都相同的方法。,2、动态绑定(binding)将一个方法调用和一个方法主体关联起来称方法绑定。若在程序执行前进行绑定,叫做前期绑定,如C语言的函数调用都是前期绑定。如果在程序运行时根据对象的类型进行绑定,则称为后期绑定或动态绑定。Java中除了static方法和final方法外都是后期绑定。有了方法的动态绑定,我们就可以编写只与基类交互的代码,并且这些代码
25、对所有的子类都可以正确运行。见下页举例。,例:动态绑定class Shape public void display()System.out.println(“This is a Shape);class Circle extends Shape public void display()System.out.println(This is a Circle);class Triangle extends Shape public void display()System.out.println(This is a Triangle);,public class PolyTest static
26、 void show(Shape s)s.display();public static void main(String args)double d=Math.random();Shape sh=null;if(d0.5)sh=new Circle();else sh=new Triangle();show(sh);,5.3.8 内部类(Inner Class)一、概述:内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,依附于外部类而存在。包含内部类的类称为外部类(Outer Class)或顶层(Top-level)类。内部类分类:1)成员/常规内部类:作为外部类的一个成
27、员存在,与外部类的属性、方法并列。该内部类可访问类本身定义的变量和方法,也可以访问外部类的变量和方法。2)局部内部类:在类的方法中定义的内部类。能访问当前代码块的常量和此外部类的所有成员。3)匿名内部类:没有名字的局部内部类。4)静态内部类:static修饰。,二、内部类的语法规则1、定义成员内部类的方法:class 成员的访问限制修饰符 static class/内部类的成员/外部类的其它成员说明:修饰符为:private、protected、public等。例:public class Outter public class Inner int i=2;int count=0;*此内部类中
28、,不能有static 变量和static 方法。,2、创建内部类对象的方法:1)在外部类之内创建内部类对象 例:InnerClass1.java 说明:编译后内部类与外部类各生成一个类文件。如上例将产生:InnerClass1.class;Outter.class;Outter$Inner.class.2)在外部类之外创建内部类对象.引用变量=.new.引用变量=new.new 例:InnerClass2.java3、局部内部类 能访问当前代码块的常量和此外部类的所有成员;局部类没有任何修饰符;由于局部类只在局部有效,所以只能在其有效的位置访问或创建其对象。例:InnerClass3.java
29、,4、匿名内部类 该类基于继承或者基于实现接口。基本语法如下:new/匿名内部类类体 上述语法格式在生成类的同时也创建了对象。该类也可以覆盖父类方法,或提供自己新的方法。例:InnerClass4.java 编译后的匿名内部类文件:$.class,n表示第n个匿名内部类文件。一个重要的应用:GUI的事件处理程序。如为按钮做事件监听器。JButton.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)System.out.println(“The Button is clicked!”)
30、;);5、静态内部类:由static 修饰的内部类,只能访问外部类的static成员。.引用变量=new.例:InnerClass5.java,5.4 抽象类、接口与包,抽象类体现数据抽象的思想,是实现程序多态性的一种手段。接口则是Java中实现多重继承的惟一途径,接口中只包含常量和没有方法体而只有声明的方法。包是一个更大的程序单位,主要实现软件复用。5.4.1 抽象类 1、定义:用修饰符abstract修饰的类。说明:将许多相关的类组织在一起,提供一个公共的类,即抽象类,而那些被它组织在一起的具体的类将作为它的子类由它派生出来。抽象类刻画了公有行为的特征,并通过继承机制传送给它的派生类。,抽
31、象类的定义:Abstract class 类名称 声明数据成员;Abstract 返回值的数据类型 方法名称(参数列表);/定义抽象方法,可以有多个 返回值的数据类型 方法名称(参数列表);/定义普通方法(非抽象方法),可以有多个,说明:(1)凡是用abstract 修饰符修饰的类被称为抽象类。凡是用abstract修饰符修饰的成员方法被称为抽象方法。(2)抽象类中可以有零个或多个抽象方法,也可以包含非抽象的方法。(3)抽象类中可以没有抽象方法,但是,有抽象方法的类必须是抽象类。(4)对于抽象方法来说,在抽象类中只指定其方法名及其类型,而不书写其实现代码。(5)抽象类可以派生子类,在抽象类派生
32、的子类中必须实现抽象类中定义的所有抽象方法。(6)抽象类不能创建对象,创建对象的工作由抽象类派生的子类来实现。(7)如果父类中已有同名的abstract方法,则子类中就不能再有同名的抽象方法。(8)abstract不能与final并列修饰同一个类。?(9)abstract 不能与private、static、final等并列修饰同一个方法。,3、抽象类应用举例:假设:编写一个计算矩形、直角三角形和圆的面积与周长的程序。分析:一般方法:定义四个类:圆类、三角形类、矩形类和使用该三个类的公共类。采用抽象类:可以为这三个类抽象出一个父类,在父类里定义圆、直角三角形和矩形三个类的共同的数据成员(如:长
33、、宽、画图坐标)及成员方法(求面积、周长)。把计算面积与周长的成员方法名放在父类给予说明,再将具体的计算公式在子类中实现。举例:C5_18.java,5.4.2 接口 接口是一系列没有实现的方法和常量的组合,它提供方法协议的封装,但不限制子类如何实现这些方法。通过接口我们可以使处于不同层次、互不相干的类具有相同的行为。接口的功能:(1)通过接口可以实现不相干类的相同行为而不需考虑这些类之间的层次关系。(2)通过接口可以指明多个类需要实现的方法。(3)通过接口可以实现“多重继承”。,1声明接口修饰符 interface 接口名extends 父接口名列表 常量数据成员声明抽象方法声明 说明:(1
34、)修饰符:public 和默认(被同一个包中的类使用)。(2)常量数据成员声明。常量数据成员前可以有也可以没有修饰符。修饰符是public final static和final static;接口中的数据成员都是用 final修饰的常量,写法如下:修饰符 数据成员类型 数据成员名=常量值或类型 数据成员名=常量值例如:public final static double PI=3.14159;final static int a=9;int SUM=100;等价于final static int SUM=100;,(3)抽象方法声明:接口中的方法都是用abstract修饰的抽象方法。在接口中只
35、能给出这些抽象方法的方法名、返回值和参数列表,而不能定义方法体。如下例所示:返回值类型 方法名(参数列表);其中:接口中的方法默认为public abstract方法。2、接口的实现 一个类要实现接口时,即一个类要调用接口时,要注意:(1)在类中,用implements关键字就可以调用接口。(2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法,而且方法头部分应该与接口中的定义完全一致,即有完全相同的返回值和参数列表。(3)如果实现某接口的类是abstract的抽象类,则它可以不实现该接口所有的方法。(4)接口的抽象方法的访问限制符都已指定为pub
36、lic,所以类在实现方法时,必须显式地使用public修饰符,否则将被系统警告为缩小了接口中定义的方法的访问控制范围。举例:1)Li5_11.java 2)TestInterface1.java,3、接口回调 是指:可以把实现某一接口的类创建的对象的引用赋给用该接口声明的接口变量,则该接口变量就可以调用被类实现的接口中的方法。例如:,interface ShowMessage void showbrand(String s);class TV implements ShowMessage public void showbrand(String s)System.out.println(s);
37、class PC implements ShowMessage public void showbrand(String s)System.out.println(s);,public class Inexa public static void main(String args)ShowMessage sm;sm=new TV();sm.showbrand(“三星牌电视机!”);sm=new PC();sm.showbrand(“联想笔记本!”);,5.4.3 包(package)包是一组相关的类和接口的集合,或者说包是接口和类的容器。使用包有利于实现不同程序间类的重用。Java语言为编程人
38、员提供了自行定义包的机制。包的作用有两个:一是划分类名空间,二是控制类之间的访问。注意下述两点:首先,既然包是一个类名空间,那么,同一个包中的类(包括接口)不能重名,不同包中的类可以重名;第二,类之间的访问控制是通过类修饰符来实现的,若类声明的修饰符为public,则表明该类不仅可以供同一包中的类访问,而且还可以被其他包中的类访问,若类声明无修饰符,则表明该类仅供同一包中的类访问。,1.创建包是指:将源程序文件中的接口和类纳入指定的包中。包的声明语句格式:package 包名;利用该语句就可以创建一个具有指定名字的包,当前.java文件中的所有类都被放在这个包中。例如:package shap
39、e;package shape.shapeCircle;创建包就是在当前文件夹下创建一个子文件夹,存放这个包中包含的所有类的.class文件。package shape.shapeCircle;语句中的符号“”代表了目录分隔符,说明这个语句创建了两个文件夹:第一个是当前文件夹下的子文件夹shape;第二个是shape下的子文件夹shapeCircle,当前包中的所有类就存放在这个文件夹里。若源文件中未使用package,则该源文件中的接口和类位于Java的无名包中(无名包又称缺省包),它们之间可以相互引用非private的数据成员或成员方法。无名包中的类不能被其他包中的类引用和复用。,2、包的
40、引用 import pack1.pack2.pack3.className1;3、应用 将Point和Rectangle类打包,放入mypackage包中,然后在类Li5_10中引入该包。Li5_10.java 注意:1)将Point.class和Rectangle.class文件放入Mypackage文件夹下,将Li5_10.class文件存入当前目录下。方法1:javac mypackagePoint.java javac mypackageRectangle.java javac Li5_10.java 方法2:javac d.Point.java 系统自动在当前目录下创建mypackage文件夹,并将编译后的Point.class存放在该文件夹下。2)在当前目录下运行主类程序:java Li5_10 3)Eclipse下的应用,表5.1 常用包列表,上机:P90 29,P163 32 33 38 39,