ImageVerifierCode 换一换
格式:PPT , 页数:86 ,大小:1.56MB ,
资源ID:503643      下载积分:10 文钱
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,省得不是一点点
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.wenke99.com/d-503643.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Java程序设计系列讲座-2OOP之封装性.PPT)为本站会员(国***)主动上传,文客久久仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文客久久(发送邮件至hr@wenke99.com或直接QQ联系客服),我们立即给予删除!

Java程序设计系列讲座-2OOP之封装性.PPT

1、Java程序设计系列讲座2OOP之封装性,黄绍辉厦门大学计算机科学系E-mail: ,面向对象程序设计基本思想,对象的基本概念对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。对象是问题域或实现域中某些事物的一个抽象,它反映该事物在系统中需要保存的信息和发挥的作用;它是一组属性和有权对这些属性进行操作的一组服务的封装体。客观世界是由对象和对象之间的联系组成。,类的基本概念,类是具有相同属性和服务的一组对象的集合。分类的原则是抽象。在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属性说明和服务说明两个主

2、要部分。类与对象的关系就如模具和铸件的关系,类的实例化结果就是对象,而对一类对象的抽象就是类。,关于OOPObject Oriented Programming,对象是基本编程单位。与此对应,Java使用类(class)表示对象,一个class就是一个类;对象由一组属性和一组服务两部分组成(两部分不必都存在)。与此对应,Java使用一组成员变量(member variable)表示属性,一组成员函数(member method)表示服务。,OOP的例子,例如我们要表示一个遥控器对象,它起码有两个属性:外壳,按钮。它起码有两个功能:换台,调音量。使用Java来设计这个对象,它看起来就是这个样子:

3、class 遥控器 外壳成员 按钮成员 换台函数() 调音量函数(),OOP的基本特征,封装性把对象的属性和服务结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节。继承性从一个已有的类来构造新类,除了保留原有的类的特性,还增加了一些新特性。已有的类称为父类superclass,新类称为子类subclass。多态性在父类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。,OOP-Part I 封装性,从C语言开始出发,任务:在程序中实现对时间的一些操作思路:时间是一个整体,包括时/分/秒,为了在程序中表示一个具体的时间,这三个部份缺一不可。最自然的,可以采用三个整型

4、变量来存储这三个部份,例如:int hour;int minute;int second;,C程序示例,void main()int hour,minute,second; hour=12; minute=12; second=12; printf(“Time is %d:%d:%d”,hour,minute,second);,如果有很多个时间,void main()int hour1,minute1,second1;int hour2,minute2,second2;int hour3,minute3,second3;printf(“Time1 is %d:%d:%d”,hour1,minu

5、te1,second1);printf(“Time2 is %d:%d:%d”,hour2,minute2,second2);printf(“Time3 is %d:%d:%d”,hour3,minute3,second3);,如果用数组,void main()int hour100,minute100,second100;for(int i=0;ihour +;,使用示例:struct MyTime t;t = AddOneHour(t);,使用示例:struct MyTime t;AddOneHour(,关于上面两个函数的探讨,前面说过,struct MyTime已经可以看成是对象了,从上

6、面的两个函数可以看出,为了修改对象的属性,比较好的作法,是(通过指针)直接修改对象本身的属性,代码简单,效率也高。但是C毕竟是面向过程的语言,实现 “对象的加工”或者叫“对象的服务”,需要借助struct MyTime之外的函数AddOneHour完成。OOP语言的第一个方便之处,就是把属性和服务整合到同一个对象中,这给编程带来了极大的方便,例如:,Java版本的AddOneHour,class MyTimeint hour;int minute;int second;void AddOneHour() hour+; ,使用示例:MyTime t=new MyTime();t.AddOneHo

7、ur();,把属性和服务整合到同一个对象内部的最大好处,是你不再需要将一个结构作为一个参数传入到外部的处理函数,也不需要考虑将处理后的结果从函数传出,甚至贴代码的时候,都不用担心会少贴一个函数,看出封装的好处了吗?,C的结构可以存储数据,但是不能包含函数,因此必须在其它的地方定义函数。这个做法可能导致以下后果:调用不方便,参数要传入传出毕竟是比较麻烦的可能和别人写的函数产生冲突(例如重名)代码的重用和修改不方便Java可以将数据和处理函数一起封装,因此数据以及对数据的加工都可以在同一个对象当中完成。,总结一下封装性,OOP中,对象就是对一组变量和相关方法的封装,其中变量表明了对象的状态,方法表

8、明了对象具有的行为。简单一点说,封装性指的是:属性和函数都放在同一个对象的内部。对Java而言就是:一个class可以内部可以有多个成员变量和多个成员函数;成员函数可以直接访问成员变量,并对其进行修改。通过对象的封装,实现了模块化和信息隐藏。,跑步进入OOP有个例子,从简单对象入手,对象不是很深奥的东西,一个对象在Java里面就是一个class而已。例如随便写一个对象:class Point /首字母大写是Java建议的对象命名规则 int x,y;这个Point对象可以用来表示平面上的一个点。注意Java并不要求对象一定要有成员函数,所以这个对象已经很完整,只是还不够好用而已,接下来我们会逐

9、步完善它。,对象的用法,要使用一个已有的对象不是太难,但是你要做足以下的两件事情:使用对象的名字声明一个变量创建对象的一个实例用上面的Point做例子,就是这样:使用对象的名字声明一个变量 Point p;创建对象的一个实例 p = new Point();接下来这个p就拥有了Point的全部资源,例如它有两个成员变量,叫x,y,而且还是整型的。,对象的用法,对象的声明和创建可以合成一步:Point p = new Point();当然也可以隔了很多步:Point p;/* 中间有很多很多很多行,但是和p无关 */p = new Point();只有一个准则:对象在创建之前是不能使用的,所以n

10、ew很重要。,对象与实例,前面说到,对象必须创建才能使用,所以你必须这样创建p:Point p = new Point();这里引入几个术语: Point 是类名,也是对象名,或者干脆叫对象 p 是对象的实例,也就是Point的实例你可以理解对象是一个图章,它每盖章一次(new一次)生成一个p,p就是一个实例。,一个完整例子:Test.java,class Point int x,y;public class Test public static void main(String args) Point p = new Point(); System.out.println(“p.x=”+p.

11、x+“ p.y=”+p.y); p.x = 1; p.y = 2; System.out.println(“p.x=”+p.x+“ p.y=”+p.y); ,插播一下:数组,使用对象,我们刚刚学会两招:招式一:对象可以同时拥有属性和函数;招式二:对象要new以后才能使用下面我们来用这两招对付Java的一个常用对象:数组。和C语言不同,Java把数组设计成了对象,所以根据我们的招式二,Java的数组必须先new才能使用。如果你能够意识到这一点,那么恭喜你,OOP入门成功,数组入门1,1 声明一个数组dataType arrayRefVar;或 dataType arrayRefVar; 例如:d

12、ouble myList;2 创建一个数组arrayRefVar = new dataTypearraySize;如:myList = new double10;,数组入门2,声明并创建一个数组dataType arrayRefVar = new dataTypearraySize;或 dataType arrayRefVar = new dataTypearraySize;例如:double myList = new double10;,数组入门3,数组在创建之后,Java会为这个数组自动分配空间。(注意声明数组的时候并没有分配数组元素空间,因为那时候不知道数组多大),数组入门4,任何一个数

13、组,都可以通过属性length得到数组的长度。如: myList.length数组创建的时候会自动赋零值,对于数值型的,就是0或者0.0或者0,对于布尔型的,就是false任何一个数组,其元素的最小下标是0,最大下标是length-1数组下标越界会引发异常,数组入门5,数组元素的引用使用 ,以下两个方法可以打印出数组myList的每一个元素值:for (int i = 0; i myList.length; i+) System.out.print( +myListi);或者(JDK1.5以上版本才支持的)for (int val : myList) System.out.print( +va

14、l);,数组入门6,数组在创建的时候可以顺便初始化,如:double myList = 1.9, 2.9, 3.4, 3.5;它相当于:double myList = new double4;myList0 = 1.9;myList1 = 2.9;myList2 = 3.4;myList3 = 3.5;,数组例程1/3,用100以内随机数初始化数组for (int i = 0; i myList.length; i+) myListi = Math.random() * 100;,数组例程2/3,数组求和double total = 0;for (int i = 0; i myList.len

15、gth; i+) total += myListi;,数组例程3/3,求数组中的最大值double max = myList0;for (int i = 1; i max) max = myListi;,数组作为函数参数1,数组作为参数,Java采用的是引用传递方式,基本数据类型(int,char等)作为参数,采用值传递方式。简单一点说,引用传递方式,实际参数和形式参数,操作的其实是同一个对象;值传递方式,实际参数和形式参数,操作的是不同对象,仅仅是这两个对象的值相等而已。,数组作为函数参数2,public class Test public static void main(String a

16、rgs) int x = 1; / x represents an int value int y = new int10; / y represents an array of int values m(x, y); / Invoke m with arguments x and y System.out.println(x is + x); / x值不变,还是1 System.out.println(y0 is + y0); / y0值已改变,本来是0的 public static void m(int number, int numbers) number = 1001; / Assig

17、n a new value to number numbers0 = 5555; / Assign a new value to numbers0 ,数组作为函数参数3,1 public class TestPassArray 2 /* Main method */ 3 public static void main(String args) 4 int a = 1, 2; 5 6 / Swap elements using the swap method 7 System.out.println(Before invoking swap); 8 System.out.println(arra

18、y is + a0 + , + a1 + ); 9 swap(a0, a1); /值传递,返回后不改变原值10 System.out.println(After invoking swap);11 System.out.println(array is + a0 + , + a1 + );1213 / Swap elements using the swapFirstTwoInArray method14 System.out.println(Before invoking swapFirstTwoInArray);15 System.out.println(array is + a0 + ,

19、 + a1 + );16 swapFirstTwoInArray(a); /引用传递,返回后原值可能改变17 System.out.println(After invoking swapFirstTwoInArray);18 System.out.println(array is + a0 + , + a1 + );19 ,数组作为函数参数4,20 /值传递,返回后不改变原值21 /* Swap two variables */22 public static void swap(int n1, int n2) 23 int temp = n1;24 n1 = n2;25 n2 = temp;

20、26 27 /引用传递,返回后原值可能改变28 /* Swap the first two elements in the array */29 public static void swapFirstTwoInArray(int array) 30 int temp = array0;31 array0 = array1;32 array1 = temp;33 34 ,多维数组1,二维数组的定义dataType arrayRefVar;或 dataType arrayRefVar; 例如:int matrix;或 int matrix;注意,这里仅仅说明matrix是一个二维数组,但是这个数

21、组的大小还未知,所以还不能存储元素。,多维数组2,二维数组有行和列的概念,如:,多维数组3,二维数组可以在声明的时候赋初值,也可以在new之后再一个一个慢慢赋值。其实二维数组行和行之间是相互独立的,每一行都相当于一个一维数组。,由于二维数组的每一行是一个一维数组,所以这些一维数组的大小不必相等,如:此时:triangleArray.length = 5, /因为数组有5行triangleArray0.length = 5, triangleArray1.length = 4, triangleArray2.length = 3, triangleArray3.length = 2, trian

22、gleArray4.length = 1.,多维数组4,二维数组例程1,随机数填充for (int row = 0; row matrix.length; row+) for (int column = 0; column matrixrow.length; column+) matrixrowcolumn = (int)(Math.random() * 100); 这里matrix是二维数组。过一遍二维数组必须用两层的循环,一般用i循环行,j循环列;如果英文好一点,可以用row循环行,column或者col循环列。,二维数组例程2,打印数组元素for (int row = 0; row ma

23、trix.length; row+) for (int column = 0; column matrixrow.length; column+) System.out.print(matrixrowcolumn + ); System.out.println();,二维数组例程3,数组求和int total = 0;for (int row = 0; row matrix.length; row+) for (int column = 0; column matrixrow.length; column+) total += matrixrowcolumn; ,杨辉三角的例子,public

24、class Yanghui public static void main(String args) int a=new int1010; for(int i=0;i10;i+) for(int j=0;j=i;j+) if(j=0|i=j) aij=1; if (i9) ai+1j+1=aij+aij+1; System.out.print(aij+ ); System.out.println(); ,研究一下构造函数,创建对象,前面说到,对象必须创建才能使用,那么创建对象Point是不是只有一种方法呢?默认的显然是只有一种,所以你只能这样创建p:Point p1 = new Point()

25、;但是实际生活里,我们必须有多种途径来创建对象,这样用起来才方便。例如你可能希望这样创建: Point p2 = new Point(1,2); 然后期待着p2的x和y成员分别是1和2,如何做到这一点呢?,什么是构造函数,可不可以换一种方式创建Point?当然可以,不过你要自己加构造函数,例如:class Point int x,y; Point(int xx, int yy) x=xx;y=yy;注意上面那个函数,它有两大神奇之处:没有定义返回值,连void都没有名字和类的名字完全一样这种写法奇怪的函数就是传说中的:构造函数,默认构造函数,现在你终于可以这样创建一个p了: Point p =

26、 new Point(1,2);不过你现在反而不能这样创建一个p了:Point p = new Point(); why?,关于构造函数 I,构造函数和类的名字完全一样,并且没有返回值,它的作用是提供类的创建方式,所以,根据类必须先创建再使用的原则,构造函数是每一个类一定要具备的东西。或许你注意到第一个版本的Point没有构造函数,是的,不过Java是这样聪明的一个语言,所以它会帮你补充一个不带参数,没有函数体的构造函数,例如Point类,它偷偷加的代码是:class Point int x,y; Point() /这一行尽管你没看见,但是它确实存在,关于构造函数 II,Java自动提供构造函

27、数仅仅当你自己没有提供构造函数的时候才这么干,如果你提供了哪怕只有一个的构造函数,它决不自作多情帮你加一个。所以第二个版本的Point最好改成下面:class Point int x,y; Point() /由于Java罢工,这个函数只好自己加 Point(int xx, int yy) x=xx;y=yy;,关于成员变量对内篇,每一个类都可以有自己的成员变量,例如Point类的x和y;对于Point类的内部而言,x,y相当于全局变量;如果脱开Point类,那么就要看x,y是怎么声明的了。class Point Point() x=10; y=10; Point(int xx, int yy)

28、 x=xx;y=yy; int x,y; ,x,y的作用范围从这里开始,x,y的作用范围到这里结束,关于成员变量对外篇,成员变量有四种修饰,它们决定了外部访问成员变量的权限:private,default,protected、public对于private,实际上是不允许外部访问的,所以如果你的Point这样定义:class Point private int x,y;然后有 Point p = new Point();那么这两个语句是错的:p.x=10; p.y=10;,关于成员变量对外篇,如果这个时候你想从外面修改x,y的值怎么办?答案是:没法改!除非Point类另外提供函数给你用,例如:

29、class Point private int x,y; public int getX() return x; /这就是传说中的getter public void setX(int xx) x=xx; /传说中的setter上帝保佑,现在你终于可以从外面改x的值了:Point p = new Point();p.setX(100); System.out.print(p.getX();,关于成员函数 I,成员函数的访问权限和成员变量完全一样,所以这里不重复了。成员函数的调用,也要通过对象的实例才能够调用(当然静态函数除外,后面再讲),不会忘记什么叫对象的实例了吧?Oh, my God!还是

30、加一个函数试试,例如我们给Point加一个成员函数:public double test(double s) return x*y*s; ,关于成员函数 II,现在我们来调这个函数(这里是在外部调,如果在类的内部调,那就直接调用就好了)Point p = new Point(3,4);System.out.print(p.test(5.0); /通过p调用test函数还是不太放心,演示一下对象内部怎么调test:class Point private int x,y; public double f() return test(5.0); public double test(double s

31、) return x*y*s; ,关于成员函数 III,总结一下,一个类的成员函数:对于类的内部而言,是直接抓过来随便爱怎么调用都行(多大公无私啊),不需要借助任何东西;对于类的外部而言,如果是private的成员函数,那显然是不能用的;如果遇到public的,那运气还不错,可以通过创建一个类的实例(也就是new一下),来间接调用这个成员函数。成员变量的结论与此类似。顺便说一下,在一个类的外部,每次new一个实例的时候,相当于调用一次构造函数;至于调用的是哪一个构造函数,那要看你给的参数了。,关于静态方法和静态成员 I,如果一个class有一个static的成员,那使用的时候要小心一点。给一个

32、例子:class A public int x; public static int y; public static void f() System.out.print(x+y); 还记得怎么调用f,怎么使用x,y么?很简单:A a = new A(); /看到这句不要晕掉,好多a.a.x = 10; a.y = 10; a.f(); /调用函数f,不要参数,关于静态方法和静态成员 II,下面来一段复杂的测试代码,测试A这个类:class Test public static void main(String args) A a = new A(); a.x = 10; a.y = 10;

33、A b = new A(); b.x = 100; b.y = 100; System.out.print(a.x=+a.x+a.y=+a.y+b.x=+b.x+b.y=+b.y); 运行上面程序,你会发现一个奇怪的现象:a.x不等于b.x,可是a.y居然等于b.y前一半比较好理解,因为a和b本来就是不同的实例,虽然它们是一个模子造出来的;可是,那y怎么回事?,关于静态方法和静态成员 III,其实,静态成员是如此特殊的一个东西,因为它是所有实例共享的!也就是无论你new多少个实例出来,静态成员自始至终就是一个而已。而且,就算是你没有new过实例,它就已经存在了,神奇吧?所以,java鼓励你这样

34、直接使用静态成员:A.y = 100; A.f(); /注意这里没有实例噢,A亲自上阵了所以,静态成员变量在java里一般被用作共享的常数,例如Math.PI,所以你可以常常看到final和static一起混的情形;静态成员函数一般被用作全局函数,供任意类调用,例如Math.sin(),再次啰唆一下类成员的访问控制,类成员总共有四种访问模式:private,protected,public以及default,它们的访问控制如下:确定访问控制权限的原则基于安全性的考虑,在能满足设计要求的前提下,访问权限越严格越好,一个例子,class Root private int a; protected

35、float b; public double c; char d; void fun() a+; b+; c+; d+; /类的内部,成员变量相当于全局 /变量,在任何函数中均可直接用 假设有一个类的实例 Root r = new Root();那么 r.a+就是错误的,因为这相当于在类的外部使用变量;但是 r.c+是正确的,因为c是public,支持外部访问。,关于封装的进一步探讨,Java的封装属性有四个(按开放程度排序): private,default,protected以及public。一般来说,封装越严格越好,因此尽量不要将成员变量设置为public。当把成员变量设置为privat

36、e时,为了能够提供外部类对这些成员变量的存取,一般要设置一堆的public的get方法和set方法。例如对hour成员:public int getHour() return hour; public void setHour(int h) hour = h; ,方法重载,方法重载是指多个方法享有相同的名字,但是这些方法的参数必须不同,或者是参数的个数不同,或者是参数类型不同。返回类型不能用来区分重载的方法。,再次啰唆一下构造方法, 构造方法是一个特殊的方法。Java 中的每个类都有构造方法,用来初始化该类的一个对象。 构造方法具有和类名相同的名称,而且不返回任何数据类型。 重载经常用于构造方

37、法。 构造方法只能由new运算符调用。,关于构造方法以及new,要生成一个对象的实例,必须使用new运算符。每次new的时候,对象的构造方法会被自动调用。构造的方法可能有很多个,new的时候调用哪一个取决于new的时候带的参数。例如:MyTime t1=new MyTime(); /调用无参数的构造方法MyTime t2=new MyTime(hour, second, minute);/调用使用三个参数的构造方法,注意三个参数的类型/要和构造方法声明的参数类型保持一致,一个练习,写一个类Person表示一个人,用name和age表示其姓名和年龄,并提供以下三个构造函数: Person();

38、/默认名字为 noname,年龄为0 Person(String name); /年龄默认为0 Person(String name, int age);在main函数中使用以上三种构造方式创建3个Person对象,然后输出。,异常,异常和异常类型,异常是程序运行时发生的错误。当异常发生时,常常导致程序崩溃,从而丢失尚未保存的数据。用户输入非法是异常的主要来源,例如:,异常是可以捕捉的,Java允许你自己去捕捉异常,从而避免程序崩溃。例如上例可以修改为:,异常处理(I),异常分类:受检异常(编程时一定要检测的异常)非受检异常异常的层次:,异常处理(II),异常产生:运行时(被动)产生主动抛出t

39、hrow异常处理捕获try.catch( ExceptionName1 e ).catch( ExceptionName2 e ).finally.,异常处理(III), try 捕获例外的第一步是用try选定捕获例外的范围,由try所限定的代码块中的语句在执行过程中可能会生成例外对象并抛弃。 catch 每个try代码块可以伴随一个或多个catch语句,用于处理try代码块中所生成的例外事件。catch语句只需要一个形式参数指明它所能够捕获的例外类型,这个类必须是Throwable的子类,运行时系统通过参数值把被抛弃的例外对象传递给catch块。,异常处理(IV), catch 语句的顺序:

40、捕获例外的顺序和catch语句的顺序有关,当捕获到一个例外时,剩下的catch语句就不再进行匹配。因此,在安排catch语句的顺序时,首先应该捕获最特殊的例外,然后再逐渐一般化。也就是一般先安排子类,再安排父类。 finally捕获例外的最后一步是通过finally语句为例外处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,finally块中的语句都会被执行。,异常处理(V),当你不希望自己处理异常时,可以尝试将其抛出,让上一级代码去catch这个棘手的问题;当然如果整个程序都没有能catch到这个异常,那这个程序只好死定了抛出异常的两种做法让方法抛出异常,方法内不处理public static void main(String args) throws IOException,IndexOutOfBoundsException主动抛出IOException e=new IOException();throw e;,

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。