第3章_面向对象(上)_补充案例

第3章_面向对象(上)_补充案例
第3章_面向对象(上)_补充案例

第三章补充案例

案例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() {

System.out.println("我的名字是 "+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(){

System.out.println("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();

https://www.360docs.net/doc/5717677787.html,="三";

s1.age=19;

s1.speak();

Student s2 = new Student();

https://www.360docs.net/doc/5717677787.html,="四";

s2.age=20;

s2.speak();

Student s3 = new Student();

s3=s2;

s3.speak();

}

}

运行结果如图3-1所示。

图3-1运行结果

三、案例总结

1、Student s3 = s2这句代码的作用是将s2引用的存地址赋值给s3,换句话说,就是使变量s3和s2引用了同一个Student对象,因此s3.speak()方法和s2.speak()方法打印的结果相同。为了更加深刻地了解这句代码的含义,下面通过一存图来演示,具体如图3-2所示。

new Student()

s1

内存

name=张三

age=19

speak()

s2name=李四

age=20

speak()

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(int a)中需要对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();

https://www.360docs.net/doc/5717677787.html, = "小新";

s1.age = -30;

s1.speak();

}

}

运行结果如图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) {

// 对传入的参数进行检查

if(a < 0){

System.out.println("设置的年龄不合法");

}else{

age = a;

}

}

void speak() {

System.out.println("我的名字是" + name + ",今年" + age + "岁");

}

}

public class Example02 {

public static void main(String[] args) {

Student s1 = new Student();

s1.setName("小新");

s1.setAge(-30);

s1.speak();

}

}

运行结果如图3-4所示。

图3-4运行结果

三、案例总结

1、Student的name和age属性使用private关键字修饰为私有后,在Example02类中不能再使用https://www.360docs.net/doc/5717677787.html, 和s1.age的方式访问这两个属性,只能通过public类型的setName(String n)和setAge(int a)方法进行访问。在上面的代码中,调用setAge(int a)方法时的传入参数为-30,由于参数小于0,会打印出“设置的年龄不合法”,并不会将负数赋值给age属性。由此可见,只要实现了封装就能对外界的访问进行控制,避免对私有变量随意修改而引发问题。

2、思考一下:定义一个Division类(除法),类中定义两个int类型的私有成员变量dividend(被除数)和divisor(除数),默认值都为1。定义四个公有方法setDividend(int mDividend )、getDividend()、setDivisor(int mDivisor)和getDivisor(),用于对私有属性进行设置和访问。在setDivisor(int mDivisor)方法中对传入的参数进行检查,如果传入值为零,则打印“除数不能为零”,如果不为零,才将其设置为divisor属性的值。

定义Example03类,在类的main()方法中创建Division对象,分别调用setDividend(int mDividend)和setDivisor(int mDivisor)方法给两个私有属性dividend和divisor赋值,然后打印出dividend和divisor的结果。

(1)定义Division类,代码如下所示:

public class Division {

private int dividend = 1;

private int divisor = 1;

public void setDividend(int mDividend) {

dividend = mDividend;

}

public int getDividend() {

return dividend;

}

public void setDivisor(int mDivisor) {

if (mDivisor == 0) {

System.out.println("除数不能为零");

} else {

divisor = mDivisor;

}

}

public int getDivisor() {

return divisor;

}

}

(2)定义Example03类,代码如下所示:

public class Example03{

public static void main(String[] args) {

Division division = new Division();

division.setDividend(10);

division.setDivisor(0);

int dividend = division.getDividend();

int divisor = division.getDivisor();

System.out.println(dividend / divisor);

}

}

运行结果如图3-5所示。

图3-5运行结果

从运行结果可以看出,由于实现了Division类的封装,在setDivisor(int mDivision)方法中对传入的值进行检查,从而避免程序中出现除数为0的错误。

案例3-4 定义有参的构造方法

一、案例描述

1、考核知识点

编号:00103005

名称:构造方法的定义

2、练习目标

?掌握有参构造方法的定义方式

?理解系统会自动分配无参构造方法的情况

3、需求分析

如果希望在创建对象的时候直接为其属性赋值,可以定义有参的构造方法。有参构造方法指的是在初始化对象时,接受外部传入的值并赋给对象的属性。为了让初学者掌握有参构造方法的用法,本案例将演示如何使用有参构造方法完成对象属性的初始化。

4、设计思路(实现原理)

1)定义一个Student类,该类有一个age属性,在类中定义一个有参数的构造方法,该参数用于为age属性赋值。

2)编写一个测试类Example04,在main()方法过有参构造方法创建一个对象。

3)打印该对象age属性的值。

二、案例实现

1、对Student类进行修改,代码如下所示:

class Student {

int age;

public Student(int mAge) {

age = mAge;

}

}

2、定义Example04类,代码如下所示:

public class Example04 {

public static void main(String[] args) {

Student s1 = new Student(20);

System.out.println("age属性的值为:"+s1.age);

}

}

运行结果如图3-6所示。

图3-6运行结果

三、案例总结

1、从运行结果可以看出,new Student(20)语句调用了有参的构造方法Student(int mAge),动态地将20传递给了age属性。和普通方法一样,构造方法中同样可以接收多个参数,只要在使用new关键字创建对象时,传入数量相同和类型一致的参数,就可以自动地调用对应的构造方法。

2、思考一下:在Example04的main()方法中是否能够使用new Student()创建对象呢?答案是否定的,因为new Student()会调用无参的构造方法,而本案例的Student类中并没有定义无参的构造方法。

有些同学肯定会问,之前的Student类都没有定义无参的构造方法,却能使用new Student()创建对象,本案例为什么不行呢?这是因为一个类中如果没有定义构造方法,系统会默认为其分配一个方法体为空的无参构造方法,而一旦定义了构造方法,系统就不再提供默认的构造方法。本案例中由于我们定义了一个有参的构造方法,所以系统不会默认分配无参的构造方法,此时如果通过new Student()去调用无参的构造方法,程序就会发生错误。

案例3-5 构造方法的重载

一、案例描述

1、考核知识点

编号:00103006

名称:构造方法重载

2、练习目标

?掌握如何在类中定义重载的构造方法

3、需求分析

和普通方法一样,构造方法也可以重载。不同的构造方法,可以为不同的属性进行赋值。本案例将通过创建对象的方式演示不同构造方法的使用方式,并根据构造方法的输出结果对构造方法的重载进行学习。

4、设计思路(实现原理)

1)对Student类进行修改,在类中定义三个重载的构造方法,包括无参的构造方法,接收一个String 类型参数的构造方法,接收String类型和int类型两个参数的构造方法。

2)编写测试类Example05,在main()方法中,分别使用三个重载的构造方法创建三个Student对象。

二、案例实现

1、对Student类进行修改,代码如下所示:

class Student {

public Student() {

System.out.println("无参的构造方法");

}

public Student(String name) {

System.out.println("一个参数的构造方法");

}

public Student(String name, int age) {

System.out.println("两个参数的构造方法");

}

}

2、定义Example05类,代码如下所示:

public class Example05 {

public static void main(String[] args) {

Student s1 = new Student();

Student s2 = new Student("Rose");

Student s3 = new Student("Rose", 23);

}

}

运行结果如图3-7所示。

图3-7运行结果

三、案例总结

一个类中可以定义多个重载的构造方法,在创建对象时,根据传入参数的不同会调用相应的构造方法。案例3-6 this关键字访问构造方法

一、案例描述

1、考核知识点

编号:00103007

名称:this关键字的使用

2、练习目标

?掌握如何在构造方法中使用this关键字访问重载的构造方法

3、需求分析

如果一个类中定义了多个重载的构造方法,为了避免在重载的构造方法中重复书写代码,可以在一个构造方法中使用this关键字调用其它的构造方法。为了让初学者掌握this关键字访问构造方法的用法,本案例将演示如何使用this关键字调用其他的构造方法。

4、设计思路(实现原理)

1)在Student类中创建多个重载的构造方法,包括无参的构造方法和一个参数的构造方法,以及两个参数的构造方法。

2)在一个参数的构造方法中使用this关键字调用无参构造方法,在两个参数的构造方法中调用一个参数的构造方法。

3)编写测试类Example06,在main()方法中,调用两个参数的构造方法创建对象,演示构造方法的执行顺序。

二、案例实现

1、对Student类进行修改,代码如下所示:

class Student {

public Student() {

System.out.println("无参的构造方法");

}

public Student(String name) {

this();

System.out.println("一个参数的构造方法");

}

public Student(String name, int age) {

this(name);

System.out.println("两个参数的构造方法");

}

}

2、定义Example06类,代码如下所示:

public class Example06 {

public static void main(String[] args) {

Student s1 = new Student("Jack", 22);

}

}

运行结果如图3-8所示。

图3-8运行结果

三、案例总结

1、从运行结果可以看出,三个构造方法都被调用了,为了更加清楚地了解三个构造方法的执行顺序,下面通过一图例进行说明,如图3-9所示。

图3-9构造方法的执行顺序

2、在构造方法中,使用this调用重载构造方法的代码必须放在第一行,否则程序不能通过编译,这就限定了在一个构造方法中只能调用一次重载的构造方法。

3、在构造方法中可以通过this.方法名([参数…])的方式调用普通的成员方法,但是在普通的成员方法中不能使用this([参数…])的方式来调用构造方法。

案例3-7 垃圾回收机制

一、案例描述

1、考核知识点

编号:00103008

名称:垃圾回收机制

2、练习目标

?掌握垃圾回收机制的特点

?掌握垃圾回收相关的方法

3、需求分析

垃圾对象会占用一定的存空间,当垃圾对象积累到一定程度后,Java虚拟机会自动进行垃圾回收。但是,如果希望程序可以及时通知Java虚拟机回收垃圾对象,可以通过System.gc()方法强制启动垃圾回收器回收垃圾。为了让初学者熟悉垃圾回收机制,本案例将演示如何通过System.gc()方法强制启动垃圾回收器回收垃圾。

4、设计思路(实现原理)

1)对Student类进行修改,在类中对finalize()方法进行重写。

2)编写测试类Example07,创建若干个Student对象,然后调用System.gc()方法通知垃圾回收期回收垃圾,为了确保可以看到垃圾回收的过程,可以在类中编写一个简单的循环语句,延

长程序执行时间。

二、案例实现

1、对Student类进行修改,代码如下所示:

class Student {

public void finalize() {

System.out.println("垃圾对象被回收了");

}

}

2、定义Example07类,代码如下所示:

public class Example07 {

public static void main(String[] args) {

new Student();

new Student();

System.gc();

for (int i = 0; i < 1000000; i++) {

// 延长程序结束时间

}

}

}

运行结果如图3-10所示。

图3-10运行结果

三、案例总结

1、从运行结果可以看到,两个Student对象的finalize()方法都被调用了,这表示两个对象作为垃圾被回收了。如果把System.gc()这行代码注释,会发现命令行窗口不会打印任何容,这说明对象在变成垃圾后不会被立即回收,同时也验证了System.gc()方法的作用。

2、由于System.gc()方法只是通知Java虚拟机尽快进行垃圾回收,这意味着垃圾回收器也可能不会马上运行,因此,在程序的最后使用了一个for循环来延长程序运行的时间,从而确保能够看到垃圾对象被回收的过程。

3、Student类中定义的finalize()方法其签名必须是public(protected) void finalize()[throw Throwable]{},这样做的原因会涉及到后面的一些知识,比如类的继承、Object类、方法的重写、异常等等,同学们在学完这些容后就会明白其中的道理。

案例3-8静态变量

一、案例描述

1、考核知识点

编号:00103009

名称:静态变量

2、练习目标

?了解静态变量的作用

?掌握静态变量的定义和使用方式

3、需求分析

当多个对象存储的数据相同时,可以使用静态变量的方式存储。例如,有一个Student类具有name、className属性,请根据该类创建出三个Student对象,并将这些对象的className值都设置为“三年级二班”。

4、设计思路(实现原理)

1)定义Student类,并在类中定义name和className属性。

2)编写测试类Example08,在main()方法中创建三个学生对象,并分别为这些对象的name和className属性赋值,然后输出这些对象的name和className值。

3)对Student类进行修改,将className定义为静态变量。

4)修改测试类,在main()方法中使用Student.className = “三年级二班”语句为静态变量className进行赋值,然后输出这些对象的name和className值。

为了更好地理解Student类中静态变量className和Student实例对象的关系,下面通过一个图例进行演示,如图3-11所示:

图3-11静态变量与实例对象的关系

二、案例实现

1、定义Student类,代码如下所示:

class Student{

String name;

String className;

}

2、定义Example08类,代码如下所示:

public class Example08 {

public static void main(String[] args) {

Student s1 = new Student();

https://www.360docs.net/doc/5717677787.html, = "三";

s1.className = "三年级二班";

Student s2 = new Student();

https://www.360docs.net/doc/5717677787.html, = "四";

s2.className = "三年级二班";

Student s3 = new Student();

https://www.360docs.net/doc/5717677787.html, = "王五";

s3.className = "三年级二班";

System.out.println("我的名字是" + https://www.360docs.net/doc/5717677787.html, + ",来自" + s1.className);

System.out.println("我的名字是" + https://www.360docs.net/doc/5717677787.html, + ",来自" + s2.className);

System.out.println("我的名字是" + https://www.360docs.net/doc/5717677787.html, + ",来自" + s3.className);

}

}

运行结果如图3-12所示。

图3-12运行结果

3、对Student类进行修改,代码如下所示:

class Student {

String name;

static String className;

}

4、对Example08类进行修改,代码如下所示:

public class Example08 {

public static void main(String[] args) {

Student.className = "三年级二班";

Student s1 = new Student();

https://www.360docs.net/doc/5717677787.html, = "三";

Student s2 = new Student();

https://www.360docs.net/doc/5717677787.html, = "四";

Student s3 = new Student();

https://www.360docs.net/doc/5717677787.html, = "王五";

System.out.println("我的名字是" + https://www.360docs.net/doc/5717677787.html, + ",来自" + s1.className);

System.out.println("我的名字是" + https://www.360docs.net/doc/5717677787.html, + ",来自" + s2.className);

System.out.println("我的名字是" + https://www.360docs.net/doc/5717677787.html, + ",来自" + s3.className);

}

}

运行结果如图3-13所示。

图3-13运行结果

三、案例总结

1、本案例中,三个Student对象的className属性值均为“三年级二班”,对于这样的相同数据,没有必要在每个对象中都开辟一块空间存储,完全可以在存中只用一块空间存储,并被一个类的所有实例对象所共享。在Java中提供了一个static关键字,使用static关键字修饰的成员变量称为静态变量,静态变量能被该类所有实例对象共享。

2、静态变量可以使用“类名.静态方法名”的方式访问,也可以通过“对象引用变量.静态方法名”的方式访问,例如本例中的静态变量className,通过Student.className或者s2.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();

https://www.360docs.net/doc/5717677787.html, = "丽丽";

Person lucy = new Person();

https://www.360docs.net/doc/5717677787.html, = "露西";

System.out.println(https://www.360docs.net/doc/5717677787.html, + "的国籍是" + lily.nationality);

System.out.println(https://www.360docs.net/doc/5717677787.html, + "的国籍是" + lucy.nationality);

}

}

运行结果如图3-14所示。

图3-14运行结果

案例3-9 静态方法中访问类的成员

一、案例描述

1、考核知识点

编号:00103010

名称:静态方法

2、练习目标

?了解在静态方法中只能访问类的静态成员,而不能访问非静态成员。

3、需求分析

在程序中经常会调用方法,但静态方法之间、静态方法和非静态方法之间,它们是否能够互相调用呢?请编写一个测试类,在类中定义若干个静态方法和非静态方法,通过方法之间的相互调用,演示静态方法和非静态方法的调用情况。

4、设计思路(实现原理)

1)编写Example10类,在类中定义两个静态方法staticMethod1()、staticMethod2(),两个非静态方法nonStaticMethod1()、nonStaticMethod2()

2)在Example10类中,针对定义的四个方法进行互相调用,观察调用情况。

二、案例实现

1、定义Example10类,在类中定义上述的四个方法和一个main()方法,代码如下所示:

public class Example10{

static void staticMethod1() {

System.out.println("静态方法1");

}

static void staticMethod2() {

System.out.println("静态方法2");

}

void nonStaticMethod1() {

System.out.println("非静态方法1");

}

void nonStaticMethod2() {

System.out.println("非静态方法2");

}

public static void main(String[] args) {

}

}

2、对静态方法staticMethod1()进行修改,在方法中访问静态方法staticMethod2()。在main()方法中调用静态方法staticMethod1(),代码如下所示:

public class Example10{

static void staticMethod1() {

System.out.println("静态方法1");

staticMethod2();

}

static void staticMethod2() {

System.out.println("静态方法2");

}

void nonStaticMethod1() {

System.out.println("非静态方法1");

}

void nonStaticMethod2() {

System.out.println("非静态方法2");

}

public static void main(String[] args) {

Example10.staticMethod1();

}

}

运行结果如图3-15所示。

图3-15运行结果

从运行结果可以看到,程序正常执行,这说明在静态方法中可以访问静态方法。

3、对静态方法staticMethod1()进行修改,在方法中访问非静态方法nonStaticMethod1(),代码如下所示:

public class Example10{

static void staticMethod1() {

System.out.println("静态方法1");

nonStaticMethod1();

}

static void staticMethod2() {

System.out.println("静态方法2");

}

void nonStaticMethod1() {

System.out.println("非静态方法1");

}

void nonStaticMethod2() {

System.out.println("非静态方法2");

}

public static void main(String[] args) {

Example10.staticMethod1();

}

}

运行结果如图3-16所示。

图3-16运行结果

从错误提示信息可以看到,发生错误的原因是在静态方法中访问了非静态的方法。

4、在staticMethod1()方法中,将代码“nonStaticMethod1()”注释掉,并对非静态方法nonStaticMethod1()进行修改,在方法中分别调用静态方法statiMethod1()和非静态方法nonStaticMethod2()。在main()方法中创建Example09的实例对象,调用nonStaticMethod1()方法,代码如下所示:

public class Example10{

static void staticMethod1() {

System.out.println("静态方法1");

// nonStaticMethod1();

}

static void staticMethod2() {

System.out.println("静态方法2");

}

void nonStaticMethod1() {

System.out.println("非静态方法1");

staticMethod1();

nonStaticMethod2();

}

void nonStaticMethod2() {

System.out.println("非静态方法2");

}

public static void main(String[] args) {

Example10 e = new Example10();

e.nonStaticMethod1 ();

}

}

运行结果如图3-17所示。

图3-17运行结果

从运行结果可以看到,程序正常执行,这说明在非静态方法中既可以方法静态方法,也可以访问非静态方法。

三、案例总结

1、在静态方法中只能访问静态方法,在非静态方法中可以访问静态方法和非静态方法。

2、思考一下:在静态方法中是否能够访问静态变量和非静态变量?其实和上面的讲解一样,非静态变量只能通过对象或者对象的引用变量访问,而静态方法在创建对象之前就可以通过类名直接访问,因此在静态方法中不能访问非静态变量,只能访问静态变量。

案例3-10 代码块

一、案例描述

1、考核知识点

编号:00103011

名称:静态代码块

2、练习目标

?理解代码块的不同分类

?掌握不同代码块的作用及其执行时机

3、需求分析

有时候,需要将某一段关联紧密的或者实现了某一功能的代码封装的一个代码块中。为了让初学者熟悉代码块的应用,本案例将编写一个包含了静态代码块,局部代码块和构造代码块的类,演示不同代码块之间的执行时机。

4、设计思路(实现原理)

1)编写Example11类,在类中定义一个静态代码块、一个构造代码块、一个无参的构造方法和一个成员方法localBlock(),在localBlock()方法中定义一个局部代码块。

2)创建Example11类的两个实例对象,使用Example11类型的变量e1和e2引用,并通过变量e1和e2调用这两个对象的localBlock()方法。

二、案例实现

定义Example11类,代码如下所示:

public class Example11 {

static {

System.out.println("静态代码块");

}

{

System.out.println("构造代码块");

}

public Example11() {

System.out.println("构造方法");

}

void localBlock() {

{

System.out.println("局部代码块");

}

}

public static void main(String[] args) {

Example11 e1 = new Example11();

e1.localBlock();

System.out.println("-----------------");

Example11 e2 = new Example11();

e2.localBlock();

}

}

运行结果如图3-18所示。

图3-18运行结果

三、案例总结

1、静态代码块在加载类的时候执行,由于类只在第一次使用时被加载,且只加载一次,因此静态代码块只执行一次。从运行结果可以看到,虽然创建了两个Example10的实例对象,由于Example10类只会加载一次,所以“静态代码块”只打印一次。

在实际开发中,经常有一些代码需要在类加载时就执行,比如加载数据库驱动,这些代码就应该放在静态代码块中。

2、构造代码块在创建类的实例对象时执行,也就是说每次创建类的实例对象时,都会执行一次构造代码块。从运行结果可以看到,构造代码块优先于构造方法执行,因此在实际开发中,可以把重载构造方法中重复的代码抽取到构造代码块中执行。

3、局部代码块定义在方法中,它在方法被调用的时候执行。使用局部代码块是为了限制变量的生命周期,使变量在使用完毕后被尽快回收,从而节省存空间。

案例3-11 单例设计模式

一、案例描述

1、考核知识点

编号:00103012

名称:单例设计模式

2、练习目标

?了解什么是单例设计模式

?掌握单例设计模式的特点

3、需求分析

在程序开发中,经常需要保证类的实例对象只有一个,这时,可以将类设计为单例设计模式。

为了让初学者熟悉单例设计模式,本案例将编写一个实现了单例设计模式的类。

4、设计思路(实现原理)

1)定义一个类Singleton,为了保证该类只能创建一个实例对象,在类中定义一个私有的构造方法。

2)在类中创建一个该类的实例对象,并且定义一个静态变量INSTANCE(变量名随意)引用此实例对象。

3)为了防止外界使用Singleton.INSTANCE的方式直接访问该实例对象,将INSTANCE变量使用private关键字修饰为私有,同时提供一个用于返回实例对象的静态方法。

二、案例实现

1、定义Singleton类,在类中定义一个私有,无参的构造方法,代码如下:

public class Singleton {

private Singleton() {}

}

2、创建Singleton的一个实例对象,定义一个私有的静态变量INSTANCE引用这个对象,代码如下所示:

public class Singleton {

private Singleton() {}

private static Singleton INSTANCE = new Singleton();

}

3、定义一个静态方法getInstance()将实例对象返回,代码如下:

public class Singleton {

private Singleton() {

第3章 面向对象程序设计基础

第3章面向对象程序设计基础

第3章面向对象程序设计基础 【1】什么是Java程序使用的类?什么是类库? 答:类是将一类事物的特性描述出来,然后如果用这个类来定义对象,则该对象就拥有了这个类所描述的所有特性。 在Java系统中,系统定义好的类根据实现的功能不同,可以划分成不同的集合,每个集合称为一个包,所有包合称为类库。 【2】如何定义方法?在面向对象程序设计中方法有什么作用? 答:方法的定义由两部分组成:方法声明和方法体。 方法的声明如下: 返回值类型方法名(参数类型形式参数1,参数类型形式参数2…){ 程序代码; 返回值; } 在面向对象程序设计中,方法的作用是完成对类和对象属性操作。 【3】简述构造方法的功能和特点。下面的程序片段是某学生为student类编写的构造方法,请指出其中的错误。 void Student(int no,String name) {

studentNo=no; studentName=name; return no; } 答:构造方法的功能是:构造方法是一个特殊的方法,主要用于初始化新创建的对象; 特点:构造方法的方法名要求与类名相同,用户不能直接调用,只能通过new运算符调用,而且构造方法是不返回任何数据类型,甚至也不返回void数据类型,即不能在构造方法前加void。 错误之处:(1)构造方法Student()前不能加void,(2)不能用return语句,(3)类名Student 首字母S改成小写s. 【4】定义一个表示学生的student类,包括的域有学号、姓名、性别、年龄,包括的方法有获得学号、姓名、性别、年龄及修改年龄。编写Java程序创建student类的对象及测试其方法的功能。 class Student { String id; String name; String sex; int age; void talk(){

第三章 面向对象程序设计(答案)

学号:姓名: 第三章面向对象程序设计作业 一、判断题 1、一个Java源程序可有多个类,但只仅有一个public类,而且程序名与public类名相同。对 2、如果类A和类B在同一个包中,则除了私有成员外,类A可以访问类B中所有的成员。对 3、接口中的成员变量全部为常量,方法为抽象方法。对 4、抽象类可以有构造方法,可以直接实例化。错 5、对static方法的调用可以不需要类实例。对 6、包含抽象方法的类一定是抽象类。对 7、方法中的形参可以和方法所属类的属性同名。对 8、接口无构造器,不能有实例,也不能定义常量。错 9、类的实例对象的生命周括实例对象的创建、使用、废弃、垃圾的回收。对 10、Java应用程序的入口main方法只有一种定义法。对 二、选择题 1、下列答案正确的是(A) A) 在同一个Java源文件中可以包含多个类,只能有一个被声明为public B) 在同一个Java源文件中只能包含一个类,并被声明为public C) 在同一个Java源文件中可以包含多个类,都可以被声明为public D) 在同一个Java源文件中可以包含多个类,只能有一个被声明为default 2、Java实现动态多态性是通过(B)实现的。 A) 重载B) 覆盖 C) 接口D) 抽象类 3、下列哪一个是正确的方法重载描述(A) A) 重载方法的参数类型必须不同 B) 重载方法的参数名称必须不同 C) 返回值类型必须不同 D) 修饰词必须不同 4、final关键字不可以用来修饰(D) A) 类B) 成员方法 C) 域D) 接口 5、接口的所有成员方法都具有(B)属性 A) private, final B) public, abstract C) static, protected D) static 6、Java的封装性是通过(A)实现的 A) 访问控制B) 设计内部类 C) 静态域和静态方法D) 包 7、下列接口或类不属于java.util.*包的是(D) A) Collection B)Vector C) MapD) Integer 8、下述哪一组方法,是一个类中方法重载的正确写法?(A) A) int addValue( int a, int b ){return a+b;}

第3章-面向对象(上)-补充案例

第三章补充案例 案例3-1 定义学生类 一、案例描述 1、考核知识点 编号:2 名称:类和对象 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() { System.out.println("我的名字是 "+name+",今年 "+age+"岁"); } } 三、案例总结 1、Java语言严格区分大小写,class和Class是不同的,在定义类时只能使用class关键字 2、在Student类中,成员变量name是String类型,String表示一个字符串,后面的章节会详细讲解 3、思考一下:自己定义一个手机(Phone)类,在类中定义品牌(brand)和价格(price)属性,定义打电话的call()方法,代码如下所示 public class Phone {

第三章 面向对象程序设计答案

学号: 姓名: 第三章面向对象程序设计作业 一、判断题 1、一个Java源程序可有多个类,但只仅有一个public类,而且程序名与public类名相同。对 2、如果类A与类B在同一个包中,则除了私有成员外,类A可以访问类B中所有的成员。对 3、接口中的成员变量全部为常量,方法为抽象方法。对 4、抽象类可以有构造方法,可以直接实例化。错 5、对static方法的调用可以不需要类实例。对 6、包含抽象方法的类一定就是抽象类。对 7、方法中的形参可以与方法所属类的属性同名。对 8、接口无构造器,不能有实例,也不能定义常量。错 9、类的实例对象的生命周括实例对象的创建、使用、废弃、垃圾的回收。对 10、Java应用程序的入口main方法只有一种定义法。对 二、选择题 1、下列答案正确的就是( A ) A) 在同一个Java源文件中可以包含多个类,只能有一个被声明为public B) 在同一个Java源文件中只能包含一个类,并被声明为public C) 在同一个Java源文件中可以包含多个类,都可以被声明为public D) 在同一个Java源文件中可以包含多个类,只能有一个被声明为default 2、Java实现动态多态性就是通过( B )实现的。 A) 重载B) 覆盖 C) 接口D) 抽象类 3、下列哪一个就是正确的方法重载描述( A ) A) 重载方法的参数类型必须不同 B) 重载方法的参数名称必须不同 C) 返回值类型必须不同 D) 修饰词必须不同 4、final关键字不可以用来修饰( D ) A) 类B) 成员方法 C) 域D) 接口 5、接口的所有成员方法都具有( B )属性 A) private, final B) public, abstract C) static, protected D) static 6、Java的封装性就是通过( A )实现的 A) 访问控制B) 设计内部类 C) 静态域与静态方法D) 包 7、下列接口或类不属于java、util、*包的就是( D ) A) Collection B)Vector C) Map D) Integer 8、下述哪一组方法,就是一个类中方法重载的正确写法?( A ) A) int addValue( int a, int b ){return a+b;} float addValue ( float a, float b) {return a+b;} B) int addValue (int a, int b ){value=a+b; }

第3章 面向对象程序设计基础 答案

第3章面向对象程序设计基础 【1】什么是Java程序使用的类?什么是类库? [解答]:Java程序的基本单位是类。对象是对事物的抽象,而类是对对象的抽象和归纳,找出事物的共性,把具有共同性质的事物归结为一类。累是具有相同属性和方法的一组对象的集合,类是在对象之上的抽象,对象是类的实例化,类定义一种对象能够拥有的数据和能完成的操作。一旦建立类后,就可用它来建立许多你需要的对象。 Java的类库是系统提供的已实现的标准类的集合,是Java编程的API,它可以帮助开发者方便、快捷的开发Java程序。 【2】如何定义方法?在面向对象程序设计中方法有什么作用? [解答]:方法的定义由两部分组成:方法声明和方法体。方法声明的基本格式如下: 返回类型方法名(形式参数) { …//方法体内容 } 方法声明包括方法名、返回类型和形式参数,方法的小括号是方法的标志;方法体为实现方法行为的Java语句。 在面向对象程序设计中,方法所起的作用是完成类和对象的属性操作。 【3】简述构造方法的功能和特点。下面的程序片段是某学生为student类编写的构造方法,请指出其中的错误。 void Student(int no,String name) { studentNo=no; studentName=name; return no; } [解答]:构造方法是一个特殊的方法,主要用于初始化新创建的对象。构造方法的方法名要求与类名相同,用户不能直接调用,只能通过new运算符调用,构造方法不返回任何数据类型,也不返回void数据类型,即不能在构造方法前加void。 上面的代码出错处:(1)构造方法student前不能加void.(2)不能用return语句。【4】定义一个表示学生的student类,包括的域有学号、姓名、性别、年龄,包括的方法有获得学号、姓名、性别、年龄及修改年龄。编写Java程序创建student类的对象及测试其方法的功能。 [解答]:class student{ private String id; private String name; private String sex; private int age; public String getId() {return id; } public String getName()

第三章面向对象程序的设计(答案)

学号:: 第三章面向对象程序设计作业 一、判断题 1、一个Java源程序可有多个类,但只仅有一个public类,而且程序名与public类名相同。对 2、如果类A和类B在同一个包中,则除了私有成员外,类A可以访问类B中所有的成员。对 3、接口中的成员变量全部为常量,方法为抽象方法。对 4、抽象类可以有构造方法,可以直接实例化。错 5、对static方法的调用可以不需要类实例。对 6、包含抽象方法的类一定是抽象类。对 7、方法中的形参可以和方法所属类的属性同名。对 8、接口无构造器,不能有实例,也不能定义常量。错 9、类的实例对象的生命周括实例对象的创建、使用、废弃、垃圾的回收。对 10、Java应用程序的入口main方法只有一种定义法。对 二、选择题 1、下列答案正确的是(A) A) 在同一个Java源文件中可以包含多个类,只能有一个被声明为public B) 在同一个Java源文件中只能包含一个类,并被声明为public C) 在同一个Java源文件中可以包含多个类,都可以被声明为public D) 在同一个Java源文件中可以包含多个类,只能有一个被声明为default 2、Java实现动态多态性是通过(B)实现的。 A) 重载B) 覆盖 C) 接口D) 抽象类 3、下列哪一个是正确的方法重载描述(A) A) 重载方法的参数类型必须不同 B) 重载方法的参数名称必须不同 C) 返回值类型必须不同 D) 修饰词必须不同 4、final关键字不可以用来修饰(D) A) 类B) 成员方法 C) 域D) 接口 5、接口的所有成员方法都具有(B)属性 A) private, final B) public, abstract C) static, protected D) static 6、Java的封装性是通过(A)实现的 A) 访问控制B) 设计部类 C) 静态域和静态方法D) 包 7、下列接口或类不属于java.util.*包的是(D) A) Collection B)Vector C) MapD) Integer 8、下述哪一组方法,是一个类中方法重载的正确写法?(A) A) int addValue( int a, int b ){return a+b;}

相关主题
相关文档
最新文档