摘要:要注意的是,如果要重写构造函数,必须要在构造函数的第一行调用父类的构造函数,在而在其他地方,则可以通过或者调用父级的变量或者方法
0x000 概述
es6真正的引入的面相对象的类,以前我们总是通过其他手段来模拟类这种形式,现在终于有了,我有点开心,又有点难过,因为在我看来,js并不是所谓的面相对象的语言,反而更偏向函数式,原型继承是他真正的面目。面相对象不过是人们在思考问题时总结出一套有效的、大家都认同的解决问题的思路。在其他语言、各种领域取得成功之后,又将这种思想带入js中,为的是将已有的经验可以复用到js,从而更有效的解决js中的问题。
的确,面相对象是一个很有用的思考模块,在分解真实世界、大型项目的维护上有很大的好处,但是却缺少了函数式的灵巧。曾经想用完全面向对象的方式写一个redux,却发现无法用这种方式写出compose这种神奇的东西。
或许是我还没能在面相对象和函数式之间取得一种平衡,以取得面相对象和函数式共同的优点。
0x001 类
普通的类
class Person{}
类表达式
// 匿名类 let Person=class{} // 具名类 let Person=class Person{}0x001 初始化类和构造函数
实例化类
可以使用new来调用一个类,从而实例化一个类实例
class Person{} new Person() // Person{}
构造函数
使用new实例化一个类实例之后,将会自动调用该类的构造函数constructor,并且可以传递参数
class Person{ constructor(name, age){ console.log(name, age) } } new Person("jack", 23) // "jack", 23
类变量
类中可以保存一些变量,在类中,可以通过this.variable_name来访问,在类外,可以通过instance_name.variable_name只有类实例可以访问他们,并且每个类实例的变量都是属于每个类实例的。
class Person { constructor(nickname, age){ this.nickname = nickname this.age = age } } console.log(Person.nickname) // undefined console.log(Person.age) // undefined let person=new Person("jack",23) console.log(person.nickname) // "jack" console.log(person.age) // 23 let person2=new Person("maria",11) console.log(person2.nickname) // "maria" console.log(person2.age) // 11
类方法
类方法是定义在类内部的函数,可以在类内部调用:this.function_name(params),也可以在实例上调用:instance_name.function_name(params)
class Person{ constructor(nickname, age){ this.nickname = nickname this.age =age } getNickname(){ return this.nickname } getAge(){ return this.age } summary(){ return `${this.nickname}:${this.age}` } } let person=new Person("jack", 23) console.log(person.getNickname()) // ""jack console.log(person.getAge()) // 23 console.log(person.summary()) // "jack:23"
静态方法
静态方法是可以通过类直接调用的方法,不需要实例化
class Person{ static sayHello(){ console.log("hello") } } Person.sayHello() // "hello"继承
继承就是将父类所有的方法和都继承下来,包括构造函数
class Person{ constructor(nickname, age){ this.nickname = nickname this.age =age } getNickname(){ return this.nickname } getAge(){ return this.age } summary(){ return "this is Person" } } class Male extends Person {} let male=new Male("jack",23) console.log(male.nickname) // "jack" console.log(male.age) // 23 console.log(male.getNickname()) // "jack" console.log(male.getAge()) // 23 console.log(male.summary()) // "this is Person"0x003 重写
有时候我们不希望一个函数的作用和父类一致,比如在上面的栗子中,male.summary()返回this is Person,不符合我们的逾期,我们希望返回this is Male,这个时候就可以用到重写,只要写一个和父类相同名字和函数就行了,甚至参数个数不一致也不影响
class Person{ constructor(nickname, age){ this.nickname = nickname this.age =age } getNickname(){ return this.nickname } getAge(){ return this.age } summary(){ return "this is Person" } } class Male extends Person { summary(){ return "this is Male" } } let male=new Male() console.log(male.summary()) // this is Male0x004 调用超类
有时候我们希望在父类的流程基础上添加一些自己的逻辑,这个时候就可以用到调用超类。要注意的是,如果要重写构造函数,必须要在构造函数的第一行调用父类的构造函数super(...params),在而在其他地方,则可以通过super.variable_name或者super.function_name(params)调用父级的变量或者方法
class Person{ constructor(nickname, age){ this.nickname = nickname this.age =age } getNickname(){ return this.nickname } getAge(){ return this.age } summary(){ return "this is Person" } } class Male extends Person { constructor(nickname, age){ super(nickname, age) this.sex="male" } getSex(){ return this.sex } summary(){ return super.summary()+", and this is Male" } } let male=new Male() console.log(male.sex) // male console.log(male.summary) //this is Person, and this is Male
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/108594.html
重写和隐藏方法 实例方法 子类中的实例方法的签名(名称,加上其参数的数量和类型)和返回类型与超类中的实例方法相同,将覆盖超类的方法。 子类覆盖方法的能力允许类从行为足够接近的超类继承,然后根据需要修改行为,重写方法与它重写的方法具有相同的名称、数量和参数类型,以及返回类型。重写方法还可以返回由被重写方法返回的类型的子类型,此子类型称为协变返回类型。 覆盖方法时,你可能希望使用@Override注解...
摘要:使用抽象基类显示表示接口如果类的作用是定义接口,应该将其明确定义为抽象基类。此外,抽象基类可以作为其他类的唯一基类,混入类则决不能作为唯一的基类,除非这个混入类继承了另一个更具体的混入这种做法非常少见。 《流畅的Python》笔记本篇是面向对象惯用方法的第五篇,我们将继续讨论继承,重点说明两个方面:继承内置类型时的问题以及多重继承。概念比较多,较为枯燥。 1. 继承内置类型 内置类型...
继承 在前面的课程中,你已经多次看到了继承,在Java语言中,类可以从其他类派生,从而从这些类继承字段和方法。 定义:从另一个类派生的类称为子类(也是派生类,扩展类或子类),派生子类的类称为超类(也是基类或父类)。 除了Object没有超类,每个类都有一个且只有一个直接超类(单继承),在没有任何其他显式超类的情况下,每个类都隐式地是Object的子类。 类可以从派生自类的类派生的类派生,依此类推,...
摘要:构造函数创建对象为了能够判断实例与对象的关系,我们就使用构造函数来搞定。像和这样的原生构造函数,在运行时自动出现在执行环境中。 大纲: 一、理解对象 1.1 属性类型 1.2 属性方法 二、创建对象 2.1 简单方式创建 2.2 工厂模式 2.3 构造函数 2.4 原型 三、继承 3.1 原型链 3.2 借用构造函数 3.3 组合继承(原型链+借用构造函数) 3....
摘要:如果需要支持类的动态加载或需要对编译后的字节码文件进行解密操作等,就需要与类加载器打交道了。双亲委派模型,双亲委派模型,约定类加载器的加载机制。任何之类的字节码都无法调用方法,因为该方法只能在类加载的过程中由调用。 jvm系列 垃圾回收基础 JVM的编译策略 GC的三大基础算法 GC的三大高级算法 GC策略的评价指标 JVM信息查看 GC通用日志解读 jvm的card table数据...
阅读 1859·2021-11-23 09:51
阅读 1231·2019-08-30 15:55
阅读 1595·2019-08-30 15:44
阅读 747·2019-08-30 14:11
阅读 1127·2019-08-30 14:10
阅读 890·2019-08-30 13:52
阅读 2616·2019-08-30 12:50
阅读 599·2019-08-29 15:04