`

实例变量的访问及数据封装

阅读更多

    你已经看到处理分数的方法如何通过名称直接访问两个实例变量numerator和denominator。事实上,实例方法总是可以直接访问它的实例变量的。然而,类方法则不能,因为它只处理本身,并不处理任何类实例(仔细想想)。但是,如果要从其他位置访问实例变量,例如,从main函数内部来访问,该如何实现?在这种情况下,不能直接访问这些实例变量,因为它们是隐藏的。将实例变量隐藏起来的这种做法实际上涉及一个关键概念——“数据封装”。它使得编写定义的人在不必担心程序员(即类的使用者)是否破坏类的内部细节的情况下,扩展和修改其定义。数据封装提供了程序员和其他开发者之间的良好隔离层。

       通过编写特殊方法来检索实例变量的值,可以用一种新的方式来访问它们。编写setNumerator:setDenominator:方法用于给Fraction类的两个实例变量设定值。为了获取这些实例变量的值,我们需要编写新的方法。例如,创建两个名为numeratordenominator的新方法,用于访问相应的Fraction实例变量,这些实例是消息的接收者。结果是对应的整数值,你将返回这些值。以下是这两个新方法的声明:

–(int) numerator;

–(int) denominator;

下面是定义:

–(int) numerator

{

   return numerator;

}

 

–(int) denominator

{

   return denominator;

}

注意,它们访问的方法名和实例变量名是相同的,这样做不存在任何问题(虽然似乎有些奇怪)。事实上,这是很常见的情况。代码清单3-4用来测试这两个新方法。

代码清单3-4

// 访问实例变量的程序 – cont'd

 

#import <Foundation/Foundation.h>

 

//---- @interface 部分 ----

 

@interface Fraction: NSObject

 

-(void) print;

-(void) setNumerator: (int) n;

-(void) setDenominator: (int) d;

-(int) numerator;

-(int) denominator;

 

@end

 

//---- @implementation 部分 ----

 

@implementation Fraction

{

   int  numerator;

   int  denominator;

}

 

-(void) print

{

   NSLog (@"%i/%i", numerator, denominator);

}

 

-(void) setNumerator: (int) n

{

    numerator = n;

}

 

-(void) setDenominator: (int) d

{

    denominator = d;

}

 

-(int) numerator

{

    return numerator;

}

 

-(int) denominator

{

    return denominator;

}

 

@end

 

//---- program 部分 ----

 

int main (int argc, char *argv[])

{

   @autoreleasepool {

      Fraction  *myFraction = [[Fraction alloc] init];

 

      // 设置分数为1/3

 

      [myFraction setNumerator: 1];

      [myFraction setDenominator: 3];

 

      // 使用两个新的方法显示分数

 

      NSLog (@"The value of myFraction is: %i/%i",

           [myFraction numerator], [myFraction denominator]);

    }

 

    return 0;

}

 

代码清单3-4  输出

The value of myFraction is 1/3

 

NSLog语句显示发送给myFraction:的两条消息的结果,第一条消息检索numerator的值,第二条则检索denominator的值。

NSLog (@"The value of myFraction is: %i/%i",

    [myFraction numerator], [myFraction denominator]);

在第一条消息调用时,numerator消息会发送给Fraction类的对象myFraction。在这个方法中,分数中numerator的实例变量的值被返回。记住,方法执行的上下文环境就是接收到消息的对象。当访问numerator方法并且返回numerator实例变量值的时候,会取得myFraction的分子并返回,返回的整数传入NSLog,从而显示出来。第二条消息调用时,denominator方法会被调用并返回myFraction的分母,它仍通过NSLog显示。

顺便说一下,设置实例变量值的方法通常总称为设值方法(setter),而用于检索实例变量值的方法叫做取值方法(getter)。对Fraction而言,setNumerator:和setDenominator:是设值方法,numeratordenominator是取值方法。取值方法和设值方法通常称为访问器(accessor)方法。

确定你已经理解了设值方法和取值方法的不同。设值方法不会返回任何值,因为其主要目的是将方法参数设为对应的实例变量的值。在这种情况下并不需要返回值。另一方面,取值方法的目的是获取存储在对象中的实例变量的值,并通过程序返回发送出去。基于此目的,取值方法必须返回实例的值作为return的参数。

你不能在类的外部编写方法直接设置或获取实例变量的值,而需要编写设值方法和取值方法来设置或获取实例变量的值,这便是数据封装的原则。你必须通过使用一些方法来访问这些通常对“外界”隐藏的数据。这种做法集中了访问实例变量的方式,并且能够阻止其他一些代码直接改变实例变量的值。如果可以直接改变,会让程序很难跟踪、调试和修改。

这里还应指出,还有一个名为new的方法可以将allocinit的操作结合起来。因此,程序行

Fraction *myFraction = [Fraction new];

可用于创建和初始化新的Fraction。但用两步来实现创建和初始化的方式通常更好,这样可以在概念上理解正在发生两个不同的事件:首先创建一个对象,然后对它初始化。

 

 

 

本文节选自《Objective-C 程序设计(4)

 

电子工业出版社出版

[]Stephen G. Kochan(斯蒂芬·G·科昌)著

林冀  范俊朱奕欣译

分享到:
评论

相关推荐

    java入门教程:数据类型_实例变量.docx

    Java编程语言是面向对象的,其中数据类型和实例变量是构建程序的基础元素。在这个Java入门教程中,我们将深入探讨这两个...在编写类和对象时,合理地使用实例变量和适当的访问控制,可以确保代码的封装性和可维护性。

    Java中实例变量与类变量测试的代码清单.pdf

    同时,合理地利用实例变量可以有效地封装对象的状态,实现数据隐藏和面向对象设计原则。 参考文献: [1] 耿祥义. Java 2 实用教程[M]. 北京:清华大学出版社,2015. 总之,Java 中的实例变量和类变量是对象状态和...

    VC封装ADO访问数据库的代码实例

    在VC++开发环境中,MFC(Microsoft Foundation Classes)是一个强大的库,它...这个代码实例对于初学者和开发者来说都是很好的学习和参考材料,帮助理解数据库访问的底层机制以及如何在VC++环境中优雅地实现数据操作。

    实例8访问控制(java实例系列)

    总结,"实例8访问控制"是一个关于Java访问控制的关键实践案例,通过实际编程加深了对访问控制的理解,帮助开发者掌握如何有效地控制代码的可见性和访问权限,以实现良好的封装性和模块化设计。通过这个实例,我们...

    一个实例告诉你什么是封装继承和多态二

    例如,在`ConsoleApplication1`项目中,可能包含一个名为`Person`的类,这个类有私有变量`_name`和`_age`,仅通过公共方法如`GetName()`和`SetAge(int newAge)`来访问或修改这些私有数据,这样可以防止外部代码直接...

    2021考研计算机基础知识点详解:数据封装.doc

    数据封装是计算机科学中一种重要的概念,特别是在面向对象编程中占据核心地位。它是指将数据和操作这些数据的方法结合在一起,作为一个独立的单元,对外只暴露必要的接口,隐藏内部实现细节。这一概念对于理解计算机...

    java封装封装的概念

    Java封装是面向对象编程的核心概念之一,它是将数据和对数据的操作绑定在一起,形成一个独立的单元,对外只提供统一的访问接口。这样的设计能够提高代码的安全性,降低耦合度,使得程序更加模块化,易于维护和扩展。...

    VC共享内存封装类及实例

    《VC共享内存封装类及实例解析》 在Windows编程中,有时我们需要在多个进程之间共享数据,这时可以利用操作系统提供的共享内存机制。本文将详细解析一个基于VC6.0的共享内存封装类及其实例,帮助读者理解如何在C++...

    JAVA封装类练习题

    5. **访问控制与封装实例**: - 在"ch7封装"的练习中,可能包含了一些具体的例子,比如创建一个学生类(Student),其中包含姓名(name)、年龄(age)等私有属性,然后提供相应的getter和setter方法。通过这些方法...

    C#版本的一个封装和反射实例

    在本实例中,可能包含一个类,这个类有一些私有的成员变量,然后通过公有的getter和setter方法来访问这些变量。这样,类的内部实现细节对外部代码隐藏,增强了代码的可维护性和可扩展性。 接下来,我们来看反射。...

    ADO封装类文件 数据库访问

    3. **记录集操作**: 通过封装Recordset对象,提供获取数据的方法,如GetNextRow、GetField等,便于遍历和访问查询结果。 4. 错误处理:封装了ADO的Error对象,当发生错误时,可以提供错误信息。 5. **事务处理**: ...

    Java 变量类型总结.docx

    默认情况下,实例变量应设为私有,以保护数据的封装性,但可以通过访问修饰符使其对子类可见。实例变量也有默认值,如数值型变量的默认值是0,布尔型的默认值是false,引用类型的默认值是null。 3、Java 局部变量 ...

    Java 变量类型总结.pdf

    为了封装,通常将实例变量设为私有,并提供公共的getter和setter方法来访问和修改。 3. Java 局部变量 局部变量只能在方法、构造器或代码块内部声明,不能使用访问修饰符。它们在相关的方法、构造器或代码块执行时...

    JAVA 内存视图与封装

    2. **静态变量与实例变量**:在Java中,变量可以分为静态变量(类变量)和实例变量(对象变量)。静态变量在内存中只有一个副本,被该类的所有对象共享;而实例变量则是每个对象独立拥有的,存储在堆空间中。例如,...

    View类变量的访问

    6. **单例模式**:如果只有一个全局的`View`实例,可以使用单例模式来确保其他类总是访问到同一个`View`实例,从而间接访问变量。 在实际编程中,选择哪种方式取决于具体的需求和设计原则。总的来说,应尽量避免...

    Java中的成员变量

    可以通过对象名来访问实例变量,如`sd1.i`或`sd2.i`。此外,可以使用`this`关键字来引用当前对象的实例变量,虽然在大多数情况下,这并不是必需的。 2. 静态变量(类变量) 静态变量由static关键字修饰,它们属于类...

    Java 程序在类中显示封装.docx

    在 Java 中,封装是通过将类的实例变量声明为私有来实现的,这意味着它们只能在类内部访问。为了允许外部访问实例变量,定义了称为 getter 和 setter 的公共方法,它们分别用于检索和修改实例变量的值。通过使用 ...

    C#应用程序开发-类的数据成员.pptx

    静态变量名`,而访问实例变量成员的语法是 `实例名.实例变量名`。 类的成员变量在实际编程中扮演着重要角色,它们帮助我们封装和管理数据。例如,在`Person`类中,`name`和`age`字段分别表示人的姓名和年龄,而`num...

    课程设计的封装部分截图

    通过使用访问修饰符(如Java中的`private`),我们可以限制对变量的直接访问,只允许通过公共方法来操作这些数据。 2. **公共接口**:为了与对象进行交互,我们需要提供公共方法,这些方法构成对象的接口。这些方法...

Global site tag (gtag.js) - Google Analytics