




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
面向对象知识小结及答疑一、面向对象基本概念回顾Java的面向对象概念,绝大部分是模拟现实世界中的事物而设计的。继承:根据功能和用途,将类按照层次关系进行设计。越在下层的类,功能越多越具体;越在上层的类,其“权力”越大。类一方面使得学习出现了暂时的困难,但也使得代码的复用变得很有意思。系统提供的标准类,其名字必须要经常查阅翻译辞典以加深印象。 构造方法:对象在新生成的时候必须要执行的方法,名字应该和类名字完全一致。 class A int x; A() x = 2; A(int x) this.x = x; void print() System.out.println(“x=” + x); 默认情况下,A()构造方法默认是会自动生成的,当然里面一点代码都没有(也就是说,你不写的话,系统会帮你写上一个空架子的构造方法)。构造方法前面必须是没有“返回类型”的。另外,类中的任何除构造方法之外的其它方法必须要“返回类型”的。方法重载:在类中存在两个同名的方法,但方法的参数类型不相同。 void print(int x) void print(int a) 注意,上面写的这两个方法不能叫重载的(参数个数、类型完全相同)方法重写/覆盖:在子类和父中存在两个同名、同参数的方法。访问修饰符:private,protected,public,(默认) static,final对类中的一个static方法来说,它可以直接通过类名进行调用,而不需要生成对象。final放在一个变量前面,表示这是一个常量,只能有一个值。final放在一个方法前面,表示这是一个不能被覆盖的方法。final放在一个类前面,表示这是一个最终类,它不能被别的类继承。抽象类:就是在class之前加了一个abstract的类,这样的类就不能用来生成对象了。因此,通常如果一个类不适合生成对象的话,我们就要把这个类定义成抽象的。或者,如果一个类中包含了没有方法体的方法(也就是抽象方法),这样的类也必须定义成抽象类。其它类继承了抽象类的话,就必须补全这个抽象类中的所有抽象方法的具体代码。abstract class A int x; abstract void print();接口:在其中只定义抽象方法。接口的目的,是为了强制某些类中必须具有同样的方法。因此,只要类实现了接口,这些类就必须提供接口中方法的具体代码。因此这些类看起来就有了一些共性了(都包含了接口中规定的方法)。这是接口的一个强制规定。此外,接口中的抽象方法必须是public的,如果不写上的话,系统会自定帮我们加上。习惯上我们还是自己写上public。interface C public void print();class A implements C int x; public void print() System.out.println(“x=” + x); class B implements C public void print() System.out.println(“hello”); 上面的类A和类B因为实现了接口C,它们就必须提供接口C中规定的方法/函数,否则编译就报错了。这就是接口的一大特点。接口可以这样使用:C c = new A();c.print(); / 其实是调用A类的对象中的print()方法c = new B();c.print(); / 其实是调用B类的对象中的print()方法可见,接口变量能够指向任何实现了该接口的类的对象,但只能调用对象中的那些“由接口规定的”方法。对接口变量c来讲,无论它指向的是A类对象还是B类对象,接口变量c只知道对象中有print()方法(也就是接口C中规定的方法),对象中的其它内容,接口变量c则一无所知。如同一个USB接口,可以插上任何实现了USB接口的实际设备,如插上优盘、移动硬盘等等。但是若移动硬盘还有MP3播放功能的话,我们的USB接口也不会知道。USB接口仍会把这种带有MP3播放功能的移动硬盘当作普通的移动硬盘来对待。 那么在Java中又为什么需要接口呢?我们再看上面的这两个类,改写一下(去掉了implements C语句):class A int x; public void print() System.out.println(“x=” + x); class B public void print() System.out.println(“hello”); 现在的类A、B定义只是少了implements C,里面的内容和前面一模一样。唯一的不同是,类A、B里面的方法名字可以随便更改了(不会受任何约束):class A int x; public void print222() System.out.println(“x=” + x); class B public void show() System.out.println(“-”); 我们看到,现在的A、B类里面已经乱七八糟了,甚至B类中连print()方法都没有了。但这两个类在编译时没有任何问题,它们只是没有遵守统一的接口约定而已。为了更好地理解面向对象这些概念,请同学们务必仔细琢磨明白提供的那几个程序文件:子类构造方法Abc.java抽象类Abc.java接口Abc.java方法修饰符Abc.java方法重写Abc.java方法重载Abc.java继承Abc.java访问修饰符Abc.java二、异常异常的设计,主要是提供一种集中处理问题的机制。大家体会一下下面的两个例子。这个例子是教材上的一个上机练习(教材第329页的练习1),其目的是计算一个从键盘输入数的阶乘(args0就是一个从键盘上输入的数字字符串)。常规的做法是这样的: / 判断是否在命令行中输入了字符串。args是一个数组变量/ 如果数组大小少于1的话,说明使用者没有输入要计算阶乘的那个数 if (args.length 1) System.out.println(请提供一个数字!); return; / 判断输入的字符串是否全部是数字。我们只要判断字符串args0中/ 包含的每一个字符是否都是数字,就可以确定输入的是否是数字 String str = args0;for(int i=0; istr.length(); i+) if(str.charAt(i) 9) System.out.println(提供的参数不是数字); return; / 将从键盘输入的数字字符串转换成一个整数,并是否是正数num = Integer.parseInt(args0);if (num = 0) System.out.println(难道要计算负数的阶乘?); return; / 计算num的阶乘,存放在n变量中for (i=1; i=num; i+)n = n * i;System.out.println(args0 + 的阶乘是: + n);我们发现,如果是按常规做法,步骤非常繁琐。而如果使用try-catch的话就好很多:try num = Integer.parseInt(args0);if (num = 0)throw new IllegalArgumentException();for (i=1; i=num; i+)n = n * i;System.out.println(args0 + 的阶乘是: + n); catch(ArrayIndexOutOfBoundsException e1) System.out.println(请提供一个数字!); catch(NumberFormatException e2) System.out.println(提供的参数不是数字); catch(IllegalArgumentException e3) System.out.println(难道要计算负数的阶乘?);上面的代码是标准的参考代码,使用try-catch可以看出代码的清晰程度(我们将来会大量使用下面的这种处理问题的方式)。如果try中的任一行代码在执行时抛出一个异常的话,接下来的catch就要开始工作了。如果我们要使得一个普通方法在调用时也有能力抛出异常,我们就需要这样定义我们自己写的方法:void check(int x) throws IllegalArgumentException if (x 0) throw new IllegalArgumentException ();这个方法和普通方法差不多,就是后面跟着一个:throws IllegalArgumentException,表示这个方法有可能会抛出一个IllegalArgumentException这样的异常,因此在调用时就必须通过try-catch进行捕捉处理。现在可以这样调用上面的check()方法了:try num = Integer.parseInt(args0);check(num);for (i=1; i=num; i+)n = n * i;System.out.println(args0 + 的阶乘是: + n); catch(ArrayIndexOutOfBoundsException e1) System.out.println(请提供一个数字!); catch(NumberFormatException e2) System.out.println(提供的参数不是数字); catch(IllegalArgumentException e3) System.out.println(难道要计算负数的阶乘?);你可以想像一下,系统中的Integer.parseInt()方法就是按照类似我们上面的做法实现的。 现在有同学就会问了,我们怎么知道什么时候要抛出什么样的异常呢?其实,上面我们只是选择了一个标准的异常类IllegalArgumentException(非法参数异常。Illegal是“非法”的意思,Argument是“参数”的意思,Exception是“异常”的意思)。我们在课堂中给大家看了一些从Exception继承而来的标准异常类,如果这些类可以使用的话,我们就可以直接选择其中一个适合我们处理情况的类来使用,就像我们上面做的一样。否则,就要自定义异常类了(必须从Exception继承): class FushuException extends Exception FushuException() / 构造方法 super(负数异常); void check(int x) throws FushuException if (x 0) throw new FushuException ();或者在try中直接这样做:if (x0) throw new FushuException (); 大家要注意,try-catch-finally异常处理只是提供了一种更方便的“处理问题”的方式。其实你完全可以在执行代码时用if去做一大堆判断,如同前面的代码。这样做的思路不怎样清晰,也就是说“执行的操作”和“问题处理”全部揉合在一起,不便于我们的观察分析。因此,大家必须先掌握异常处理的这种手段,以后我们会不断地接触到其它地方是怎样使用try-catch做异常处理的。通过不断的接触、观察、分析、总结,从而我们就能模仿着写自己的异常处理了。另外,Integer是一个独立的类,表示“整数类”的意思,其中包含了一个int值。但它和int又是有区别的,int只是单纯的一个整数,没有其它任何东西;Integer是一个类(想像一下结构体),里面包含了属性字段变量和方法/函数。以下是从JDK文档中摘录出来的对Integer类的描述:public final class Integer extends Number implements ComparableInteger 类在对象中包装了一个基本类型 int 的值。Integer 类型的对象包含一个 int 类型的字段。 此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。三、Java语言学习指导和答疑1、Java是由许许多多的“类”构成的,这些类有的是抽象类,有的类又实现了一些接口(遵从了接口中的方法/函数约定)。但基本上是一个类就负责“一块事情”。类名字是有规律的,类名单词的第一个字母总是大写的。 2、我们经常接触的类是必须要知道的。也就是说,类名单词只能记下来。当然,记下来并没有那么痛苦,我们可以将经常接触到的类名写在一个本子上,经常翻阅。比如仿照下面的方式: String 字符串类,包含了许多处理字符串的方法 Integer 整数类,包含了许多处理整数的方法 至于类里面包含的方法的具体使用,我们完全可以通过JDK文档查阅到。3、Java中显得复杂的内容,就是类。我们将来会不断地遇到很多的类。初学者往往会觉得Java的难就难在类太多,很乱。这在开始是属于正常现象。随着我们学习的推进,大家会慢慢理清这些内容的。4、几乎所有同学课题上都不做笔记。难怪同学们在课堂上听起来比较舒服,课后就什么都不懂了!笔记怎么做?碰到难的问题或者老师一再强调的地方,记录一下要点,以便课后查阅。不是不分重点一股脑儿什么都记录下来,也不是做课堂录音。答疑1:为什么在定义类时,习惯上将属性字段写成private的,而将方法写成public的?class Bear int legs; public void show() System.out.println(本熊有 + legs + 条腿); class Test public static void main(String args) Bear b1, b2;b1 = new Bear(); b1.legs = 4; b1.show(); System.out.println(这只熊确实有 + b1.legs + 条腿); b2 = new Bear(); b2.legs = -2; b2.show(); System.out.println(这只熊确实有 + b2.legs + 条腿); 我们可以看到上面的b2.legs赋值明显是不合逻辑的,腿的数量不可能是负数。那么有没有什么办法来控制这种情况?我们知道,因为legs字段变量是在类Bear中被管辖的,因此最好让Bear类来负责这件事情。因此改变成现在这样:class Bear int legs; public void show() System.out.println(本熊有 + legs + 条腿); public void setLegs(int legs) if (legs 0) this.legs = 4; else this.legs = legs; 我们希望编程人员使用setLegs()方法来设置熊的腿数量: b1.setLegs(3); b1.show(); System.out.println(这只熊确实有 + b1.legs + 条腿); b2.setLegs(-4); b2.show(); System.out.println(这只熊确实有 + b2.legs + 条腿);现在的情况比前面好多了,至少不会出现腿的数量是负数的情况。但总有那么一些不安分的编程人员就是要这样写(或者会不小心这样): b2.legs = -4;也就是说,尽管我们提供了一个设置熊腿数量的方法setLegs(),但仍无法杜绝将熊腿的数量设置为负数的情况。现在,我们在int legs前面增加一个private就可以彻底解决这个问题:class Bear private int legs; public void show() System.out.println(本熊有 + legs + 条腿); public void setLegs(int legs) if (legs 0) this.legs = 4; else this.legs = legs; 现在: b1.legs = 4; b2.legs = -2;都是不允许做的(不可以在类对象的外面直接访问私有的东西),故而要设置熊的腿数量,就只能调用b1.setLegs(4)和b2.setLegs(-2)了,并且执行后的结果就保证了腿数为正数。 不过我们又发现了另一个不足,就是下面这条语句出现编译错误: System.out.println(这只熊确实有 + b1.legs + 条腿); System.out.println(这只熊确实有 + b2.legs + 条腿);原因在于,legs字段变量是Bear类中私有的东西,不能在类对象以外访问。既不能在类的对象之外修改,也不能在类的对象之外读取。所以,为了使得外面的代码仍可以访问到熊的腿数,我们需要再增加一个读取legs值的方法:class Bear private int legs; public void show() System.out.println(本熊有 + legs + 条腿); public void setLegs(int legs) if (legs 0) this.legs = 4; else this.legs = legs; public int getLegs() return legs; 这样将上面的测试代码再重写一遍就好了: b1.setLegs(3); b1.show(); System.out.println(这只熊确实有 + b1.getLegs() + 条腿); b2.setLegs(-4); b2.show(); System.out.println(这只熊确实有 + b2. getLegs() + 条腿);所以,以后我们在写自己的类时,大多数情况下都是将属性字段变量设置为private的,然后提供一系列set和get方法来修改或读取那些private属性字段的值。这种方法命名的特点是,set或get后面跟着变量名字,且变量名字的第一个字母改为大写。答疑2:所有类都是继承自Object类的。也就是说,Object类是Java语言中的所有类的鼻祖!(你不写的话,系统会自定帮你添上)class A 等价于 class A extends Object 答疑3:父类的引用变量,可以指向其子类的对象。class A int x = 1; void print() System.out.println(x= + x); class B extends A int y = 2; void show() System.out.println(y= + y); 上面A是B的父类。我们可以生成两个对象看看: A a = new A(); a.print(); B b = new B(); b.print(); b.show();BbAa现在这样: a = b; / b的辈份比a小,“小”的直接覆值给“大”的是允许的 a.print(); / 调用的是B类对象的print()方法,因为a指向的是B类对象bBa上面的这个a,其实就相当于是一个指针变量,它指向的实际对象是B类对象。当a.print();执行时,执行的实质上就是B类对象中的print()方法。现在有一个问题,既然a指向的实际上是一个B类对象,而我们又知道,B类对象中不仅有从类A继承过来的东西(x和prin
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 瓶栽速写课件
- 农村合作开发建房协议5篇
- 关于猪场技术托管协议6篇
- 琼剧鉴赏教学课件
- 杆线工程保护方案(3篇)
- 渡槽工程设备安装方案(3篇)
- 平南县东来农牧科技有限公司东华镇科技养殖园项目环评报告
- 农业温室项目2025年智能化温室大棚技术集成研究报告
- 农业温室智能化技术应用案例研究报告
- 猫咪饲养员岗前培训课件
- 2025年福建省福州市辅警考试题库(附答案)
- 2025年国家网络安全宣传周知识竞赛考试练习题库(完整版)含答案
- 绿化项目养护监理方案投标文件(技术方案)
- 科普短视频与新闻传播融合模式的研究
- 2025年教师资格证中学综合素质+教育知识与能力真题及答案
- 安徽省港航集团有限公司所属企业招聘笔试真题2024
- 《电力系统微机继电保护》课件-第五章 微机线路保护举例
- (2025)中小学“学宪法、讲宪法”知识竞赛题库(含答案)
- 2025年中国PC工业计算机(工控机)数据监测研究报告
- 玉米收获机械技术课件
- (2025)社区网格员笔试考试题库及答案
评论
0/150
提交评论