第四章 类和对象 合集

4.1面向对象概述

        在程序开发初期,人们使用结构化开发语言,但随着软件的规模越来越庞大,结构化语言的弊端也逐渐暴露出来,开发周期被无休止地拖延,产品的质量也不尽如人意,结构化语言已经不再适合当前的软件开发。这时,人们开始将另一种开发思想引入程序中,即面向对象的开发思想。面向对象思想是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,同时了解这些对象具有哪些相应的属性以及行为,以解决这些对象面临的一些实际问题,这样就在程序开发中引入了面向对象设计的概念,面向对象设计实质上就是对现实世界的对象进行建模操作。

        4.1.1 对象

        对象,是一个抽象概念,英文称作“Object”,表示任意存在的事物。世间万物皆对象!现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体,例如一个人。通常将对象划分为两个部分,即静态部分与动态部分。静态部分被称为“属性”,任何对象都具备自身属性,这些属性不仅是客观存在的,而且是不能被忽视的,例如人的性别;动态部分指的是对象的行为,即对象执行的动作,例如人可以行走。

        4.1.2 类

        类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类。例如,把雁群比作大雁类,那么大雁类就具备了喙、翅膀和爪等属性,觅食、飞行和睡觉等行为,而一只要从北方飞往南方的大雁则被视为大雁类的一个对象。

        在Java语言中,类包括对象的属性和方法。类中对象的属性是以成员变量的形式定义的,对象的行为是以方法的形式定义的,有关类的具体实现会在后续内容中予以介绍。

        4.1.3 封装

        封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常会对客户隐藏其实现细节,这就是封装的思想。例如,用户使用计算机时,只需要使用手指敲击键盘就可以实现一些功能,而无须知道计算机内部是如何工作的。

        采用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据。这样就避免了外部操作对内部数据的影响,提高了程序的可维护性。

        4.1.4 继承

        矩形、菱形、平行四边形和梯形都是四边形。因为四边形与它们具有共同的特征:拥有4个边。只要将四边形适当的延伸,就会得到上述图形。以平行四边形为例,如果把平行四边形看作四边形的延伸,那么平行四边形就复用了四边形的属性和行为,同时添加了平行四边形特有的属性和行为,如平行四边形的对边平行且相等。Java中,可以把平行四边形类看作是继承四边形类后产生的类,其中,将类似于平行四边形的类称为子类,将类似于四边形的类称为父类或超类。值得注意的是,在阐述平行四边形和四边形的关系时,可以说平行四边形是特殊的四边形,但不能说四边形是平行四边形。同理,Java中可以说子类的实例都是父类的实例,但不能说父类的实例是子类的实例。

        综上所述,继承是实现重复利用的重要手段,子类通过继承复用了父类的属性和行为的同时又添加了子类特有的属性和行为。

        4.1.5 多态

        将父类对象应用于子类的特征就是多态。首先创建一个螺丝类,螺丝类有两个属性:粗细和螺纹密度;然后再创建了两个类,一个是长螺丝类,一个短螺丝类,并且它们都继承了螺丝类。这样长螺丝类和短螺丝类不仅具有相同的特征(粗细相同,且螺纹密度也相同),还具有不同的特征(一个长,一个短,长的可以用来固定大型支架,短的可以固定生活中的家具)。综上所述,一个螺丝类衍生出不同的子类,子类继承父类特征的同时,也具备了自己的特征,并且能够实现不同的效果,这就是多态化的结构。

 4.2 类

        类是封装对象的属性和行为的载体,Java中定义类使用class关键字,其语法如下:

class 类名称{

   // 成员变量

   // 成员方法()

}

        在Java语言中对象的属性以成员变量的形式存在,对象的方法以成员方法的形式存在。本节将对类与对象进行详细讲解。 

        4.2.1 成员变量

        在Java中对象的属性也称为成员变量,成员变量的定义与普通变量的定义一样,语法如下:

数据类型 变量名称 [ = 值] ;

        [ = 值]表示可选内容,即:定义变量时可以为其赋值,也可以不为其赋值。 

        Java代码中使用class关键字来定义类,成员变量的类型可以设置为Java中合法的数据类型,其实成员变量就是普通的变量,可以为它设置初始值,也可以不设置初始值。如果不设置初始值,则会有默认值。Java中常见类型的默认值如表4.1所示。

表4.1 JAVA中常见类型的默认值
数据类型默认值说明
byte、short、int、long0整形零
float、double0.0浮点零
char‘ ’空格字符
booleanfalse逻辑假
引用类型,例如Stringnull空值

        4.2.2 成员方法 

        在JAVA语言中,成员方法对应于类对象的行为,它主要用来定义类可执行的操作,包含一系列语句的代码块,本节将对成员方法进行详细讲解。

        定义成员方法的语法格式如下:

[权限修饰符] [返回值类型] 方法名( [参数类型 参数名] ) [throws 异常类型] {

    …// 方法体

    return 返回值;

}

        其中,权限修饰符可以是private、public、protected中的任一个,也可以不写,主要用来控制方法的访问权限,关于权限修饰符将在下一章中详细讲解;“返回值类型”指定方法返回数据的类型,可以是任何类型,如果方法不需要返回值,则使用void关键字;一个成员方法既可以有参数,也可以没有参数,参数可以是对象也可以是基本数据类型的变量。

        如果定义的方法有返回值,则必须使用return关键字返回一个指定类型的数据,并且返回值类型要与方法返回的值类型一致。

        调用方法时可以给该方法传递一个或多个值,传给方法的值叫作实参,在方法内部,接收实参的变量叫作形参,形参的声明语法与变量的声明语法一样。形参只在方法内部有效。Java中方法的参数主要有3种,分别为值参数、引用参数和不定长参数,下面分别进行讲解。

        值参数表明实参与形参之间按值传递,当使用值参数的方法被调用时,编译器为形参分配存储单元,然后将对应的实参的值复制到形参中,由于是值类型的传递方式,所以,在方法中对值类型的形参的修改并不会影响实参。

        引用参数,如果在给方法传递参数时,参数的类型是数组或者其他引用类型,那么,在方法中对参数的修改会反映到原有的数组或者其他引用类型上,这种类型的方法参数被称之为引用参数。

        不定长参数,声明方法时,如果有若干个相同类型的参数,可以定义为不定长参数,该类型的参数声明如下:

权限修饰符 返回值类型 方法名(参数类型… 参数名)

        4.2.3权限修饰符

         Java中的权限修饰符主要包括private、public和protected,这些修饰符控制着对类和类的成员变量以及成员方法的访问。如果一个 类的成员变量或成员方法被修饰为private, 则该成员变量只能在本类中使用,在子类中是不可见的,并且对其他包的类也是不可见的。如果将类的成员变量和成员方法的访问权限设置为rpablic,那么除了可以在本类中使用这些数据,还可以在子类和其他包的类中使用这些数据。.如果一个类的访问权限被设置为private,这个类将隐藏其内的所有数据,以免用户直接访问它。如果需要使类中的数据被子类或其他包中的类使用,则可以将这个类设置为public访问权限。如果一个类使用prftected修饰符,那么只有本包内的该类的子类或其他类可以访问此类中的成员变量和成员方法。这么看来,public 和protected修饰的类可以由子类进行访问,如果子类和父类不在同包中,那么只有修饰符为public的类可以被子类进行访问。如果父类不允许通过继承产生的子类访问它的成员变量,那么必须使用private声明父类的这个成员变量。表4.2中描述了private、 protected 和public修饰符的修饰权限。

表4.2 JAVA语言中的权限符权限
访问包位置类修饰符
privateprotectedpublic
本类可见可见可见
同包其他类或子类不可见可见可见
其他包的类或者子类不可见不可见可见

        4.2.4局部变量 

        如果在成员方法内定义一个变量,那么这个变量被称为局部变量。

        局部变量是在方法执行时被创建,在方法执行结束时被销毁。局部变量在使用时必须进行赋值操作或被初始化,否则会出现编译错误。

        4.2.5this关键字

        当类中的成员变量与成员方法中的参数重名时,方法中如何使用成员变量呢?首先来看一下重名的情况下会发生什么问题。

        如果方法中出现了与局部变量同名的参数,会导致方法无法直接使用该成员变量。

        成员变量与在showName()方法中的形式参数的名称相同,都为name,那么该如何在类中区分使用的是哪一个变量呢?在Java语言中规定使用this关键字来代表本类对象的引用,this关键字被隐式地用于引用对象的成员变量和方法。

        事实上,this关键字引用的就是本类的一个对象,在局部变量或方法参数覆盖了成员变量时,如上面代码的情况,就要添加this关键字明确引用的是类成员还是局部变量或方法参数。

        如果省略this关键字直接写成name = name,那只是把参数name赋值给参数变量本身而已,成员变量name的值没有改变,因为参数name在方法的作用域中覆盖了成员变量name。

        其实,this关键字除了可以调用成员变量或成员方法之外,还可以作为方法的返回值。

 4.3 类的构造方法

        在类中除了成员方法之外,还存在一种特殊类型的方法,那就是构造方法。构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。每当类实例化一个对象时,类都会自动调用构造方法。

        构造方法的特点如下:

        构造方法没有返回类型,也不能定义为void。

        构造方法的名称要与本类的名称相同。

        构造方法的主要作用是完成对象的初始化工作,它能把定义对象的参数传给对象成员。

        构造方法的定义语法如下:

class Book {

public Book() { // 构造方法

     

}

}

        public :构造方法修饰符。

        Book :构造方法的名称,与类同名。

        在构造方法中可以为成员变量赋值,这样当实例化一个本类的对象时,相应的成员变量也将被初始化。如果类中没有明确定义构造方法,则编译器会自动创建一个不带参数的默认构造方法。

        除此之外,在类中定义构造方法时,还可以为其添加一个或者多个参数,即有参构造方法,语法如下:

class Book {

public Book(int args) { // 有参数构造方法

// 对成员变量进行初始化

    }

}

        public:构造方法修饰符。

        Book:构造方法的名称。

        args:构造方法的参数,可以是多个参数。

4.4 静态变量和静态方法

        由static关键字修饰的变量、常量和方法分别被称作静态变量、静态常量和静态方法,也被称作类的静态成员。

        4.4.1 静态变量

        很多时候,不同的类之间需要对同一个变量进行操作,比如一个水池,同时打开入水口和出水口,进水和出水这两个动作会同时影响到水池中的水量,此时水池中的水量就可以认为是一个共享的变量。在Java程序中,如果把共享的变量用static修饰,那么该变量就是静态变量。

        调用静态变量的语法如下:

类名.静态类成员

        4.4.2 静态方法

        如果想要使用类中的成员方法,需要先将这个类进行实例化,但有些时候不想或者无法创建类的对象时,还要调用类中的方法才能够完成业务逻辑,这种情况下就可以使用静态方法。

        调用类的静态方法语法如下:

类名.静态方法();

        4.2.3 静态代码块

        用static关键字修饰的代码区域可以称之为静态代码块。定义一块静态代码块,可以完成类的初始化操作,在类声明时就会运行。

        语法如下:

public class StaticTest {

static {

// 此处编辑执行语句

}

}

        最后总结使用static关键字要注意以下几点:

                在静态方法中不可以使用this关键字;

                在静态方法中不可以直接调用非静态方法;

                局部变量不可以用static关键字进行声明;

                主方法必须用static关键字声明;

                只有内部类可以使用static关键字进行声明。

 4.5 类的主方法

        主方法是类的入口点,它指定了程序从何处开始;主方法提供对程序流向的控制,Java编译器通过主方法来执行程序。

        主方法的语法如下:

public static void main(String[] args){

// 方法体

}

        在主方法的定义中可以看到主方法具有以下特性:

        主方法是静态的,所以如要直接在主方法中调用其他方法,则该方法必须也是静态的。

        主方法没有返回值。

        运行时参数。其中args[0]~args[n]分别代表程序的第一个参数到第n+1个参数,可以使用args.length获取参数的个数。

4.6 对象

        JAVA是一门面向对象的程序设计语言,对象是由类实例化而来的,所有问题都通过对象来处理。对象可以通过操作类的属性和方法来解决相应的问题,因此了解对象的产生、操作和消亡是十分必要的。本节就来讲解对象在Java语言中的应用。

        4.6.1 对象的创建

        在4.1节中曾经讲解过对象,对象可以被认为是在一-类事物中抽象出的某一个特例,程序开发人员可以通过这个特例处理这类事物出现的问题。在JAVA语言中,通过new操作符创建对象。前文在讲解构造方法时介绍过,每实例化个对象就会自动调用次构造方法, 实质上这个过程就是创建对象的过程。准确地说,可以在JAVA语言中使用now操作符调用构造方法创建对象。语法如下:

Test test = new Test();
Test test = new Test("a");

        test对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间。6.3 节中介绍过,可以在构造方法中初始化成员变量,当创建对象时,自动调用构造方法。也就是说,在Java语言中,初始化与创建是被捆绑在一起的。

        每个对象都是相互独立的,在内存中占据独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成垃圾,由JAVA虚拟机自带的垃圾回收机制处理,不能再破使用(对于垃圾回收机制的知识将在4.6.4 节中进行讲解)。 

        4.6.2 访问对象的属性和行为

        用户使用new操作符创建一个对象后, 可以使用“对象类成员"来获取对象的属性和行为。前文已经提到过,对象的属性和行为在类中是通过类的成员变量和成员方法的形式来表示的,因此当对象获取类成员时,也相应地获取了对象的属性和行为。

        4.6.3 对象的引用

        在JAVA语言中,尽管一切都可以被看作是对象,但真正的操作标识符实质上是一个引用,那么引用在JAVA中是如何体现的呢?语法如下:

类名 对象的引用变量

类名 引用 = 对象的实体

people tom = new people();

        4.6.4 对象的销毁

        每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址需要要被回收。在其他语言中,需要用户手动回收废弃的对象。JAVA 拥有套完整的垃圾回收机制,用户不必担心废弃的对象会占用内存,垃圾回收器会自动回收无用却占用内存的资源。

        在学习垃圾回收机制之前,读者首先需要了解何种对象会被Java虚拟机视为“垃圾”。

        虽然JAVA的垃圾回收机制已经很完善,但垃圾回收器只能回收那些由new操作符创建的对象。某些对象不是通过new操作符在内存中获取存储空间的,这种对象无法被垃圾回收机制所识别。在JAVA中,提供了一个finalize(方法,这个方法是Obect类的方法,它被声明为protected, 用户可以在自己的类中定义这个方法。如果用户在类中定义了finalize()方法,在垃圾回收时会首先调用该方法,在下一次垃圾回收动作发生时, 才真正回收被对象占用的内存。

        需要明确的是,垃圾回收或finalize()方法并不保证一定会发生。如果JJAVA虚拟机内存损耗待尽,它将不会执行垃圾回收处理。

        由于垃圾回收不受人为控制,具体执行时间也不确定,因此finalize()方法也就无法执行。为此,JAVA提供了System.gc()方法来强制启动垃圾回收器,这与给120 打电话通知医院来救护病人的道理一样,主动告知垃圾回收器来进行清理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值