资讯专栏INFORMATION COLUMN

面向对象特征之封装-Es6中Class私有和受保护的属性及方法

neuSnail / 2343人阅读

摘要:熟悉面向对象编程的都知道,面向对象编程最重要的原则之一从外部接口划分内部接口。所以,面向对象编程就类似于汽车一样。

熟悉面向对象编程的都知道,面向对象编程最重要的原则之一 - 从外部接口划分内部接口。也就是说,针对某一类事物,我们其实并不是那么在乎其内部究竟是怎样去实现的,只关心怎样使用而已。

为了理解这点,让我们先来看看现实生活中的列子。通常,我们使用的设备非常复杂。但是从外部接口界定内部接口允许使用它们没有什么问题。列如一辆汽车。从外面看主要有:轮子、车身、车顶、方向盘等。

但是,内部...

有许多的细节,但是我们并不用去知道这些细节,也可以很好地开车车。

汽车非常可靠,不是吗?我们可以使用很多年,只有在出现问题时才能使用它 - 进行维修。汽车的可靠性和使用的简单性在于隐藏内部细节。

如果我们从汽车上取下发动机,那么使用它将会复杂得多(安装在哪?),并且危险(它可以电击)。

所以,面向对象编程就类似于汽车一样。

内部和外部接口

在面向对象的编程中,属性和方法可以分为两组:

内部接口-方法和属性,可以从类的其他方法访问,但不能从外部访问

外部接口-方法和属性,也可以从外部访问

如果我们继续与汽车进行类比 - 内部隐藏的部分:发动机、变速器、半轴等 - 是其内部接口。对于对象的运行,内部接口是非常有用的,其细节互相使用。例如,弹性元件连接到减震器。

但是从外面看,汽车被外层车壳保护着,所以没有人可以接触到。细节隐藏且无法访问。我们可以通过外部接口使用它的功能。所以,我们在使用一个对象的时候,并不关心它内部是怎样工作的。

在JavaScript中,有两种类型的对象字段(属性和方法):

公共的:随处都可访问,它们包含外部接口,我们在开发中一直常用的也就是公共的属性和方法了

私有的:仅在类的内部可访问,主要用于内部接口

在许多其他语言中,还存在“受保护”字段:只能从类内部访问和扩展它们。它们对内部接口也很有用。它们在某种意义上比私有更广泛,因为我们通常希望通过继承类来获取和访问它们。

受保护的字段不是在JavaScript语言级别上实现的,但实际上它们非常方便,我们也可以模拟地去实现它们。现在我们用JavaScript来制作一台具有这些类型属性的汽车。

class MBWCar{
    oilAmount = 0; // the amount of oil inside
    constructor(power){
        this.power = power
        alert( `Created a mbw-car, power: ${power}` );
    }
}
// create the mbw car
let mbwCar = new MBWCar(100)

// oil water
mbwCar.oilAmount = 200

从上面的代码可以看出oilAmountpower这两个属性是公共的,我们可以在外部轻易地设置以及获取它们。

让我们将oilAmount属性更改为protected以对其进行更多控制。例如,我们不希望任何人将其设置为零以下。

受保护的属性通常以下划线_为前缀

这不是在语言层面强制去执行,但咱们程序员之间有一个众所周知的惯例,即不应该从外部访问这些属性和方法。

class MBWCar{
    _oilAmount = 0;

    constructor(power){
        this._power = power

    }

    set oilAmount(value){
        if (value < 0) throw new Error("Negative oil");
        this._oilAmount = value
    }

    get oilAmount(){
        return this._oilAmount
    }
}
// create the mbw car
let mbwCar = new MBWCar(100)

// oil water
mbwCar.oilAmount = -10 //Error Negative oil

现在访问受到控制,因此将油量设置为零以下将失败。

那么我们可以把power属性设置为只读属性,这在一些程序开发中也有类似的需要,某些属性只读不可更改其值。

class MBWCar{
    constructor(power){
        this._power = power

    }
    get power(){
        return this._power
    }
}
// create the mbw car
let mbwCar = new MBWCar(100)
alert(`Power is: ${mbwCar.power}W`); // Power is: 100W

mbwCar.power = 25 // Error (no setter)
getter/setter方法
 class Car{
    _oilMount = 0;
    setOilMount(value){
        if(value<0) throw Error("Negative oil")
        this._oilMount = value
    }
    getOilMount() {
        return this._oilMount;
    }
}
let mbw = new Car()
mbw.setOilMount(100);
alert(mbw.getOilMount());

受保护的属性是可以继承的

如果我们继承类MBWCar扩展Car,那么没有什么能阻止我们从新类的方法中访问this._oilMount 或this._power属性。
所以受保护的属性是可以继承的,不像接下来我们所说的私有属性。
私有字段

这是JavaScript后面新增的一个针对类属性的语法。JavaScript引擎不支持,或者部分支持,需要进行polyfilling
在JavaScript的提议中,有一个已完成的标准,为私有属性和方法提供语言级支持。

私有的私有字段与#开头,仅在类的内部可进行访问.

  class Car{
    #oilLiMit = 100;

    #checkOil(value){
        if(value<0) throw Error(`Negative oil`)
        if (value > this.#waterLimit) throw new Error("Too much oil");
    }
}

let car = new Car();

// can"t access privates from outside of the class
car.#checkOil(); // Error
car.#waterLimit = 1000; // Error

class BWMCar extends Car{
    method() {
        alert( this.#oilLiMit ); // Error: can only access from Car
    }
}

私有字段不能够通过this[name]去访问

 class User{
   sayHi(){
       let filedName = "Darkcod"
       alert(`Hello,${this.filedName}`) //Hello,undefined
   }
}

 new User().sayHi()
 

总结:

面向对象编程最重要的原则之一 - 从外部接口划分内部接口,这就涉及到属性和方法的可访问范围度

在面向对象编程中,可通过private、protected、public来对类的属性和方法进行限制,例如你从你父亲那里继承了一些属性,但你父亲其他属性不像被你继承到等。

在JavaScript中,受保护的属性和方法名以_开头,私有的属性和方法名以#开头

面向对象编程的一个较大的好处之一是我们不必理解其内部实现,依然可以很好地去进行编程开发,例如:一个U盘,我们想要将电脑中的某些文件拷贝到它那里进行存储,这时候我们并不关心U盘的内部是这样形成的,我们只知道通过USB口插入即可完成拷贝的工作

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105751.html

相关文章

  • TypeScript快速入门

    摘要:添加了可选的静态类型注意并不是强类型和基于类的面向对象编程。类类型接口示例接口更注重功能的设计,抽象类更注重结构内容的体现模块中引入了模块的概念,在中也支持模块的使用。 一:Typescript简介 维基百科: TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个严格超集,并添加了可选的静态类型和基于类的面向对象编程。C#的首席架构师以及Delp...

    moven_j 评论0 收藏0
  • PHP面试面向对象(1)

    摘要:二面向对象有什么特征面向对象的主要特征有抽象继承封装和多态。析构函数析构函数是在引入的,它的作用与调用时机和构造函数刚好相反,它在对象被销毁时自动执行。 PHP面试专栏正式起更,每周一、三、五更新,提供最好最优质的PHP面试内容。PHP中面向对象常考的知识点有以下7点,我将会从以下几点进行详细介绍说明,帮助你更好的应对PHP面试常考的面向对象相关的知识点和考题。整个面向对象文章的结构涉...

    phodal 评论0 收藏0
  • php学习笔记(三)面向对象高级实践

    摘要:由于静态方法不需要通过对象即可调用,所以伪变量在静态方法中不可用。继承一个抽象类的时候,子类必须定义父类中的所有抽象方法另外,这些方法的访问控制必须和父类中一样。 extends对象继承 PHP中类不允许同时继承多个父类,也就是extends后面只能跟一个父类名称,这个特性被称为PHP的单继承特性 当扩展一个类,子类就会继承父类所有公有的和受保护的方法。除非子类覆盖了父类的方法,被...

    Hancock_Xu 评论0 收藏0
  • Java核心技术笔记 对象与类

    摘要:核心技术卷第章对象与类面向对象程序设计创建标准类库中的类对象如何编写自己的类传统的结构化程序设计首先确定如何操作数据,再决定如何组织数据。当使用构造器时,无法改变所构造的对象类型。 《Java核心技术 卷Ⅰ》 第4章 对象与类 面向对象程序设计 创建标准Java类库中的类对象 如何编写自己的类 OOP 传统的结构化程序设计:首先确定如何操作数据,再决定如何组织数据。 面向对象程序设...

    imtianx 评论0 收藏0
  • TypeScript入门-类

    摘要:可以使用关键字来定义类的静态属性,示例代码如下输出输出抽象类有抽象类的概念,他是供其他类继承的基类,不能直接实例化。抽象类必须包含一些抽象方法,同时也可以包含非抽象的成员。 学习Angular 2 , 《揭秘Angular 2》读书笔记。Angular2 选择 TypeScript 作为其官方最主要的构建语音,这意味着掌握 TypeScript 语音将更有利于高效地开发 Angular...

    longmon 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<