Day 06 | Dart基本介绍 - private & static

在昨天的文章中,讲到了类别基础用法包含了「宣告」、「建构子」及「实体化」,今天会继续说明Dart class中的其他语法。

私有变数、getter、setter

如果有学习过Java之类的物件导向程序语言,应该都有听过封装(Encapsulation)这个概念,如果要用一句话解释封装大概就是:「朕给你的,才是你的﹐朕不给﹐你不能抢。」

封装基本上就是要确保我们内部的变数或者方法不能被外部(其他人)随意的调用,在其他语言都会利用 private protected public 等语法来决定哪些东西可以给用。

但 Dart 没有这些东西。基本上没有特别写都是公开的,大家都可以呼叫及存取。那要怎麽实作私有变数/方法呢?

class Person {
	String _age
	Person(this._age);
}

就只要以 _做为命名的开头就好,就是这麽简单。

如果是使用DartPad的读者,应该会发现即使加了_外部依然存取的到,为什麽?因为Dart private的scope是在package而不是class,简单来说就是如果是在这只档案依然存取的到。

当我们把 Person 移到另外一只档案後就会发现我在main里面的 instance 无法存取到 _name_age

https://ithelp.ithome.com.tw/upload/images/20210919/20112906B0E6QtUPFz.png

那我们要如何取得私有变数呢?以及要如何更改私有变数?
基本上都是利用一个function包装起来例如:

String getName() => _name; 
// 上面是简写的arrow function形式,相等於
String getName(){
	return _name;
}

那要如何更改私有变数呢?

void setName(String x) {
    _name = x;
  }

操作起来就会像是这样

todd.getName() // todd
todd.setName('toddd')
todd.getName() // toddd

也许有人会问如果我将一个变数改成私有变数然後我宣告了getter及setter让外部可以读取及更改它,那跟之前公开的状态有什麽两样?
我个人认为是这样的写法是可以让变数的存取或更改都必须要经过一个Function才能进行动作,所以我们可以将每个setter/getter多了一层中间的处理。

而Dart另外提供了方便的语法糖 setget来进行getter及setter的宣告:

String get getName => _name;
set setName(String x) => _name = x;

看起来只是多加一个关键字而已那到底差在哪里?主要差异会是在调用时的差异:

todd.getName //todd
todd.setName = 'toddd';
todd.getName // toddd

主要就是我们在调用 getter 时不是call function的形式,而是比较像是一般存取属性时的用法了。而setter也是我们将要set的数值直接放在等号右边。

但另外要注意的是使用 set 时要注意一定要一个参数不能多也不能少,我觉得这个功能相当等於override掉 = 的功能让我们在对某些变数做 = 时有抽象的空间。

那到底要直接用Dart提供的setget 还是用function形式呢?我觉得就是看需求及个人习惯了。

Static

所谓的静态方法/变数意味着我们不需实体化出一个物件我们就能调用了。

宣告起来也很简单就是在前面加上static即可:

static const type = 'humen';
static void hello() {
    print('hello');
  }

而在调用时就会是这样:

Person.hello(); 
Person.type 

我们就不是从 todd 来调用而是直接从类别 Person 进行调用,那这种静态方法或变数会用在哪里呢?最常见大概在共用样式时会用到,我们可能有字体颜色、大小、间距等等众多数值要管理,总不能设一堆全域变数放这吧?为了方便管理大概就是会建立一个class然後用静态变数将这些样式存起来,那之後所有的样式的源头都会是这个class我要更改或查看时都会知道要去哪只档案看了。而且使用class也比较不怕全域变数污染的问题。


今天的程序码也有放到github上:
https://github.com/zxc469469/dart-playground/tree/Day06/private-and-static

今天开始介绍了许多跟OOP切身相关的语法,但有可能会因为我对OOP的了解不够深入而导致我少讲或讲错了什麽,也欢迎各位读者在下面留言纠正及讨论。

下一篇文章会继续讲解class相关的语法:extends、abstract、mixin。



<<:  Leetcode 207. Course Schedule | 含C++笔记

>>:  .NET Core第19天_SelectTagHelper的使用

26. 如何淘汰万年遗毒的code

前言 这篇文章适合给那些要处理Legacy System(旧系统)的朋友们看,如果你们团队有系统的...

30天零负担轻松学会制作APP介面及设计【DAY 21】

大家好,我是YIYI,今天我要来制做设定页面。 从哪里可以进入设定页面呢? 点击LIST的设定~如下...

EP29 - 秽土转生~到了 AWS 也要能够备份~

在 EP13 - 灾难演练,重建你的 VPC, 我们在重建 VPC 之前, 有带着大家怎麽进行单次备...

Day 26 阿里云上运行Kubernetes 2 - ACK

接续昨天,我们建立完集群,也连上集群了来创立ngin服务吧 我们先查看一下丛集讯息 查看集群 kub...

30天零负担轻松学会制作APP介面及设计【DAY 25】

大家好,我是YIYI,今天我要来展示过去24天来努力的结晶了。 影片介绍 一开始会进入写着SECRE...