首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

考虑到对象封装,getter应该返回一个不可变的属性吗?

答案:

根据您的问答内容,我将提供一个完善的答案:

问题:

考虑到对象的封装, getter 方法应该返回一个不可变的属性吗?

答案:

这个问题没有绝对的正确答案,但在很多情况下,答案是不,getter 方法应该返回一个不可变的属性。

以下是为什么这个答案的正确性:

  1. 封装: Getter 方法是用于访问对象内部属性的一种方法。如果属性是可变的(即它们可以被修改),那么在 getter 方法内修改该属性可能导致对象的状态丢失,因为每次访问同一属性时会获取到不同的值。因此,使用 getter 方法访问一个可变的属性会导致不稳定性。
  2. 不可变性: 为了实现封装,属性应该具有不可变性。这将限制访问属性的方式来创建一个对象的公共接口。使用不可变的属性可以确保您和其他开发人员能够在不影响整体系统的情况下对属性进行扩展或更改。
  3. 安全性: 不可变性有助于防止潜在的安全性问题。如果可变的属性公开为 getter 方法并暴露给外部调用,那么恶意用户可能会通过此方法更改对象的内部状态并损害对象本身。相反,使用不可变的属性可确保数据完整性以及安全性。
  4. 良好的编程实践: 将属性设计为不可变是常见和受支持的编程实践。许多编程语言库和框架(如 React、Vue 和 Angular)会要求您使用不可变的属性来实现对象的封装,以提高代码的可维护和健壮性。

应用场景:

在许多情况下,您希望将属性设计为不可变的,例如创建一个具有计算属性的对象、遵循函数式编程范式或使用其他需要稳定和可预测性的设计模式。以下是一些常见示例:

  • 对象状态管理:一个状态值可能需要依赖于其他多个输入值来计算。将属性设计为只读属性可以确保状态的完整性。
  • 单一职责原则:避免将一个类具有过多的职责,每个类都应该只负责定义它的功能。通过将部分功能封装到类的内部属性中,可以有效地控制外部访问权限,从而提高程序的性能和可靠性。
  • 安全性和访问控制:通过在 getter 方法中返回不可变的属性,您可以防止外部或第三方代码直接访问原始属性,保证数据的私密性和安全性。
代码语言:txt
复制
这里是一个不可变的属性的 PHP 示例:

```php

class User {

代码语言:txt
复制
private $firstName; // 字符串私有属性
代码语言:txt
复制
private $lastName; // 字符串私有属性
代码语言:txt
复制
private $email; // 字符串私有属性
代码语言:txt
复制
public function getFirstName() {
代码语言:txt
复制
    return $this->firstName; // 获取到的 firstName 是一个只读属性,无法直接在 getter 方法内修改值
代码语言:txt
复制
}
代码语言:txt
复制
public function setFirstName($firstName) { // 只能通过 setter 方法修改 firstName 的值
代码语言:txt
复制
    $this->firstName = $firstName;
代码语言:txt
复制
}
代码语言:txt
复制
public function getEmail() {
代码语言:txt
复制
    return $this->email; // 获取到的 email 是一个只读属性,无法直接在 getter 方法内修改值
代码语言:txt
复制
}
代码语言:txt
复制
public function setEmail($email) { // 只能通过 setter 方法修改 email 的值
代码语言:txt
复制
    $this->email = $email;
代码语言:txt
复制
}

}

代码语言:txt
复制

推荐的腾讯云相关产品和产品介绍链接地址:

由于答案已经包含了一些与腾讯云相关的建议,以下是在推荐产品链接地址中涉及的通用云计算产品:

  • 腾讯云 TKE
  • 腾讯云 CVM(计算优化实例)
  • 腾讯云 COS
  • 腾讯云 RDS(关系型数据库)
  • 腾讯云 SSL证书
  • 腾讯云 CDN(内容分发网络)
  • 腾讯云 AI(腾讯云 NLP )
  • 腾讯云 CMS
  • 腾讯云云数据库 SQL Server
  • 腾讯云 COS 对象存储
  • 腾讯云消息队列 Queue
  • 腾讯云对象存储 COS
  • 腾讯云数据库 MySQL
  • 腾讯云全球加速 GCDN
  • 腾讯云函数计算 Flutter

希望这个详尽全面的答案对你有所帮助。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Java复习2-对象与类

一个class属性应该只能自己修改,其他class都只是与本class沟通,而不应该有能力修改。比较常见一个问题是Date属性。...按照封装要求,这样做法是不合适。因为其他class可以获取Date对象,Date对象可变。那么,就有可能会产生日期被修改可能。...如果项目有引入Findbugs扫描,这个class肯定会被扫描出来,不应该返回一个可变对象。那么,怎么做才可以避免这个问题?我们确实需要暴露Date啊。 答案是暴露一个可变对象。...LocalDate就像String一样,没有提供任何可以改变内部属性方法,所有的修改之类方法都将会创建一个对象。这样,修改操作将不会影响原来class。...这也上开头讲述封装不应返回一个可变变量原因。任何拿到这个可变变量地址方法都可以直接修改变量里属性。那方法2有什么不同? ?

68540

iOS字典转模、xib使用、自定义视图

) 1、只读指针属性分析(指向关系不可变,指向对象内容可变) 不可变属性值,若存储是指针,则该属性对应对象成员是可变 只读指针属性地址值不可变,意味指针和指向对象关系不可变,但被指向对象内容是可变...,让编译器主动推动对象实际类型,以避免使用ID,造成开发中不必要麻烦 1.instancetype 只能使用于返回值类型,不能像id一样用于参数类型;但instancetype比id多一个好处是:...属性不能使用New 开头进行命名 1.6 @synthesize用法 ---- @synthesize 中可以定义 与变量名不相同getter和setter命名,籍此来保护变量不会被恰当访问...和setter命名,籍此来保护变量不会被恰当访问 /** 懒加载模型图片对象属性 */ - (UIImage *)image{ if (nil == _image) {//...2)使用模型修改数据、读取数据均采用对象属性,提高编写效率 2.1 字典转模型实现步骤 1)字典转模型过程,通常被封装在模型内部 2)模型应该提供一个“带有NSDictionary类型”参数构造方法

83410

iOS_理解“属性”(property)这一概念

=XXX:指定“获取方法”方法名 setter=XXX:指定“设置方法”方法名 四、灵魂拷问 一、属性概念 ​ “属性”(property)是Objective-C一项特性,用于封装对象数据。...NSString*时,经常使用此特性来保护其封装性,因为传递给setter方法新值,有时候可能是一个指向NSMutableString类实例,若此时拷贝字符串,那么设置完属性后,字符串值就可能会在对象不知情情况下遭人更改...Runtime维护了一个全局hash(哈希)表:key为对象内存地址,value为可变数组可以存放n个weak对象指针地址。...__unsafe_unretained:该引用不对对象保持强引用,并在对象被释放后不会置为nil, 从而成为一个野指针,所以是unsafe __autorelease:用于表示通过引用(id *)传递并在返回时自动释放参数...因为xib或storyboard对该控件已经有一个强引用了,而拖出来属性应该跟这个控件保持相同生命周期,所以应该用weak修饰。 ​

55720

学 Guava 发现:不可变特性与防御性编程

一、面试常谈:String 类与不可变特性 问:String 类是可变? 答:emm……由于String类底层是 final 关键字修饰,因此它是不可变。...除了构造新 Date 对象,还有深克隆方式,但是此处推荐使用克隆。至于为什么?由于篇幅有限,大家可自行百度! 那么,这样就实现了 Period 类不可变了吗? 并没有!...2、Arrays.asList 返回仅可查看“视图” Arrays.asList() 返回一个ArrayList内部类,没有add()、remove()、无法改变长度等,这样设计初衷是什么?...为什么直接返回可变 ArrayList(new ArrayList())? 和我们刚刚重写 getter 方法类似,用于保证对象安全不可改变特性!...举个例子,就是你有一个数组,怎么设计一个方法:保证既可以遍历,又不能修改呢? 返回一个继承了List接口轻量级“视图”不失为一个设计方式。而直接返回数组则是不安全选择。

51240

Getter & Setter:使用还是废弃

考虑下面的例子 我们通常都认为以上是糟糕代码风格,因为它破坏了封装性。替代方法是: 有人认为这样封装属性。这真的实现了封装? 实际上,Getter/Setter和封装性没有任何关系。...以这种方式使用Getter和Setter通常破坏了封装性。 一个真正完整封装类是没有setter方法,而且最好也没有getter方法。...类应该负责使用自身数据计算并返回结果,而不是从某个类获得数据并计算这些数据。...增加一个不必要getter会暴露内部结构,这也增加了代码耦合机会。避免方案是在每次增加存取方法时候,我们应该分析是否可以通过封装行为来替代存取方法。...但是,为每一个属性都创建getter和setter方法确实有些极端。而且这也要根据具体情况来定,有些时候你仅仅希望有一个单纯数据对象而已。应该为真正需要属性添加存取方法。

1.2K60

iOS @property探究(一): 基础详解你要知道@property都在这里

setter方法是有一个参数返回值方法,getter方法是没有参数且有一个返回方法,返回值类型与属性声明类型一致。...即getter方法,它不接受任何参数,并且返回一个值。如果将这个方法转换成一个属性,就可以用readonly关键字标记它。...getter方法应当是幂等(idempotent)(如果一个getter方法被调用两次,那么第二次调用时返回结果应该和第一调用时返回结果相同)。...,因为Foundation框架提供这些类都实现了NSCopying协议,使用copy方法返回都是不可变对象,如果使用copy修饰符在对可变对象赋值时则会获取一个可变对象,接下来如果对这个对象进行可变对象操作则会产生异常...返回值为可变对象

1.6K90

iOS理论基础(二)

属性” (property)作为 Objective-C 一项特性,主要作用就在于封装对象数据。 ivar、getter、setter 是如何生成并添加到这个类中?...为这种属性设置新值时,设置方法既不保留新值,也释放旧值。此特质同 assign 类似, 然而在属性所指对象遭到摧毁时,属性值也会清空(nil out)。...若是自己定义存取方法,那么就应该遵从与属性特质相符原子性。...a.因为父类指针可以指向子类对象,使用 copy 目的是为了让本对象属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个可变副本....b.如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性. aa.在非集合类对象中:对 immutable 对象进行 copy 操作,是指针复制

39310

Kotlin实战【二】Kotlin基本要素

作为一个静态类型语言,Kotlin不是要求每个表达式都应该在编译期具有类型?事实上,每个变量和表达式都有返回类型。...***使用不可变引用、不可变对象及无无副作用函数让你代码更接近函数式编程风格***。 定义了val变量代码块执行期间,val变量只能进行唯一一次初始化。...如果你想在变量里面存储一个匹配类型值,你必须转换或者协变这个值到正确类型。...name: String, //只读属性:自动生成一个域和简单getter var isMarried: Boolean //可写属性一个域,getter和setter ) 接下来我们看下如何使用上面定义好...>**小贴士:** > - 你可以在Java定义类中使用Kotlin属性语法。在Java类中getter可以在Kotlin中val属性获取,getter/setter可以通过var属性获取。

1.1K20

小米 二面

你好,我是田哥 上周,一位朋友去小米面经,很多都是开放性问题,真的八股文好像也顶用了。 1、Java 编程语言它有什么样特点?...面向对象: Java 是一种支持面向对象编程范式语言,提供类、对象、继承、封装、多态等面向对象特性。...异常信息封装: 创建一个统一异常信息结构,包括异常类型、错误代码、错误消息等,并封装异常信息以便返回给前端。 返回异常信息给前端: 在发生异常时,通过适当方式将异常信息返回给前端。...类型异常,封装异常信息到 ErrorResponse 对象,并返回给前端。...无参构造函数: 提供一个无参构造函数,以便 JSON 转换库能够实例化对象属性访问修饰符: 使用私有字段并通过公共 getter 和 setter 方法来访问属性,符合封装概念。

11310

面经之《招聘一个靠谱iOS》import CYLBlockExecutor.himport CYLBlockExecutor.himport CYLNSObject+RunAtDeallo

属性类型为 NSString 时,经常用此特质来保护其封装性,因为传递给设置方法新值有可能指向一个 NSMutableString 类实例。...所以,这时就要拷贝一份“不可变” (immutable)字符串,确保对象字符串值不会无意间变动。只要实现属性所用对象是“可变” (mutable),就应该在设置新属性值时拷贝一份。...因为父类指针可以指向子类对象,使用 copy 目的是为了让本对象属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个可变副本....如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性. copy 此特质所表达所属关系与 strong 类似。...所以,这时就要拷贝一份“不可变” (immutable)字符串,确保对象字符串值不会无意间变动。只要实现属性所用对象是“可变” (mutable),就应该在设置新属性值时拷贝一份。

980100

一文讲透 Java 中 POJO, JavaBeans, DTO 和 VO 区别

private,并使用 getter/setter 方法访问属性。...VO 应该始终覆盖 equals() 和 hashCode() 方法。VO 通常封装小型对象,例如数字、日期、字符串等等。它们遵循值语义,即它们直接更改对象值并传递副本而不是引用。...将值对象设置为不可变一个好习惯。值更改只能通过创建一个对象而不是更新旧对象本身来发生。这有助于理解两个创建相等对象隐式契约应该保持相等。...DTO 通常包含一些与领域模型无关属性,用于传递数据而不是表示实体。 VO(Value Object,值对象):VO 是一种用于表示领域模型中对象,它通常是不可变,一旦创建就不会改变。...VO 一般包含一些属性,用于表示某个特定值,例如货币、日期、地址等等。VO 可以用于在应用程序不同层之间传递值,但一般包含与业务逻辑相关方法。

1.1K10

DDD话语评价之二:“值对象”是DDD创新(全文)

. , 2020 ****** Seriously Good Software中译本起名《你真的会写代码》,已于2021年7月出版。此处非广告。我未和出版社联系过,也欣赏中译本乱改名行为。...8.2.8.4 本书关于“值对象观点 对象本就应该可变 “面向对象”就是把某些数据和经常操纵这些数据行为封装在一起变成类,以此作为系统基本构造块,如图8-72。...像下面这些经常看到有规律一一对应“面向对象封装: *每个属性刚好对应一对getter/setter操作(现在Property语法就更省事了),然后就说封装了,面向对象了。...应该用哪些属性值来计算,怎么计算,会修改哪些属性值,怎么修改,这些行为规则封装在类中,可以通过状态机描述。状态表征了对象表现出相同行为规则属性值组合,把行为和数据连接起来。...如果没有做到这样封装,或者认为没有必要做到这样封装,那面向对象意义就不大了。如果一味强求属性值或状态“不可变”,那完全可以采用另外一种思考范式嘛。

47420

面向对象思想,谈面试过程?

4 个重要概念: 成员变量(有时叫做域,有时叫做字段,有时叫做属性)name; 成员变量访问器(有时叫做 getter/setter)getName() 和 setName(); 构造方法(有时叫做构造器...公有方法是类调用者和维护者最关心方法,应该在比较靠前位置展示;保护方法虽然只有子类关心,也可能是“模板设计模式”下核心方法,所以也要靠前;私有方法只对本类可见,一般不需要特别关心,所以往后放;getter...在初学 Java 编程时候,我经常产生一个疑惑:为什么不使用 public 修饰成员变量呢?这样做不是比 getter/setter 更方便? 我最先想到答案是这样: ?...然后再把这个引用通过 = 操作符赋值给左侧对象变量 qiuqiu,赋值后,qiuqiu就不再是对象变量了,应该称为对象引用。 ? 看完老王解释,你会不会情不自禁地“哦,原来如此啊!”...当 getter 需要返回一个可变对象引用时,应该先进行克隆(clone)。以下展示了一个非常简单克隆方案。

47920

OOP三大特性之封装

但这一切前提:每个对象要构建好,即封装要做好。就像每个细胞都有细胞壁将其与外界隔离,形成一个完整个体。 Kay强调对象之间只能通过消息通信。...即便我们把对象理解成数据+函数,数据、函数也不是对等: 函数是接口 接口是稳定 数据是内部实现 实现是易变应该隐藏 很多人开发习惯:写一个类,写其一堆字段,然后生成一堆getter、setter...关于setter: 大概率是你用错名字,应该一个表达意图名字 setter通常意味着修改,这是推荐 可变对象会带来很多问题,后续再深入讨论。所以,设计中更好做法是设计不变类。...设计角度,必须谨慎自省:这个方法有必要暴露? 其实可仅暴露一个方法: 外部调用代码也会简化: 尽可能减少接口暴露,该原则适于类设计、系统设计。...其实如果用另一个名字“最小知识原则”可能更容易理解一些,这个也算是程序员“黑话”吧。 虽然接触OOP已经很久了,不过写程序时,大多数人还是习惯“一个对象一张表”,也没有太多考虑封装

47920

哪些代码设计看似是面向对象,实际是面向过程

实际上,这样做法我是非常推荐。它违反了面向对象编程封装特性,相当于将面向对象编程风格退化成了面向过程编程风格。我通过下面这个例子来给你解释一下这句话。...而面向对象封装定义是:通过访问权限控制,隐藏内部数据,外部仅能通过类提供有限接口访问、修改内部数据。所以,暴露不应该暴露 setter 方法,明显违反了面向对象封装特性。...但是,对于 items 属性就不一样了,这是因为 items 属性 getter 方法,返回一个 List集合容器。...正确做法应该是,在 ShoppingCart 类中定义一个 clear() 方法,将清空购物车业务逻辑封装在里面,透明地给调用者使用。...我们可以通过 Java 提供Collections.unmodifiableList() 方法,让 getter 方法返回一个不可被修改UnmodifiableList 集合容器,而这个容器类重写了

74661

Effective Java(第三版)——条目十六:在公共类中使用访问方法而不是公共属性

class Point { public double x; public double y; } 由于这些类数据属性可以直接被访问,因此这些类不提供封装好处(条目 15)。...坚持面向对象程序员觉得这样类是厌恶应该被具有私有属性和公共访问方法类(getter)所取代,而对于可变类来说,它们应该被替换为setter设值方法: // Encapsulation of data...如条目 67所述,暴露Dimension内部结构决定是一个严重性能问题,这个问题在今天仍然存在。 虽然公共类直接暴露属性并不是一个好主意,但是如果属性是不可变,那么危害就不那么大了。...this.hour = hour; this.minute = minute; } ... // Remainder omitted } 总之,公共类不应该暴露可变属性...公共累暴露不可变属性危害虽然仍然存在问题,但其危害较小。 然而,有时需要包级私有或私有内部类来暴露属性,无论此类是否是可变

82110

Objective-c 知识总结 -- @property

_age); } @end 那个警告明显是说,我自动合成实例变量是__age,而不是 _age,所以你应该定义一个 __age 实例变量才对,不然我就警告你; 其实这里是间接地证明了,如果你自己定义了相应带下划线实例变量...- (NSObject *)obj{ return _obj ; } copy 拷贝对象(相当于创建了新实例对象),是不可变副本; copy 只能用于遵守了 NSCopying..., copy ) NSMutableArray *mArray; 这种声明真的是自己挖坑了;你要可变对象,但是一 copy 就是不可变对象了,运行时会出问题; 4..../** * 移除实例对象所有关联值 * * @param object 实例对象 * * @note 这个方法核心目的是为了方便让实例对象所有关联值还原到初始状态;你不应该使用此方法来对一个关联值进行还原...不过这么做编译器会报错,但是只要新建一个该类类别,在类别.h文件中写上原始类该方法声明,类别.m文件中什么也写,就可以正常调用私有方法了。这就是传说中私有方法前向引用。

1.3K31

iOS今日头条第3轮面试回忆

一、自我介绍 简单介绍一下你自己吧 解析:简单介绍下自己名字,教育背景,现在工作,做过项目 二、自我介绍衍生口头问题 讲讲下你在你项目中做过优化或者技术难点 解析:介绍了自己封装一个集picker...如果你自己写 getter/setter,那 atomic/nonatomic/retain/assign/copy 这些关键字只起提示作用,写写都一样。...分配内存时候?还是初始化时候? 成员变量存储在堆中(当前对象对应堆得存储空间中) ,不会被系统自动释放,只能有程序员手动释放。...在strong修饰下,可变字符串赋值给myString后,两个对象都指向了相同地址。而copy修饰下,myString和mutableString指向了不同地址。...当修饰不可变类型属性时,如NSArray、NSDictionary、NSString,用copy。 4.7 题目: 分类中添加实例变量和属性分别会发生什么,编译时就报错,还是什么时候会发生问题?

1.4K20
领券