第3章面向对象(上)_补充案例
- 格式:doc
- 大小:369.50 KB
- 文档页数:13
面向对象设计(OOD)思想(C#)任务:设计媒体播放器软件如何设计:一、传统过程化设计思想假定该媒体播放器目前只支持音频文件MP3和wav。
按照结构化设计思想,设计出来的播放器的代码如下:public class MediaPlayer{private void PlayMp3(){MessageBox.Show("Play the mp3 file.");}private void PlayWav(){MessageBox.Show("Play the wav file.");}public void Play(string audioType){switch (audioType.ToLower()){case ("mp3"):PlayMp3();break;case ("wav"):PlayWav();break;}}}从传统的过程化设计思想来看,这是一段既实用又简洁的代码。
如果,客户又提出新的要求:要播放器不仅仅播放mp3和wav文件,还要播放其他音频文件如wma、MP4等,为此我们要不断地增加相应地播放方法和修改条件语句,直止条件语句足够长。
如果,客户感到这个媒体播放器功能太少了,只能闻其声,不能见其人,太单一。
如果在听着优美音乐的同时又能看到歌唱者潇洒、英俊的舞姿那就更好了。
从代码设计的角度看,他们希望媒体播放器支持视频文件了。
也许你会想,不会再增加视频这方面的代码,可以,在增加视频媒体的播放方法,在修改条件判断语句,如果还有其他,还可以同样地增加、修改。
到此你也许会提出,要是不修改或很少修改原来的代码就能增添其他功能该多好啊!这样看,原来的软件设计结构似乎有点问题。
事实上,随着功能的不断增加,你越来越发现这个设计非常的糟糕,因为它根本没有为未来的需求变更提供最起码的扩展。
为了应接不暇的变更需求,你不得不不厌其烦地修改原来的代码,使其适应需求变化,甚至在修改代码时,由于过多的代码依赖关系弄得人焦头烂额,直止一塌糊涂。
第三章补充案例案例3-1 定义学生类一、案例描述1、考核知识点编号:00103002名称:类和对象2、练习目标掌握类定义的方式掌握如何在类中定义成员变量和成员方法3、需求分析在面向对象的思想中最核心就是对象,在程序中创建对象的前提是需要定义一个类。
为了让初学者掌握类的定义方式,本案例将设计一个表示学生的类,该类具有表示姓名的属性name和表示年龄的属性age,同时还具有表示说话行为的方法speak(),用于输出学生的姓名和年龄。
4、设计思路(实现原理)1)使用class关键字定义一个表示学生类型的类,类名为Student。
2)在Student类中定义两个成员变量name和age,分别用来表示姓名和年龄。
其中,name的数据类型为String,变量age的数据类型为int。
3)在Student类中定义一个表示说话行为的speak()方法,用于输出学生的姓名和年龄。
二、案例实现class Student{String name;int age;void speak() {"我的名字是 "+name+",今年 "+age+"岁");}}三、案例总结1、Java语言严格区分大小写,class和Class是不同的,在定义类时只能使用class关键字2、在Student类中,成员变量name是String类型,String表示一个字符串,后面的章节会详细讲解3、思考一下:自己定义一个手机(Phone)类,在类中定义品牌(brand)和价格(price)属性,定义打电话的call()方法,代码如下所示public class Phone {String brand;double price;void call(){"hi,how are you doing");}}案例3-2 同一对象被多个变量引用一、案例描述1、考核知识点编号:00103003名称:对象创建与使用2、练习目标掌握如何创建类的对象掌握如何使用两个或者多个变量引用同一个实例对象。
3、需求分析在程序中,一个对象可能在多处使用,这样就可能需要有多个变量来引用这个对象。
为了让初学者更好地掌握对象的创建和使用,本案例将基于案例3-1,创建三个学生对象,它们的引用变量分别是s1、s2和s3,首先分别使用s1和s2引用,为name和age赋值,然后调用speak()方法,最后将s2变量赋值给s3, s3也调用speak()方法。
4、设计思路(实现原理)1)编写Example01类2)在main()方法中,创建Student类的第一个对象,其引用变量为s1,使用s1调用name和age 变量分别为它们赋值为“张三”和“19”,然后调用speak()方法。
3)创建Student类的第二个对象,其引用变量为s2,使用s2分别为name和age赋值为“李四”和“20”,然后调用speak()方法。
4)创建Student类的第三个对象,其引用变量为s3,将s2的值赋给s3,然后使用s3调用speak()方法。
二、案例实现public class Example01 {public static void main(String [] args) {Student s1 = new Student();="张三";=19;();Student s2 = new Student();="李四";=20;();Student s3 = new Student();s3=s2;();}}运行结果如图3-1所示。
图3-1运行结果三、案例总结1、Student s3 = s2这句代码的作用是将s2引用的内存地址赋值给s3,换句话说,就是使变量s3和s2引用了同一个Student对象,因此()方法和()方法打印的结果相同。
为了更加深刻地了解这句代码的含义,下面通过一张内存图来演示,具体如图3-2所示。
new Student()s1内存name=张三age=19speak()s2name=李四age=20speak()new Student()s3图3-2内存图2、可以使用两个或者多个变量引用同一个实例对象,只要通过其中一个变量对该对象的属性进行修改,使用其它引用变量访问时,访问的都是修改后的属性。
案例3-3 类的封装一、案例描述1、考核知识点编号:00103004名称:类的封装2、练习目标了解为什么要对类进行封装了解如何实现类的封装3、需求分析在案例3-2中,s1对象的年龄是可以随便赋值的,如果将age的值赋值为-30,显然违背了事实。
为了解决这类问题,我们需要对类进行封装,防止外界对类中的成员变量随意访问。
为了让初学者更好地掌握类的封装,本案例将使用private关键字对成员变量name和age进行私有化,同时分别提供一个setName(String n)和setAge(int a)方法用于外界的访问,其中setAge(inta)中需要对age进行判断。
4、设计思路(实现原理)1)编写测试类Example02,将属性age的值设为-30,演示不合理现象。
2)对Student类进行修改,将name和age属性使用private修饰,然后定义getName()、setName(String n)、getAge()和setAge(int a)四个对外访问name和age的方法。
3)在setAge(int a)方法中对传入的参数进行检查,如果输入值为负数,则打印出“设置的年龄不合法”,如果不为负数,才将其设置为age属性的值。
4)对Example02类进行修改,在main()方法中创建Student类的实例对象,通过调用对象的setName(String n)和setAge(int a)方法来设置的name属性和age属性值,并调用speak()方法。
二、案例实现1、定义Example02类,代码如下所示:public class Example02 {public static void main(String[] args) {Student s1 = new Student();= "小新";= -30;();}}运行结果如图3-3所示。
图3-3运行结果从上图可以看出,当将age的值设置为-30后,程序不会报错,但却违背了现实。
2、对Student类进行封装,其代码如下:class Student {private String name = "张三";private int age = 19;public String getName() {return name;}public void setName(String n) {name = n;}public int getAge() {return age;}public void setAge(int a) {Student(String name,int age)this(name)Student(String name)Student()this()执行顺序法名([参数…])的方式调用普通的成员方法,但是在普通的成员方法中不能使用this([参数…])的方式来调用构造方法。
案例3-7 垃圾回收机制一、案例描述1、考核知识点编号:00103008名称:垃圾回收机制2、练习目标掌握垃圾回收机制的特点掌握垃圾回收相关的方法3、需求分析垃圾对象会占用一定的内存空间,当垃圾对象积累到一定程度后,Java虚拟机会自动进行垃圾回收。
但是,如果希望程序可以及时通知Java虚拟机回收垃圾对象,可以通过()方法强制启动垃圾回收器回收垃圾。
为了让初学者熟悉垃圾回收机制,本案例将演示如何通过()方法强制启动垃圾回收器回收垃圾。
4、设计思路(实现原理)1)对Student类进行修改,在类中对finalize()方法进行重写。
2)编写测试类Example07,创建若干个Student对象,然后调用()方法通知垃圾回收期回收垃圾,为了确保可以看到垃圾回收的过程,可以在类中编写一个简单的循环语句,延长程序执行时间。
二、案例实现1、对Student类进行修改,代码如下所示:class Student {public void finalize() {"垃圾对象被回收了");}}2、定义Example07类,代码如下所示:public class Example07 {public static void main(String[] args) {new Student();new Student();();for (int i = 0; i < 1000000; i++) {className{Student三年级二班namename nameStudent实例对象{s1s2s3态方法名”的方式访问,也可以通过“对象引用变量.静态方法名”的方式访问,例如本例中的静态变量className,通过或者这两种方式访问都是可以的,不过更推荐使用前一种方式。
3、思考一下:定义一个Person类,在类中定义两个String类型的成员变量name和nationality(国籍),变量nationality使用static关键字修饰为静态变量,其值为“中国”。
定义Example09类,在类的main()方法中创建Person类的两个实例对象,并打印出这两个对象的姓名和国籍。
(1)定义Person类,代码如下所示:class Person {String name;static String nationality = "中国";}(2)定义Example09类,代码如下所示:public class Example09{public static void main(String[] args) {Person lily = new Person();= "丽丽";Person lucy = new Person();= "露西";+ "的国籍是" + ;+ "的国籍是" + ;}}运行结果如图3-14所示。
图3-4运行结果案例3-9 静态方法中访问类的成员一、案例描述1、考核知识点编号:00103010名称:静态方法2、练习目标了解在静态方法中只能访问类的静态成员,而不能访问非静态成员。
3、需求分析在程序中经常会调用方法,但静态方法之间、静态方法和非静态方法之间,它们是否能够互相调用呢请编写一个测试类,在类中定义若干个静态方法和非静态方法,通过方法之间的相互调用,演示静态方法和非静态方法的调用情况。