第三讲面向对象程序设计方案思想类和封装.docx
《第三讲面向对象程序设计方案思想类和封装.docx》由会员分享,可在线阅读,更多相关《第三讲面向对象程序设计方案思想类和封装.docx(12页珍藏版)》请在冰豆网上搜索。
![第三讲面向对象程序设计方案思想类和封装.docx](https://file1.bdocx.com/fileroot1/2022-11/16/a46dc9c0-c5db-4cf6-b08c-6fdcb2ecee75/a46dc9c0-c5db-4cf6-b08c-6fdcb2ecee751.gif)
第三讲面向对象程序设计方案思想类和封装
第三章面向对象程序设计思想<1)——类和封装
3.1面向对象设计方法的由来
<1)提高软件的可维护性和可复用性
●如何同时提高软件的可维护性和可复用性是现代软件工程的核心问题
●一个好的软件设计,必须能够允许新的设计要求以较为容易和平和的方式加入到已有的系统中去,从而使这个系统能够不断的焕发青春。
●复用的重要性:
提高生产效率、提高软件质量、改善软件可维护性
●传统的复用方法:
代码粘贴、算法复用、数据结构复用
<2)问题抽象的进步
●所有编程语言都是对目标问题的“抽象”。
●汇编语言用机器的思维去考虑问题,是面向机器的抽象
●高级语言以接近自然语言的思维去考虑问题,是面向问题的抽象
●面向对象语言以自然界“物质”的思维去考虑问题,认为程序是由一堆对象相互作用的结果
<3)机器性能的提高
●思维的抽象越来越接近自然,也就意味着要用越来越多的“额外”代码来做支撑。
●软件执行速度和复用型、可维护性常常是一对矛盾
3.2“纯粹”的面向对象程序设计方法是什么样的
<1)所有东西都是对象
可将对象想象成一种新的类型;
同一类的对象具有相同的属性名称和方法;
<2)程序是一堆对象相互作用的结果。
它们通过相互发送消息来彼此作用
为了告诉对象做什么,需向那个对象“发送一条消息”。
具体地讲,可将消息想象为一个调用,它调用的是从属于目标对象的一个子例程或函数。
<3)每个对象是独立的,也就是拥有独立的存储空间
<4)每个对象都有一种类型
<5)同一类型的各个对象,它们能接收的消息是相同的
<6)程序通过引用访问对象
3.3对象和类
3.3.1类
人们对事物的抽象描述,概括出该事物所具有的属性和方法,并将其进行封装,以供使用。
用class定义类,声明类的形式为:
[附加声明][访问修饰符]class类名称[extends[基类]
{
[属性]
[方法]
}
例3.1
每位学生每学期最多有15门课程,课程有考试课和考查课两种。
课程成绩的原始分按正常考试/考查实际得分计算。
考试课的原始分使用百分制形式,考查课的原始分采用等第形式<优秀、良好、中等、及格、不及格)。
在进行测评成绩计算时,考查课程成绩中的优秀、良好、中等、及格、不及格的,分别换算成为95、85、75、65和50分。
测评计算公式为:
分析:
从上面描述中可以得到以下有效关键字:
学生、课程、考试课、考查课、原始分、评测成绩、学分
因此,得到下面几个类:
学生类、课程类、考试课类、考查课类。
进一步考虑,我们可以发现,考试课类和考查课类都是课程类的子类型。
这种现象在面向对象的设计中称为“继承”,在UML的类图中使用空心三角的箭头<
)表示继承,箭头指向父类。
我们可以把相同的东西合并到父类里。
注意,为了“统一”起见,我们将考试课的原始分也定义为了String类型<字符串),这样,考试课的“转换成绩”要做的事是将字符串的数值还原成百分制<具体的实现后面会讲到),而考查课的“转换成绩”要做的事是将等第进行转换。
于是,我们就可以写出这四个类的结构:
<1)学生类
class学生类
{
publicString姓名。
publicString学号。
public课程类[]课程列表。
publicvoid添加课程(课程类课程>
{
//将课程添加到课程列表中
}
publicdouble计算评测成绩(>
{
return0.0。
}
}
说明:
●public关键字是用来设定访问权限的,表示任何程序都能够访问。
与它相对应还有protected<保护)、private<私有);
●课程列表我们使用了数组。
关于数组,我们要过一段时间再介绍。
<2)课程类
class课程类
{
publicString课程名。
publicString原始分。
publicdouble学分。
publicdouble转换成绩(>
{
return0.0。
}
}
<3)考试课类
class考试课类extends课程类
{
publicdouble转换成绩(>
{
//将数值型的字符串转换为百分制
return0.0
}
}
说明:
●extends关键字表示继承,这说明考试课类是课程类的子类,它继承考试类中的内容。
<4)考查课类
class考试课类extends课程类
{
publicdouble转换成绩(>
{
//将等第转换为百分制
return0.0。
}
}
3.3.2对象
对象<实例):
类的实例化。
客观的。
对象在建立时分配了内存,创建对象实际上作了两个方面的工作:
<1)使用new关键字分配内存;
<2)使用构造函数初始化数据<构造函数是与类名同名的函数)。
学生类st=new学生类(>。
3.3.3使用对象
1、不直接使用对象,而是使用“引用”
“引用”指该类型的变量并不直接存储所包含的实际数据,而是存储实际数据的地址。
2、引用间赋值时传递的是存放对象的地址
3、当一个对象不被任何句柄引用时,视作“垃圾”。
由JAVA的垃圾回收机制自动销毁不再使用的对象。
垃圾回收机制是在它认为适当的时候自动回收不再使用的内存的。
class测试学生类
{
publicstaticvoidmain(String[]args>
{
学生类st=new学生类(>。
st.姓名="张三"。
st.学号="200"。
System.out.println(st.姓名+"的学号为"+st.学号>。
}
}
输出:
张三的学号为200
3.4JAVA中的常用类
JAVA中的数据类型分为“基本类型”和“引用类型”两种。
基本类型存放在栈内存中,对象存放在堆内存中,而引用存放在栈内存中,并指向对象。
使用class定义的类型称为引用类型,在使用引用类型时,不是直接使用对象,而是通过“引用”访问对象。
就像使用遥控器访问电视机。
3.4.1字符串类型String
Java将字符串作为String类型对象来处理。
有些出乎意料的是当创建一个String对象时,被创建的字符串是不能被改变的。
这也就是说一旦一个String对象被创建,将无法改变那些组成字符串的字符。
表面上看起来,这好像是一个严格的约束。
然而事实并非如此。
你仍能够执行各种类型的字符串操作。
区别在于每次需要改变字符串时都要创建一个新的String对象来保存新的内容。
原始的字符串不变。
之所以采用这种方法是因为实现固定的,不可变的字符串比实现可变的字符串更高效。
对于那些想得到改变的字符串的情况,有一个叫做StringBuffer的String类的友类。
它的对象包含了在创建之后可被改变的字符串。
String类和StringBuffer类都在java.lang中定义。
●length(>方法可以得到字符串的长度
●charAt(intindex>方法可以从一个字符串中截取一个字符
●toCharArray(>方法可以将字符串中的字符转换为一个字符数组
●equals(>方法可以比较两个字符串是否相等
●indexOf(Stringstr>搜索字符或子字符串首次出现的位置
●lastIndexOf(Stringstr>>搜索字符或子字符串的最后一次出现的位置
●substring(>方法可以截取子字符串,它有两种形式。
其中第一种形式如下:
Stringsubstring(intstartIndex>这里startIndex指定了子字符串开始的下标。
这种形式返回一个从startIndex开始到调用字符串结束的子字符串的拷贝。
第二种形式允许指定子字符串的开始和结束下标:
Stringsubstring(intstartIndex,intendIndex>这里startIndex指定开始下标,endIndex指定结束下标。
返回的字符串包括从开始下标直到结束下标的所有字符,但不包括结束下标对应的字符。
●replace(>方法用另一个字符代替调用字符串中一个字符的所有具体值:
Strings="Hello".replace('l','w'>。
将字符串“Hewwo”赋给s。
●trim(>方法去除字符串首尾空格
3.4.2数值封装类
在java.lang中定义了与基本类型相对应的类类型:
双精度型●Byte,Short,Integer,Long,Float和Double类分别提供了parseByte(>,parseShort(>,parseInt(>,parseLong(>,parseFloat(>和parseDouble(>方法。
这些方法返回与调用它们的数值字符串相应的字节和双精度(double>值。
如果转换失败,将产生NumberFormatException异常
例3.2
str=”123”。
try{
inti=Integer.parseInt(str>。
}
catch(NumberFormatExceptione>{
System.out.println("Invalidformat">。
i=0。
}
●Integer和Long类还同时提供了toBinaryString(>,toHexString(>和toOctalString(>方法,可以分别将一个值转换成二进制,十六进制和八进制字符串。
例3.3
intnum=19648。
System.out.println(num+"inbinary:
"+Integer.toBinaryString(num>>。
System.out.println(num+"inoctal:
"+Integer.toOctalString(num>>。
System.out.println(num+"inhexadecimal:
"+Integer.toHexString(num>>。
输出:
19648inbinary:
100110011000000
19648inoctal:
46300
19648inhexadecimal:
4cc0
●要将基本类型转换为字符串类型,可以调用相应类方法。
例3.4
inti=1111。
doubled=3.25。
Strings=Integer.toString(i>+Double.toString(d>。
System.out.println(s>。
到这里,我们应该可以写出考试课类的转换成绩(>方法了:
例3.5
publicdouble转换成绩(>
{
try
{
doubleresult=Double.parseDouble(this.原始分>。
returnresult。
}
catch(NumberFormatExceptione>
{
return-1。
}
}
我们在主程序中输入以下代码进行测试:
考试课类ks=new考试课类(>。
ks