




已阅读5页,还剩117页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java程序设计教程,第4章 面向对象程序设计,第4章 面向对象程序设计,4.1 面向对象的基本概念 4.2 对象和类 4.3 接口 4.4 包 本章小 结,4.1 面向对象的基本概念,4.1.1 对象 4.1.2 类 4.1.3 接口 4.1.4 包 4.1.5 方法 总结,1. 什么是抽象 ? Benjamin 说:我们把自然界分解,然后组织成不同的概念。 例如,把一对情侣抽象为2,把“空”抽象为0,这种表示方法就是一种抽象。自然界的抽象基于人们的经验。 计算机程序设计的抽象: 例如:汇编语言 - 高级语言 涉及到 2个概念:问题空间 和 解空间 。 2. 对象的概念,4.1.1 对象,4.1.1 对象,问题空间:是需要用计算机去解决的问题,是问题解决者对问题的认识,这些问题是存在于现实生活中的。比如机场管理、个人信用卡关系、银行账户管理。 解空间:所谓解空间就是对问题空间中有待解决的问题进行建模的空间。这里讨论的解空间将以计算机为载体,要做的工作就是如何将现实中将要解决的问题抽象成计算机可理解并表示的单元,这个单元即为所谓的对象。所以将现实抽象成对象是个很重要的过程。,4.1.1 对象,2. 对象的概念 Thinking in Java一书中的作者Bruce Eckel 说 :什么都是对象 ,比如 一个人,一个灯泡等。 以灯泡为例:灯泡有其属性,如功率、电流、发光颜色等;也有其行为,如点亮、熄灭、调亮、调暗等。 一个对象基本上有自己的名字、属性(变量)和可以提供的服务(行为,函数实现)。 图示说明: 总结:Object (对象) Class(类) ADT(抽象数据类型)。,4.1.1 对象,2. 对象的概念 举例说明: 图4-1中的矩形是一个UML(Unified Modeling Language)图,它清晰地描述了一个对象应有的基本元素。 对象名。 矩形上层外面的Type Name,这里的Type 是很严谨的定义。应该记住这样一个层次关系:Object Class ADT。 对象提供的服务(方法或函数)。 对象的一些行为所带来的效果映射成现实中的服务。在图4-1的矩形框下半部分的四个行为on()、off()、brighten()、dim(),表示此处的对象提供的服务有4种,可选择打开、关闭、调亮和调暗电筒的光源。,手电筒,4.1.2 类,类:就是一组对象的集合。 面向对象的程序设计语言都用class关键字来表示类。class是一种抽象的数据类型。 类的特性:封装性、继承(Inheritance)性和多态(Polymophism)性。 封装性:类是属性和其所提供的服务(方法)的封装体。如图4-1所示。 继承性:课本P70:图4-2 和 图4-3 。 多态性:就是指同一个符号或名字在不同情况下的不同解释。例如: 除法运算符: /。 (注:多态性在此简单了解,后面做详细学习),4.1.2 类,Apple,Orange,Banana,图4-2 is-a关系(继承关系),父类(基类、超类),子类(派生类),4.1.2 类,图4-3 has-a关系(组合关系),说明:上述 has-a关系不属于类的继承关系,在此仅作了解。,4.1.3 接口,接口:是和类相似的一种抽象数据类型。 接口中只给出公有的静态常量数据成员,不能定义其他的数据成员,只能定义公有的抽象方法,不能定义其他形式的成员方法。 接口表达了设计级的内容,在某种意义上,它比类更抽象,是类的一个框架,也是观察某个类的一个角度。 例如:某些电器可以遥控,“可遥控”就是一个接口。某些动物会游泳, “会游泳 ” 就是一个接口。,4.1.4 包,程序包:是多个类或接口的集合,它使得大型Java程序可以具有清晰的层次化结构。 程序包、子程序包、编译单元、类或接口构成了Java程序的逻辑组织结构; 目录、子目录、文件在大多数Java运行平台下构成了Java程序的物理组织结构。 程序包的作用:使得不同的类或接口的名字层次化,减少了类或接口名字的冲突,因此Java程序的重用更为方便。 标准的 Java库分为许多程序包。常用的有: java.lang(自动引入) 、 java.applet、 java.util java.awt 、 java.io、 、 java.sql、,4.1.5 方法,1. 方法的声明与调用 2. 参数调用 3. 标识符的作用域 4. 使用Java API,4.1.5 方法,1.方法的声明与调用 (1)方法的声明。 声明格式如下: 返回类型 方法名字(形式参数表) 方法体; ,格式说明:方法名字和形式参数表构成了方法的基调,所谓的基调是一种函数关系。方法名是一个Java标识符,通常根据方法所执行的功能为方法选择一个有意义的名字;形式参数表是用逗号分隔的变量声明列表,用于接收从方法调用程序传递给该方法的数据,如果该方法不需要接收数据,那么形参表可以为空。,(2) 方法的调用。,4.1.5 方法,(2)方法调用 方法调用在Java语言中是一个表达式,它的一般格式为: 方法名 (实际参数表),格式说明:实际参数表也用逗号分隔,个数和形式参数表的个数相同,类型和形式参数对应兼容。注意,即使实际参数为空,形参也为空,方法名后面的圆括号也是不能省略的。在程序设计中,经常会用到嵌套调用。即方法a调用方法b,而方法b又调用了方法c,如图4-4所示。,4.1.5 方法,2. 参数调用 Java中对参数的调用有两种方式: 对于所有的基本数据类型:采用按值调用; 而对于对象:则按引用调用。 说明: (1) 按值调用:是指当程序调用一个方法的时候,该方法的形参接收的是实际参数的拷贝而不是实际参数本身,也就是说接收的只是一个值的概念。无论在方法体中对形参作什么操作,都不会改变原来实参的值; (2) 按引用调用:是指传递的是对象的引用,也就是指向对象的指针,所以对形参的操作也就是对这个指针的操作。,4.1.5 方法,3. 标识符的作用域 标识符命名要求能表达变量的含义不要过于简短,这样既便于阅读也便于多人合作的开发。 标识符的作用域规则:(共4条 ,见课本P72 ) (1)方法的形式参数涵盖整个方法体。 (2)在块中声明的标识符其作用域从声明开始到该块结束。在嵌套块之前声明的标识符涵盖该嵌套块。所谓的块就是用花括号括住的一个区域,方法就是一个块,块中也可以嵌套块。程序举例说明 (3)在for语句初始化部分声明变量的作用域为for语句中的三部分以及整个循环体。,例如,有以下程序段: public void scope(int x) x=x+1 ; int y=x*2 ; if ( y5 ) int z=y-x ; System.out.println( x+“,“+y+“,“+z ); y=y*2 ; int z=x+5 ; System.out.println(x+“,“+y+“,“+z ); ,说明:该规则禁止了方法体中声明的局部变量隐藏同名的形式参数,也禁止在内层块中声明的变量隐藏外层声明的同名变量。,运行程序: 如果方法传入的参数为6,那么显示应该为: 7 , 14 , 7 7 , 28 , 12,3. 标识符的作用域 (4) 类中声明的方法的作用域是包含整个类的,所以方法的声明次序是无关紧要的。 注意:如果对作用域的概念比较模糊,就可能造成标识符命名冲突。例如: public void conflit( int x ) int x=0 ; int y=x+5 ; if( y4 ) int y=x-5 ; System.out.println(x+“, “+y) ; ,注意 :黄色标注的语句出现命名冲突,是错误的。,4.1.5 方法,4. 使用Java API Java语言的一个很大的优点是Java语言本身提供了非常丰富的API供程序员使用,里面包含了大量的方法,其中有很多是静态的方法。和静态变量(后面将详细讨论)的定义一样,静态方法是类的方法,当需要使用类的服务时,不需要创建对象来提供服务,而可以直接指示该类来提供服务,用下面的语法来实现: Class . methods( ); 例如,Java API 提供的Math类就有很多常用的数值运算方法,参见课本P73表4-1所示。 说明:尽量去用一些现成且久经考验的工具去完成一项工作是十分明智的,API就扮演了这样一个角色。能够熟练掌握并运用Java API提供的服务,对开发程序是十分有利的。,Java程序的结构总结:,package 语句 - 0/1 个(或)必须放在文件开始。(包说明语句) import 语句 - 0/多 个,必须放在所有类定义之前。(引入语句) 公有的(public)类定义 - 0/1 个 类定义 - 0/多 个 接口定义 - 0/多 个,说明: 一个java源文件可以有三个顶层元素, 即: 一个包说明;任意多个引入语句;类和接口的说明。,4.2 对象和类,4.2.1 类的定义 4.2.2 对象实例的创建 4.2.3 封装、继承与多态 (1)封装 (2)继承 (3)方法的重定义和方法重载 (4)多态 (5)抽象类和最终类,本节主要学习如何用Java语言将类和对象表达出来。,【类与对象之间的关系】,类与对象的关系,一个程序是对现实世界中一些实体的建模,一个实体主要包括了属性和行为特性。 类:描述实体抽象概念的程序成分。 对象:描述实体具体个体的程序成分。 【结论1】类是一组对象的集合。 数据成员(成员变量):实体的属性。 方法成员:实体的行为(操作),函数实现。 【结论2】 对象是数据和操作(代码)的封装。,【结论3】对象通过类来创建。,类结构组成图示如下一页所示。,类与对象的关系,【结论3】对象通过类来创建。,类结构组成图示如下:,4.2.1 类的定义,1. 类的声明 2. 类的访问修饰符 3. 类作用域,4.2.1 类的定义,1. 类的声明 程序举例: 类声明格式: Java程序格式说明:,4.2.1 类的定义,类的声明-程序举例 【例4-1】编写一个计算器类,可以实现加、减、乘、除四种运算。,计算器的属性(数据成员):运算结果,用变量base表示,初始值规定为0。此外还表示四种运算的第一个数据。 计算器提供功能(方法成员):分别为加法运算、减法运算、乘法运算、除法运算,可以通过函数(方法)实现。这四这种运算需要两个数据才能完成相应的操作,假设第一个数据已经在属性变量base中,方法中的形参变量给出第二个数据。此外,增加一个查询运算结果(读取base)的函数。,问题分析:,4.2.1 类的定义,类的声明 【例程4-1】 SimpleCalculator.java public class SimpleCalculator private double base = 0; /数据成员,存储计算结果 public void add( double arg ) /加法运算 base = base + arg; public void minus( double arg ) /减法运算 base = base - arg; public void multiple( double arg ) /乘法运算 base = base * arg; public void devide( double arg ) /除法运算 if (arg = 0) return; /除数为0的特殊情况 base = base / arg; public double getResult( ) /取得计算结果 return base; ,4.2.1 类的定义,程序说明: 例程4-1用关键字 public 和 class 来定义一个名字为 SimpleCalculator 的简单计算器类。 类名必须是一个有效的标识符,习惯上以大写字母开头。 类名后以花括号括住的内容称为类体,在类体中可声明多个成员,这些成员分为数据成员和方法成员。 数据成员用于定义类的属性,方法成员用于定义类的行为。,4.2.1 类的定义,类声明格式: 访问修饰符 class extends SuperclassName implements InterfaceName 类的数据成员 ; 类的方法成员 ; 构造方法 ; ,类的访问修饰符: public abstract | final ,Java程序格式说明: 一个Java 应用程序只能由一个用public声明的类,也只能由一个包含main方法的类,这个包含main方法的类称为主类。主类和用public声明的类可以是同一个类,也可以是不同的类。 文件名应该和用public声明的类名相同。 main方法是程序的入口,程序应该从包含 main方法的类开始运行。 如果某个程序中没有被声明为public的类,则可以用任意一个类的名字作为文件名,但是仍然要从包含main方法的类开始运行。,4.2.1 类的定义,4.2.1 类的定义,2. 类的访问修饰符 在Java中存在着一些修饰符,用于控制类、对象、方法的访问权限、存储空间等。 类成员(数据成员和方法成员)有四种访问控制级别:公有(public)、受保护(protected)、包级、私有(private),其开放程度各有不同。,4.2.1 类的定义,3. 类作用域,数据成员(类体中定义的变量)- 在整个类中有效。 方法成员- 在整个类中有效。 局部变量(类的方法中定义的变量)-只在定义它的方法中有效。 形式参数-只在其所在的方法中有效。 【重要用法】 在类作用域中声明的形式参数或局部变量隐藏了同名的数据成员,但是可以使用前缀 this(关键字 ,代表当前对象)访问该数据成员。 用法程序举例:课本P75 【例程4-2】。,/例程4-2:NameHiding.java public class NameHiding private double x = 0 ; public boolean set( double x ) / 这个method中的x 将屏蔽类成员 x if (x 0) this.x = x ; /使用前缀this访问类的数据成员x return true ; else return false ; public double get() double y = x * x ; double x = y + 1 ; return x ; ,public class Demothis public static void main( String args) NameHiding nh=new NameHiding( ) ; System.out.println( “nh.set(6)=“+nh.set(6) ) ; /* 类的私有成员x只能有该类中声明的方法成员来访问, *对于其他所有的类都是不可见 System. out. println( “nh.x=“+nh.x ); (错误)*/ System. out. println( “nh.get()=“+nh.get( ) ) ; ,4.2.2 对象实例的创建,1. 对象的声明与使用 2. 对象的初始化 3. 静态成员 4. 对象的参数传递方式 5. 变量和对象实例的生存期 6. 内部类,4.2.2 对象实例的创建,1. 对象的声明与使用 Java程序的基本组成单位是类,类定义了一种抽象数据类型。但是若一个程序仅由类定义组成,是无法完成任何功能的,要使用这个类就需要创建可以用于服务的类对象。利用类创建若干对象实例。让这些对象实例相互协作,能够完成指定功能。 说明:,4.2.2 对象实例的创建,1. 对象的声明与使用 说明:类除了可以将复杂程序划分为一个个模块之外,还可作为一种用户自定义的类型使用。因此它与基本数据类型一样,能够声明具体的实例,这些实例就为对象。类中定义的数据成员决定了该类的每一个对象实例的表示方法,方法成员决定了该类的每一个对象实例的可用操作。 用法程序举例:使用计算器类创建计算器对象及其运算的使用。 【例程 4-3】 SimpleCalculatorDemo.java,4.2.2 对象实例的创建,【例程4-3】SimpleCalculatorDemo.java public class SimpleCalculatorDemo public static void main(String args) /定义了一个momo计算器,初始值为0 SimpleCalculator momo = new SimpleCalculator() ; /定义了一个popo计算器,初始值为0 SimpleCalculator popo = new SimpleCalculator(); momo.add(5) ; /momo计算器加5 momo.minus(10) ; momo.multiple(3) ; momo.devide(0) ; /momo计算器除以0 popo.add(4); /popo计算器加4 popo.multiple(1);,4.2.2 对象实例的创建,/查询momo和popo的计算结果 System.out.println( “momo: “ +momo.getResult() ) ; System.out.println( “popo: “ + popo.getResult() ) ; ,说明: 程序中的SimpleCalculator类的main方法是整个程序的入口。main方法必须是public和static的,其中的第一条和第二条语句分别声明了名为momo和popo的对象。创建了对象实例后,就可以执行该对象所能够提供的计算服务。,4.2.2 对象实例的创建,2. 对象的初始化 数据成员是对象或者类的属性,不同的对象,数据成员可以不同。不同的数据成员往往标识了不同的对象。有些数据成员是非静态的,有些数据成员是静态的。 对象(数据成员 或者 成员变量)的初始化方法: (共有3种方式) 默认的初始化方法。见表4-2。 成员变量在类体中声明之后,不允许用另外的语句在类体中对它赋值,但允许在声明成员变量的同时进行赋值。 成员变量赋值操作可以在类的构造方法中进行。,4.2.2 对象实例的创建,2. 对象的初始化 下面的表4-2列出了Java中的最常用的成员变量的基本数据类型和初始值(默认)。,4.2.2 对象实例的创建,2. 对象的初始化 (1)构造方法使用说明: 构造方法的名称必须与类名相同。 构造方法必须是void型(void可省略不写),即没有返回值。 在创建一个类时系统会自动创建一个默认的构造方法(是一个没有参数的特殊的构造方法;是隐式的,它的类体在程序中不出现)。如果除了默认功能外,还要在构造方法中加入其它功能,则需显式定义构造方法。 (2)用法程序举例: 信用卡及其功能操作实现。 (3)构造方法的重载:,4.2.2 对象实例的创建,2. 对象的初始化 (2)“构造方法”程序举例:编写一个银行信用卡,它具有取钱、存钱、查询余额三个功能操作。,问题分析:,编写一个信用卡类(CreditCard) ,具有属性balance,表示信用卡的存款数;属性maxOverdraft,表示本信用卡的最大透支限额。假设用户办理的信用卡的maxOverdraft如果大于等于1000元,则银行给予奖励100元存入你的balance。此外,还包括取钱(withdraw)、存钱(deposit)、查询余额(getBalance)三大功能操作,可通过方法(函数)实现。再编写一个类,创建信用卡对象,对信用卡类进行测试。,4.2.2 对象实例的创建,2. 对象的初始化 “构造方法”用法程序举例: 编写一个银行信用卡,它具有取钱、存钱、查询余额三个功能操作。,(2)编写程序:,【例程4-4 】CreditCard.java(类定义) 【例程4-5 】CreditCardDemo. java (对象实例的创建),/例程4-4:CreditCard.java public class CreditCard private double maxOverdraft ; / 透支限额 private double balance ; / 存款余额 / 构造方法,将透支限额maxOverdraft设置为max public CreditCard( double max ) maxOverdraft=max ; if( max=1000 ) balance=100 ; else balance=0 ; / 存款金额为amount public void deposit( double amount ) balance=balance+amount ; ,/ 取款金额为amount;取款成功返回true,否则返回false public boolean withdraw( double amount ) if( amount=balance+maxOverdraft) balance=balance - amount ; return true ; else return false ; / 查询帐户的当前余额 public double getBalance( ) return balance; ,/例程4-5:CreditCardDemo . Java public class CreditCardDemo public static void main( String args ) / 为momo开设一个信用卡,允许最大透支限额为1000元 CreditCard momo=new CreditCard( 1000 ) ; / momo的信用卡存入500元后又取出100元 momo.deposit( 500 ) ; if( !momo.withdraw( 100 ) ) System.out.println( “余额不足,取款失败!“ ) ; / 为popo开设一个信用卡,允许最大透支限额为500元 CreditCard popo=new CreditCard( 500 ) ;,/ 从momo的信用卡取出700元存入popo的信用卡 if( !momo.withdraw(700) ) System.out.println(“余额不足,转帐失败!“); else popo.deposit( 700 ) ; / 查询momo和popo的信用卡余额 System.out.println( “momo的信用卡余额为“ +momo.getBalance( ) ); System.out.println( “popo的信用卡余额为“ +popo.getBalance( ) ) ; ,构造方法: 构造方法的重载:定义多个构造方法,其参数列表不同。 作用:是使类对象具有不同的初值,为类对象的初始化提供方便。 程序举例:Constructor.java 方法成员: 方法的重载:是指在一个类的方法成员(包括其继承成员)中有多个名字相同但参数列表不同的方法。 程序举例: 计算器类的加、减、乘、除四个方法可以进行重载。,4.2.2 对象实例的创建,3. 静态成员 3.1 数据成员(成员变量)的分类:有2种。 实例变量(非静态变量) - 没有 static 关键字修饰。 类变量(静态变量) -用 static 关键字修饰。 3.2 方法成员的分类: 分为2种,有静态和非静态之分。,4.2.2 对象实例的创建,3. 静态成员 实例(非静态)变量- 没有 static 关键字修饰。 使用规则: 非静态的成员变量是指每一次创建对象时都会分配一个存储空间来存储这个变量。每一个对象都拥有这个变量的存储空间,这个变量属于对象的,是对象的变量。 例如,信用卡类的成员变量balance,表示信用卡的存款数。,4.2.2 对象实例的创建,3. 静态成员,类(静态)变量 -用 static 关键字修饰。 使用规则:静态的类成员具有类属性,当创建一个对象或者说实例的时候,编译器并不会分配额外的空间给这个变量,所有的对象都共享一个变量内存空间。 用法程序举例:相同的信用卡,其最大透支限额maxOverdraft值都相同,将其定义为静态变量。 【例程4-6】UniformCreditCard.java(类定义) 【例程4-7】 UniformCreditCardDemo.java(实例创建),3.2 方法成员的分类: 类方法:用static 关键字修饰。 - 类方法只能操作类变量。 实例方法:没有static修饰 。 - 实例方法可以操作实例变量和类变量。 用法说明: 实例方法和实例变量只能通过类的对象调用。 类方法和类变量既可以通过类的对象调用也可以通过类名调用。 用法程序举例:smp34.java,3. 静态成员,3.2方法成员的分类:有2 种。 静态方法成员用法程序举例:smp34.java public class smp34 static int a1=1, a2=2; /类变量 int x; / 实例变量 smp34() x=99; public static void pntout(String s) /类方法 System.out.println(s); public static int geta1() /类方法 return a1; public void get() /实例方法 System.out.println(“a1=“+a1+“ x=“+x); ,3. 静态成员,3.2 方法成员的分类:有2 种。 静态方法成员用法程序举例:smp34.java class smp341 public static void main (String args ) smp34 abc=new smp34(); System.out.print(“1+2=“); System.out.println(abc.a2+abc.a1); System.out.println(smp34.a2+smp34.a1); System.out.println(abc.x); smp34.pntout(“你们好,朋友们!“); abc.pntout(“你们好,朋友们!“); System.out.println(“abc.a1=“+abc.geta1(); System.out.println(“smp34.a1=“+smp34.geta1(); abc.get(); ,3. 静态成员,4.2.2 对象实例的创建,4. 对象的参数传递方式 对象作为一个变量,当然也可以被作为参数传递,就像前面所说的一样,对象的传递是以引用的方式传递的。也就是说当传递一个对象的时候,其实传递的是指向对象的那个指针,即指向某一片存储区域的地址。,4.2.2 对象实例的创建,5. 变量和对象实例的生存期 成员变量的生存期如下图4-7所示。 对象实例的生存期与成员变量的生存期相比,在提供服务之后多了一个“收集”阶段,这与对象实例的初始化存在着对应关系。例如,在初始化时打开了文件,则应在收尾时关闭该文件。Java语言为每个类提供了一个finalize()方法,该方法负责执行收尾工作,在对象实例被作为垃圾收集时会被隐式调用。,6.内部类 (简单了解即可) 概念:是定义在类中的类(类支持嵌套定义) 作用:是将逻辑上相关的类放到一起。 匿名内部类:它没有类名,在定义类的同时生成该类的一个实例。由于不会在其他地方用到该类,所以不用取名字。 介绍目的:在后面学习关于Swing/AWT的章节中出现的内部类不会感到突然,这里仅仅简单举例说明匿名的内部类。 代码如下: momo.addListener ( new WindowAdapter( ) / 匿名内部类 public void windowClosing (WindowEvent e) System.exit(0); ),4.2.2 对象实例的创建,4.2.3 封装、继承与多态,1. 封装 封装:是指利用抽象数据类型将数据和基于数据的操作封装在一起,数据被保护在抽象数据类型的内部,系统的其他部分只有通过包装在数据外面的合法操作,才能够与这个抽象数据类型交互。 类的定义体现类的封装性,类是数据和操作的封装。,4.2.3 封装、继承与多态,2. 继承。 引例:水果类与桔子类、苹果类、香蕉类之间有何关系? - 类的继承关系。 使用类的继承的好处:可以使程序的整个架构具有相当的灵活性,更具有层次,提高了代码的可重用性,减少了程序设计的难度。 说明:Java类只支持类之间的单继承,即一个类至多只有一个超类。 Java中所有的类都派生自 java . lang . Object 类。 下面将详细讲解类继承的语法和实现。,4.2.3 封装、继承与多态,2. 继承 (1)类继承的定义语法格式: 在Java语言中,一个类A继承另一个已存在的类B的语法格式: public class A extends B 成员列表; 格式说明:B为基类(父类),A为B的派生类(子类)。花括号中的成员列表是派生类自己的成员。 (2)用法程序举例: (3)类的继承规则:,4.2.3 封装、继承与多态,2.继承 (2)用法程序举例: 定义一个学生父类,再编写两个子类,分别为大学生和研究生,然后再编写一个类,对子类进行用法测试。 【例程4-8 】Student.java(父类) 【例程4-9 】Undergraduate.java (子类) 【例程4-10 】Graduate.java (子类) 【例程4-11 】 StudentDemo.java (测试类),【例程4-8】:Student.java public class Student /定义父类 public final static int NUM_OF_SCORE = 3 ; /成绩个数 private String name ; / 姓名,私有成员 protected int scores ; / 成绩数组,受保护成员 public Student( ) / 构造方法一 name = “; scores = new int NUM_OF_SCORE ; public Student( String name ) / 构造方法二 = name ; scores = new int NUM_OF_SCORE ; ,public void setName(String newName) name = newName; public String getName( ) return name; public void setScore(int scoreNum, int score) / 检查参数的正确性 if( scoreNum = NUM_OF_SCORE ) return; if(score 100) return ; scores scoreNum = score ; ,public int getScore(int scoreNum) if(scoreNum = NUM_OF_SCORE) return -1 ; return scores scoreNum ; public int getAverageScore( ) / 计算学生的平均成绩 int total = 0 ; for(int i = 0; i NUM_OF_SCORE; i+) total = total + scores i ; return (int) (total/NUM_OF_SCORE) ; ,【例程4-9】:Undergraduate.java /定义子类(本科生) public class Undergraduate extends Student public String computeGrade( ) int total = 0 ; for(int i = 0; i 60 ) return “PASS“ ; else return “NO PASS“ ; ,例程4-10:Graduate.java /定义子类(研究生) public class Graduate extends Student public String computeGrade( ) int total = 0; for( int i = 0; i 80 ) return “PASS“ ; else return “NO PASS“ ; ,【例程4-11】:StudentDemo.java public class StudentDemo public static void main( String args ) / 创建第一个实例(研究生) Graduate student1 = new Graduate( ) ; student1.setName( “momo“ ) ; student1.setScore( 0, 78 ) ; student1.setScore( 1, 92 ) ; student1.setScore( 2, 72 ) ; System.out.println( “The grade of graduate student “ +student1.getName( ) +“ is +puteGrade( ) ) ;,/创建第2个实例(本科生) Undergraduate student2 = new Undergraduate() ; student2.setName( “popo“ ) ; student2.setScore( 0, 80 ) ; student2.setScore( 1, 78 ) ; student2.setScore( 2, 75 ) ; System.out.println( “ The grade of undergraduate student “ + student2.getName( ) + “ is “ + puteGrade( ) ) ; ,4.2.3 封装、继承与多态,2. 继承 (3)类的继承规则: A. 数据成员的继承规则。 B. 方法成员的继承规则。 C. 类的继承规则程序举例: 例1:jichenggz.java 例2:EmployeeTest.java,(3)类的继承规则: A.数据成员的继承规则:子类不需要重新定义就拥有了父类已有的非私有数据成员。 具体细则:有2个。 子类继承了父类的数据成员,表示子类被创建时另外开辟了新的存储空间来存储从父类继承而来的数据成员,其初值应该是父类中该数据成员的初值。但之后,就是彼此相互独立的成员变量了。即:子类继承了父类的数据成员的类型,而不是数据成员的值。,子类可以重新定义父类的非私有数据成员- 数据成员的覆盖(重定义)。 说明:这样,子类定义了一个与父类同名的数据成员,而且子类也继承了父类的该数据成员。(即子类有两个和父类同名的数据成员) 用法:通过调用该数据成员的对象或方法来决定使用哪一个。 当使用指向父类的对象时,调用的就是父类的数据成员。 当子类:执行继承自父类的操作(方法)时,处理的将是继承自父类的数据成员;执行自定义的操作(方法)时,处理的将是自定义的数据成员,或者可以使用关键字 super 来实现对继承自父类的数据成员的直接应用。,B.方法成员的继承: 继承规则:子类不需要重新定义就拥有了父类已有的非私有方法成员。 具体细则如下: 能够继承声明为 public 和 protected 的方法成员。 能够继承同一包中的默认修饰符的方法成员。 不能继承声明为 private 的方法。 不能继承父类的构造方法。 如果子类方法与父类方法同名,则不能继承,子类方法会覆盖父类的同名方法。 方法覆盖(重定义):是指子类定义了一个和父类同名且形参表相同的方法。如果子类需要调用父类的被覆盖的方法,同样用关键字 super 实现。,4.2.3 封装、继承与多态,3.方法的重定义和重载:,在子类需要有区别于父类的特殊服务时,就要使用方法的重定义和重载。 方法重定义: 是指子类对父类的方法体进行修改以达到其所需要的服务目的。重定义的方法应该和父类的方法有完全相同的接口,即有相同的返回类型、方法名和参数列表。当子类重定义了父类的方法后,如果调用子类对象的相应方法,那么父类方法就会被屏蔽。 方法重载:(是多态的一种)。 方法重载:是指在一个类的方法成员(包括其继承成员)中有多个名字相同但参数列表不同的方法。 用法程序示例:参见课本P84的例子。,public class SuperClass public void method(int x, double y) System.out.println(“SuperClass“) ; public class SubClass1 extends SuperClass public void method( int x, double y ) /方法重定义 System.out.println(“SubClass1“) ; public class SubClass2 extends SuperClass public void method( int x ) /方法重载 System.out.println(“SubClass2“) ; ,方法重定义和方法重载的用法示例:课本P84的例子,4.2.3 封装、继承与多态,4. 多态 4.1 多态的概念:就是程序中同一个符号在不同的情况下具有不同的意义。 例如:“/ ”这个符号,在操作数都是整数的时候表示整除,而如果操作数是浮点数的话就表示除法运算。 Java语言中体现:方法的重载和方法的重定义。 4.2 多态的基本形式: 有两种,分别为:编译时多态和运行时多态。而运行时多态是面向对象程序设计语言的一大特点。,4.2.3 封装、继承与多态, 编译时多态: 是指在编译阶段就可以确定下来的多态,主要通过重载来获得。即程序员用相同的两个名字或更多方法使语义非常相近的方法可以用同样的标识符来命名。 运行时多态: 是要等程序运行时才可以确定的多态性,主要通过继承和动态绑定来实现。,编译时多态: 问题:静态编译如何确定调用那个方法? 实现过程:编译器总是会去匹配最精确的方法。 假设有如下两个方法, 方法一的参数列表是: 方法二的参数列表是: 如果满足下面的条件,则方法一比方法二更精确: 定义方法一的类是定义方法二的子类型。 对于任意的i,ai和bi的类型相同或者ai的数据都能隐式类型转换为bi。 注意:Java语言的编译器在匹配最精确的方法时只考虑对象引用的静态类型,而不考虑动态类型 程序举例:课本P85:【例程4-12】 SuperClass.java 【例程4-13】SubClass.java【例程4-14】OverloadDemo.java,4. 多态,运行时多态。 是要等程序运行时才可以确定的多态性,主要通过继承和动态绑定来实现。 动态邦定: 子类继承父类并重定义父类的方法,如果对象引用的是父类的实例,JVM调用父类的方法,而如果引用的是子类的实例,那么JVM调用子类的方法。 注意:Java中的任何数据类型都在编译时确定了其静态类型:基本数据类型只有静态类型;而对象引用有静态类型和动态类型,动态类型在运时确定而且肯定是静态类型的子类型。 实现过程:,4. 多态,实现过程: 先是静态绑定(即:在编译时确定最精确的方法),再是动态邦定(邦定最精确的方法可能具有重定义的版本)。 解释说明: 运行时,JVM会检查对象的动态类型,然后调用在编译时确定的最精确的方法在动态类型对应类中的方法版本。如果对象引用的静态类型和动态类型不同,而且动态类型所对应的类重定义了这个最精确的方法,那么运行时,实际调用的方法就是这个重定义的方法。 用法程序示例:(课本P87) 例1:yshduotai.java 例2:superclass.java, subclass.java, yun2.java,4. 多态,4.3 接口,4.3.1 接口的作用 4.3.2 接口的声明 4.3.3 接口的实现 4.3.4 接口的继承,问题引入:电视机和遥控器之间的关系?,答案:类和接口的关系。,4.3.1 接口的作用 (有4点),1. 在某种意义上,接口是对类的一种观察。 类实现了某个接口,说明该类可以在某种角度被观察。 2. 接口本质上是使用者和实现者的一组约束的抽象,接口也是程序的组成单位,但是接口表示的是一种设计级的内容而不是实现级的内容。 方法的接口:是指方法的返回值类型、方法名、参数类型。 类的接口:是指类提供给其他类可访问的数据成员和方法成员。,3. 接口相当于纯抽象类,即只有抽象方法的类。 接口只能定义公有的静态常量数据成员,不能定义其他形式的数据成员。只能定义公有的抽象方法,不能定义其他形式的方法成员。 接口没有实现,也不能创建任何实例。,4.3.1 接口的作用,4.3.1 接口的作用,4. Java语言不允许类的多继承,但允许一个类实现多个接口。 例如,现实生活中一个物体也是可以从多角度观察的。比如:一个电视机,可以是“可遥控的”、“可上网的”。) ( 同时:一个接口可以被多个类实现)。 总结说明:接口不同于类,Java语言的类继承是单根的,所有的类都派生自 java . lang . Object 类,但接口允许多继承,所以不存在一个接口是所有接口的祖先接口。,4.3.2 接口的声明,接口的声明语法与类的声明语法类似。 1. 接口的声
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 智能建筑设计软件合同
- 废旧资产处置协议书
- 政府资金申报协议书
- 挂名股东退股协议书
- 房屋更换门窗协议书
- 担保公司合营协议书
- 快递转让经营协议书
- 广告入围合同协议书
- 房产转赠家庭协议书
- 房屋过户他人协议书
- 环宇电子科技公司镀膜铣刀生产项目环评资料环境影响
- 2025物业管理服务承包合同范本
- 企业所得税课件
- 2025年高考政治核心知识总结
- 2025广西中马钦州产业园区投资控股集团限公司招聘49人易考易错模拟试题(共500题)试卷后附参考答案
- 工程过账协议合同协议
- 托管中心晚辅老师培训
- 兼职顾问服务合同范本
- 人教版(新教材)高中物理选择性必修2教学设计2:2 2 法拉第电磁感应定律教案
- 2024-2025学年人教版数学八年级下册期中押题重难点检测卷(含答案)
- 广西地方公路养护工程预算定额
评论
0/150
提交评论