JAVA05进一步讨论对象和类.ppt

上传人:牧羊曲112 文档编号:6509197 上传时间:2023-11-07 格式:PPT 页数:63 大小:345.50KB
返回 下载 相关 举报
JAVA05进一步讨论对象和类.ppt_第1页
第1页 / 共63页
JAVA05进一步讨论对象和类.ppt_第2页
第2页 / 共63页
JAVA05进一步讨论对象和类.ppt_第3页
第3页 / 共63页
JAVA05进一步讨论对象和类.ppt_第4页
第4页 / 共63页
JAVA05进一步讨论对象和类.ppt_第5页
第5页 / 共63页
点击查看更多>>
资源描述

《JAVA05进一步讨论对象和类.ppt》由会员分享,可在线阅读,更多相关《JAVA05进一步讨论对象和类.ppt(63页珍藏版)》请在三一办公上搜索。

1、5 进一步讨论对象和类,5.1 抽象数据类型,抽象数据类型(数据结构的概念)(ADT:Abstract Data Types),由用户定义,用以表示应用问题的数据模型由基本的数据类型组成,并包括一组相关的操作信息隐蔽和数据封装,使用与实现相分离,类就是一种抽象数据类型,用一个类来代表某类事物(如动物)特点:封装:将实现细节隐藏,使用类时只需知其功能,不需知道功能如何实现继承:描述类间的(抽象程度)的层次结构,实现代码重用(动物:哺乳动物、爬行动物)多态:同一个方法在不同类中运行的结果不同(“鸣叫”在不同动物类中的表现),封装的概念,封装的含义:类的设计者把类设计成一个黑匣子,使用者只能看见类中

2、定义的公共变量和公共方法,而看不见方法的具体实现细节,也不能对类中非公共的数据进行操作。为保护类中成员的正确性或一致性1、在类的定义中设置对对象中的成员变量和方法进行访问的权限(使用private、public等关键字);2、提供一个统一供其他类引用的方法;3、其他对象不能直接修改本对象所拥有的属性和方法(而必须通过对象自己提供的方法)。,最常见的封装,将类成员设置成私有(private),外部无法访问,只有类中的方法可访问设置一些公开的(public)、专门访问类成员和为类成员赋值的方法;在这些方法中可加入一些控制过程,保证对类成员的访问和改写是合法的。访问类成员的方法称为getter;改写

3、类成员的方法称为setter;,简单的封装例子:Students类(P87页4.10题),public class Student implements Comparableprivate String name;/姓名private int id;/学号private String sex;/性别private double creditSum;/学分积private Course courses=new Course3;/三门课public String getName()return name;public void setName(String name)this.name=name;

4、public int getid()return id;public void setid(int id)this.id=id;public String getSex()return sex;public void setSex(String sex)this.sex=sex;public Course getG()return courses;public void setG(Course g)this.courses=g;public double getCreditSum()return creditSum;/给学分积赋值,也就是计算学分积public void setCreditSu

5、m()if(courses=null)creditSum=0;elsedouble sum=0;for(Course c:courses)/对每门课程计算学分积并加到sum中去if(c.getScore()94)sum+=c.getCredit()*4.0;else if(c.getScore()89)sum+=c.getCredit()*3.8;else if(c.getScore()84)sum+=c.getCredit()*3.6;else if(c.getScore()79)sum+=c.getCredit()*3.2;else if(c.getScore()74)sum+=c.get

6、Credit()*2.7;else if(c.getScore()69)sum+=c.getCredit()*2.2;else if(c.getScore()64)sum+=c.getCredit()*1.7;else if(c.getScore()59)sum+=c.getCredit()*1.0;elsesum+=0;creditSum=sum;,5.2 对象的构造和初始化,5.2 对象的构造和初始化,要使用对象,首先必须构造它们,并指定它们的初始状态,然后将方法应用于对象。在Java程序设计语言中,使用构造方法(constructor)来构造新的实例。一个构造方法是一个新的方法,它的作用

7、是构造并初始化对象。,5.2 对象的构造和初始化,构造方法是类的一种特殊方法,它的特殊性主要体现在如下的几个方面:(1)构造方法的方法名与类名相同。(2)构造方法没有返回类型。(3)构造方法的主要作用是完成对类对象的初始化工作。(4)构造方法不能由编程人员显式地直接调用。(5)在创建一个类的新对象的同时,系统会自动调用该类的构造方法为新对象初始化。,构造方法的特点,(1)构造方法和类具有相同的名字。(2)一个类可以有多个构造方法。(3)构造方法可以有0个、1个或多个参数。(4)构造方法没有返回值。(5)构造方法总是和new运算符一起被调用。(6)构造方法必须声明为public。,Java中可以

8、不定义构造方法,Java中可以不定义构造方法,此时系统会自动生成一个默认的构造方法。这个构造方法的名字与类名相同,它没有任何形式参数,也不完成任何操作。在类的定义中可以不定义构造方法,而其他类仍然可以通过调用new classname()来实例化某类对象。这是因为系统给未定义构造方法的类自动加入了一个特殊的构造方,这个方法不带参数且方法体为空,称为默认的构造方法。用默认的构造方法初始化类对象时,系统把类对象的数据成员初始化为默认值。注意:一旦在类中自己定义了构造方法,默认的构造方法就不被加到类的定义中。此时,如果在程序中初始化对象时使用了默认的构造方法将出现了编译错误,所以为了避免此类错误,如

9、果类中定义了构造方法,通常也加入不带参数的构造方法。,构造方法可以有多个,满足不同的创建对象的方式不同构造方法之间完全同名,但输入参数的个数或类型不能相同。这实际上是方法的重载(overload),见后类中只要自定义了一个构造方法,系统为类准备的默认构造方法就失效了。如果希望默认的无参数构造方法依然可用,则需添加一个这样的构造方法,构造方法示例,public class Student private String name;/姓名private int id;/学号private String sex;/性别 public Student()/无参数构造方法,可以没有 public Stud

10、ent(String name,int id,String sex)/构造方法this.name=name;this.id=id;this.sex=sex;/写toString 方法来显示对象的各个属性/在main方法中创建一个对象并显示其内容,5.3 this引用,5.3 this引用,this是java中的一个关键词,用于在类中指代所创建的对象本身通过这种方法使得类中一个方法可调用同类中的其它方法和成员变量.,例:构造方法调用另一构造方法,希望在无参数的构造方法中给对象的成员变量赋予默认值 public Student()name=unknown;id=0;sex=unknown;/thi

11、s(unknown,0,unknown);/主程序验证public static void main(String args),5.4 子类(和继承),继承性是软件复用的一种形式。新类由已存在的类生成,通过保留它们的属性和行为,并且根据新类的要求对性能加以修改,添加新的属性和行为。从现有类出发定义一个新类,称为新类继承了现有的类,其中被继承的现有类叫做超类(superclass)或父类,由继承而得到的类称为子类(subclass)。,继承,Super超类,继承super部分sub1增加部分,继承super部分sub2增加部分,Sub1子类,Sub2子类,如果子类只从一个父类继承,则称为单继承;

12、如果子类从一个以上父类继承,则称为多继承。注意 Java不支持多重继承,但它支持“接口”概念(间接实现多重继承)。,单重继承,一、父类和子类继承和继承的实现,1、类继承的实现,修饰符 class 类名 extends 父类名 类体;,二、成员变量的继承,子类继承父类中所有可被子类访问的成员变量。继承原则如下:能够继承那些声明为public和protected的成员变量。能够继承同一包中的那些默认修饰符的成员变量。不能继承那些声明为private的成员变量。如果子类声明一个与父类成员变量同名的成员变量,则不能继承父类的成员变量。此时子类的成员变量称做隐藏了父类的成员变量。,三、成员方法的继承,子

13、类继承成员方法的规则类似于继承成员变量的规则:子类继承父类中所有可被子类访问的成员方法。继承规则如下:能够继承那些声明为public和protected的成员方法。能够继承同一包中的默认修饰符的成员方法。不能继承那些声明为private的成员方法。不能继承父类的构造方法。如果子类方法与父类方法同名,则不能继承。子类方法称为覆盖了父类中的那个方法。,super和this关键字:指代本对象和父对象,1、super(参数):基类中的某一个构造方法(必须作为为构造方法中的第一条语句被使用)2、this(参数):本类中另一种形式的构造方法(必须作为为构造方法中的第一条语句被使用);3、super:引用当

14、前对象的直接父类(即上一级或“父”但并不代表“爷爷”)的对象(用来访问直接父类中被隐藏的父类中成员数据或方法,基类与派生类中有相同成员定义时)4、this:代表当前对象名。其主要的用途:在程序中易产生二义性之处,应使用this来指明当前对象;如果方法的形参与类中的成员数据同名,这时需用this来指明成员变量名,student的子类:postgraduate,public class Postgraduate extends Studentprivate String tutor;/可增加与父类类似的带参数的构造方法public Postgraduate(String name,int id,S

15、tring sex,String tutor)super(name,id,sex);this.tutor=tutor;public String getTutor()return tutor;public void setTutor(String tutor)this.tutor=tutor;public String toString()return super.toString()+.导师:+tutor;/通过主程序验证子类public static void main(String args)Postgraduate p1=new Postgraduate(tom,3014,male,M

16、ary);System.out.println(p1);,5.5方法的重写(多态、重写和重载),重写(又称覆盖),重写是指在继承过程中,子类中的成员(包括数据和方法)与其父类中的成员同名,但功能不同,此时,子类的成员“覆盖”从父类继承过来的成员。数据重写:又称为数据隐藏,子类中声明一个与父类中的成员完全同名的成员(但可以类型不同),它们实际上是完全不同的两个数据。此时父类的该成员在子类中不可见;方法重写:子类中声明一个与父类的某方法名称相同,参数表也完全相同(但功能不同)的方法。此时父类的该方法在子类中不可见。,重写后,父类的对应方法依然可访问,在数据隐藏和方法覆盖后,子类成员覆盖了父类的同名

17、成员,要访问父类的这些成员,可用super关键字来引用当前类的父类。super的用法有3种情况。1super.变量名:访问父类中被隐藏的成员变量。2super.方法名(参数表):调用父类中被重写的方法。3super(参数表):调用父类的构造方法,此时可用super来表示父类的构造方法。,由重写引出“多态”,同名方法在不同的类中(或不同参数时)表现出不同的功能,称为“多态”多态机制是面向对象程序设计的一个重要特征。Java 的多态机制主要表现在方法的重载、构造方法的重载以及方法的覆盖几个方面。多态的特点是采用同名的方式,根据调用方法时传送的参数的多少以及传送参数类型的不同,调用不同的方法,这样对

18、于类的编制而言,可以采用同样的方法获得不同的行为特征。,Java中多态机制有两种,重写(覆盖)、重载 重写:子类中用完全相同的方法覆盖父类的方法重载:同一类中出现名称完全相同,但参数个数或参数类型不同的多个方法,多态之重载,在编程时我们可能需要在一个类中定义几个功能相似但参数不同的方法。例如要从3个数中找出其中的最大者,而每次求最大数时数据类型不同,可能是3个整数、3个双精度或3个长整数。这样就需要定义三个方法,如:int getMax1(int a,int b,int c)double getMax2(double a,double b,double c)long getMax3(long

19、a,long b,long c)这种定义方式不仅显得枯燥,而且要求使用这个类的程序员熟悉多个不同的方法名称,给程序员带来麻烦。有人会想:能否不用3个方法名称而用一个统一的名称呢?,多态之重载,为此,Java语言提供了方法重载(overloading)机制。方法的重载是允许在一个类的定义中,多个方法使用相同的方法名。对于上述三个求最大数的方法,利用重载机制可以进行如下定义:public int getMax(int a,int b,int c)public double getMax(double a,double b,double c)public long getMax(long a,lon

20、g b,long c)这样使用一个方法名称getMax就可以定义求各种类型数据的最大值的方法,程序员只需记住一个方法名,减轻了程序员的负担,上述例子中getMax方法被重载。,重载的正式定义,就是在类中创建了多个方法,它们具有相同的名称,但有不同的输入参数和不同的定义。在调用方法时依据其参数个数及类型自动选择相匹配的方法去执行。达到各种对象处理类似问题时具有统一的接口之目的。多个重载方法的返回值类型可以相同也可以不相同。无法以返回值类型作为重载方法的区分标准对重载的说明:,构造方法的重载,在一个类中可以定义多个构造方法,以便对类对象提供不同的初始化的方法,供用户选用。这些构造方法具有相同的名字

21、,而参数的个数或参数的类型不相同。这称为构造方法的重载。,重载示例,public class OverloadExppublic static void main(String args)OverloadExp demo=new OverloadExp();System.out.println(demo.getMax(2,3);System.out.println(demo.getMax(2.3f,3.5f);System.out.println(demo.getMax(24,4.8f);/这里到底调用了哪个方法?/返回较大整数public int getMax(int i,int j)if(

22、i b)return a;elsereturn b;/仅仅返回类型不一样不能构成重载/public double getMax(float a,float b)/if(a b)/return a;/else/return b;/如果只是访问修饰符不一样不能构成重载/private double getMax(float a,float b)/if(a b)/return(double)a;/else/return(double)b;/,总结:重写和重载,重写override,又称覆盖:方法的格式完全相同(名称、自变量的个数和类型、返回值类型等)被重写的方法处于不同的类中重载overload:只

23、有方法名完全相同,在其它方面(自变量的个数或类型)必须有至少一项不同两个重载的方法处于同一类中,5.6 java包,包是一组类的集合一个包可以包含若干个类文件,还可包含若干个包包的作用将相关的源代码文件组织在一起类名的空间管理,利用包来划分名字空间,便可以避免类名冲突提供包一级的封装及存取权限,类的组织包的概念,包的命名每个包的名称必须是“独一无二”的Java中包名使用小写字母表示命名方式建议若包名中有任何不可用于标识符的字符,用下划线替代若包名中的任何部分与关键字冲突,后缀下划线若包名中的任何部分以数字或其他不能用作标识符起始的字符开头,前缀下划线,类的组织包的概念,一个Java源代码文件称

24、为一个编译单元,由三部分组成所属包的声明(省略,则属于默认包)Import(引入)包的声明,用于导入外部的类类和接口的声明(主体部分)一个编译单元中只能有一个public类,该类名与文件名相同,编译单元中的其他类往往是public类的辅助类,经过编译,每个类都会产一个class文件利用包来划分名字空间,便可以避免类名冲突,编译单元与类空间,包的声明命名包(Named Packages)例如:package Mypackage;当一个类的第一句是这一句时,该类必须位于名称为“Mypackage”的文件夹中,否则出错;默认包(未命名的包)不含有包声明的编译单元是默认包(当前文件夹)的一部分,类的组

25、织包的概念(续),包与目录Java使用文件系统来存储包和类包名就是文件夹名,即目录名用javac编译源程序时,如遇到当前目录(包)中没有声明的类,就会以环境变量classpath为相对查找路径,按照包名的结构来查找。因此,要指定搜寻包的路径,需设置环境变量classpath,类的组织包的概念(续),引入包 为了使用其它包中所提供的类,需要使用import语句引入所需要的类Java编译器为所有程序自动引入包java.langimport语句的格式 import package1.package2.(classname|*);其中package1.package2表明包的层次,它对应于文件目录cl

26、assname则指明所要引入的类名如果要引入一个包中的所有类,则可以使用星号(*)来代替类名,类的组织包的概念(续),复习:类成员的访问控制词,Eclipse:自动管理包,包管理虽然很繁琐,但是很规律;Eclipse中可以很方便的管理包新建包(自动生成对应文件夹)包中新建类(自动补充“package”语句)引入其它包中的类(自动寻找类,并补充“import”语句)示例,5.7 类成员,一般称为“静态成员”更易识别,类的静态成员,类的静态成员指的是类在实例化之前就存在的方法和变量(称静态方法和静态变量)因为在产生对象之前就存在,故称为“静态成员”如果用来指代与“对象成员”(即对象创建之后才出现的

27、成员)相异的概念,也可称为“类成员”但这样称呼易与“类的成员”相混淆以修饰词“static”标示静态成员可以直接通过调来类名来使用。,5.8 关键字 final,final,类前面使用“final”,则该类不允许有子类(也就是不能被继承)方法前面使用“final”,则该方法不允许被重写(覆盖)变量前面使用“final”,则该变量是常量,不允许被重新赋值。,5.9 抽象类,专门提供给其他类继承的类,抽象类,以“abstract”关键字修饰的类抽象类是不能直接被实例化的类,因此一般作为其它类的父类,与final类正好相反;抽象类中的抽象方法:以“abstract”关键字修饰的方法在该类中声明但不在

28、该类中提供实现(也就是方法体是空的),由继承类提供细节定义抽象方法的类必须是抽象类.子类如果继承自抽象类,则必须实现(也就是重写)抽象类的所有抽象方法;否则它还是一个抽象类,不能实例化对象,抽象类的例子,import;/=抽象类,代码如下:abstract class AbstractGuessNumberprivate int number,guess=0;public void setNumber()(想一个数让他猜去,);this.number=getUserInput();/获得用户输入的整数,令其等于number变量protected abstract void showMessag

29、e(String message);protected abstract int getUserInput();/子类中需要重写的两个类public void begin()showMessage(欢迎玩猜数字游戏!n);while(number!=guess)guess=getUserInput();/获取用户所猜的数字if(number guess)showMessage(猜小了,别泄气啊n);showMessage(你可算猜对了n);/=继承抽象类,实现所有抽象方法class ExtendsGuessNumber extends AbstractGuessNumberprivate Sc

30、anner scanner;/为实现抽象方法getUserinput准备的成员/*Scanner对象可调用下列方法,读取用户在命令行输入的各种数据类型:nextByte(),nextDouble(),nextFloat,nextInt(),nextLine(),nextLong(),nextShot()上述方法执行时都会造成堵塞,等待用户在命令行输入数据回车确认.*/public ExtendsGuessNumber()/构造函数scanner=new Scanner(System.in);/*Scanner对象可调用下列方法(函数),读取用户在命令行输入的各种数据类型:next.Byte()

31、,nextDouble(),nextFloat,nextInt(),nextLine(),nextLong(),nextShot()上述方法执行时都会等待用户在命令行输入数据,待回车确认后完成输入.*/这是需要实现的抽象方法之一public void showMessage(String message)for(int i=0;i message.length()*2;i+)(*);/输出界面格式控制,新手不用太在意System.out.println(n+message);for(int i=0;i message.length()*2;i+)(*);/输出界面格式控制,新手不用太在意Sys

32、tem.out.print(n);/这是需要实现的抽象方法之二public int getUserInput()(请输入一个数吧:);return scanner.nextInt();/专用于执行主程序的类public class Startpublic static void main(String args)ExtendsGuessNumber egu=new ExtendsGuessNumber();/实例化egu.setNumber();egu.begin();,抽象类,抽象类中除了抽象方法外,一般还包含成员变量和非抽象的方法如果所有方法都是抽象方法,则它应该被“接口”代替,5.10

33、接口,可将其想像成未实现任何方法的抽象类,接口,接口(interface):有时也翻译成”界面”,在java中,接口类型是抽象类概念的进一步升华,也是实现多重继承的一种结构,它用来声明一组常量和抽象方法.接口本身不提供实现功能的方法体,而由”继承”这个接口功能的各个类来具体实现.接口与抽象的区别:接口不需要继承,从而为相互没有关系的类能实现同样功能的一组方法提供一种有效手段.接口其实就是对类必须实现何种功能的一个规定。,接口的定义,public interface 接口名 extends 父接口名列表/声明常量字段publicstaticfinal 数据成员名=常量值;/声明抽象方法publi

34、cabstract方法名(参数表);,特点:1、接口的访问控制修饰符只有public。2、接口类型也可以继承,并且可以多重继承3、接口体内只能声明常量字段和抽象方法,并且被隐式声明为public,static,final.当然可写可不写,接口的实现,class 类名 implements 接口名 类体可实现多个接口,接口名之间以逗号隔开即可需在类中实现接口的所有方法,程序5-12,接口定义:public interface Shape2Ddouble pi=3.14;public abstract double area();接口必须单独定义在一个文件中,程序5-12,实现接口的类:class

35、 Rectangle implements Shape2Dint width,height;public Rectangle(int w,int h)width=w;height=h;public double area()return width*height;public class Circle implements Shape2Ddouble radius;public Circle(double r)radius=r;public double area()return(pi*radius+radius);/为了简单,主程序直接放在Circle里面了public static voi

36、d main(String args)Rectangle rect=new Rectangle(5,6);System.out.println(n矩形的面积为:+rect.area();Circle cir=new Circle(4);System.out.println(n圆形的面积为:+cir.area();/还可以声明接口类型的变量,令其等于实现了该接口的某个类实例,/然后调用接口的方法(由于变量是接口类型,因此该变量不能调用接口之外的方法)Shape2D s1,s2;s1=rect;s2=cir;System.out.println(n接口变量s1挂接的对象的面积是:+s1.area(

37、);System.out.println(n接口变量s2挂接的对象的面积是:+s2.area();,进阶练习:P87 题4.11,提示:创建一个student类;创建一个course类(课程),包含三门课程的成绩和学分以及学分积student中将一个course实例数组作为student的成员,这样每个学生就有了成绩。,进阶练习:P87 题4.11,在student类的main方法中编写主程序代码,创建一个学生数组,然后将数组的元素按学分积排序后从高到低输出(超出要求的)关键问题:如何根据学分积将学生排序?对student类需实现comparable接口使之可以通过Arrays.sort方法比

38、较大小该接口只包含一个方法:compareTo,因此必须在student类中实现该方法;在compareTo方法中以学分积作为比较依据,import;public class Student implements Comparableprivate String name;/姓名private int id;/学号private String sex;/性别private double creditSum;/学分积private Course courses=new Course3;/三门课/public Student()/public Student(String name,int id,

39、String sex)/构造函数this.name=name;this.id=id;this.sex=sex;public String getName()return name;public void setName(String name)this.name=name;public int getid()return id;public void setid(int id)this.id=id;public String getSex()return sex;public void setSex(String sex)this.sex=sex;public Course getG()ret

40、urn courses;public void setG(Course g)this.courses=g;public double getCreditSum()return creditSum;/给学分积赋值,也就是计算学分积public void setCreditSum()if(courses=null)creditSum=0;elsedouble sum=0;for(Course c:courses)/对每门课程计算学分积并加到sum中去if(c.getScore()94)sum+=c.getCredit()*4.0;else if(c.getScore()89)sum+=c.getC

41、redit()*3.8;else if(c.getScore()84)sum+=c.getCredit()*3.6;else if(c.getScore()79)sum+=c.getCredit()*3.2;else if(c.getScore()74)sum+=c.getCredit()*2.7;else if(c.getScore()69)sum+=c.getCredit()*2.2;else if(c.getScore()64)sum+=c.getCredit()*1.7;else if(c.getScore()59)sum+=c.getCredit()*1.0;elsesum+=0;c

42、reditSum=sum;/为了实现student可比较大小必须有的函数,属于Comparable接口public int compareTo(Object o)double d=(Student)o).getCreditSum();return Dpare(this.getCreditSum(),d);/为方便打印将student对象直接输出给printLn函数时会调用本函数形成字符串public String toString()return name+t+id+t+sex+t+学分积:+creditSum+t+courses0.toString()+t+courses1.toString

43、()+t+courses2.toString();public static void main(String args)Student students=new Student2;students0=new Student(liming,19,male);students1=new Student(xiaoli,20,female);/两位学生Course courses1=new Course3;/liming的三门成绩courses10=new Course(65,3);courses11=new Course(72,4);courses12=new Course(85,4);Cours

44、e courses2=new Course3;/xiaoli的三门成绩courses20=new Course(90,3);courses21=new Course(95,4);courses22=new Course(53,4);/为所有学生加载成绩,并计算学分积students0.setG(courses1);students0.setCreditSum();students1.setG(courses2);students1.setCreditSum();/对学生数组进行排序,实际是根据学生积升序排序Arrays.sort(students);for(int i=students.len

45、gth-1;i-1;i-)/降序输出,所以i从大到小System.out.println(studentsi);/main/class Student/课程类,其实例用来作为student类的成员class Courseprivate int score;/成绩private int credit;/学分public Course(int score,int credit)this.score=score;this.credit=credit;public int getCredit()return credit;public void setCredit(int credit)this.credit=credit;public int getScore()return score;public void setScore(int score)this.score=score;public String toString()return score:+this.score+t+credit:+this.credit;/class Course,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号