JavaScript封装 继承 多态0711

JavaScript封装 继承 多态

1.封装(和java,c++一样)

1.1 首先了解一下什么是对象的私有变量和函数
  • 默认情况下对象中的属性和方法都是公有的, 只要拿到对象就能操作对象的属性和方法,外界不能直接访问的变量和函数就是私有变量和是有函数,构造函数的本质也是一个函数, 所以也会开启一个新的作用域, 所以在构造函数中定义的变量和函数就是私有函数
1.2 什么是封装
  • 封装性就是隐藏实现细节,仅对外公开接口
1.3 为什么要封装
  • 不封装的缺点:当一个类把自己的成员变量暴露给外部的时候,那么该类就失去对属性的管理权,别人可以任意的修改你的属性
  • 封装就是将数据隐藏起来,只能用此类的方法才可以读取或者设置数据,不可被外部任意修改. 封装是面向对象设计本质(将变化隔离)。这样降低了数据被误用的可能 (提高安全性和灵活性)
1.4 代码说明
  • function Person() {
        this.name = "lnj";
        // this.age = 34;
        let age = 34;
        this.setAge = function (myAge) {  //封装
            if(myAge >= 0){
                age = myAge;
            }
        }
        this.getAge = function () { //封装
            return age;
        }
        this.say = function () {
            console.log("hello world");
        }
    }
    let obj = new Person();
    // 结论: 默认情况下对象的属性和方法都是公开的, 只要拿到对象就可以操作对象的属性和方法
    // console.log(obj.name);
    // obj.age = -3;
    // console.log(obj.age);
    // obj.say();
    // console.log(age);
    //封装后就不可任意修改
    obj.setAge(-3);
    console.log(obj.getAge());
    
1.5 私有属性注意点
  • 针对以上代码,我们看如下操作的区别

  • let obj = new Person();
    // 1.操作的是私有属性(局部变量)
    obj.setAge(-3);
    console.log(obj.getAge());
    /*
    // 注意点:
    // 在给一个对象不存在的属性设置值的时候, 不会去原型对象中查找, 如果当前对象没有就会给当前对象新增一个不存在的属性
    // 由于私有属性的本质就是一个局部变量, 并不是真正的属性, 所以如果通过 对象.xxx的方式是找不到私有属性的, 所以会给当前对象新增一个不存在的属性
     */
     // 2.操作的是公有属性
     obj.age = -3;
     console.log(obj.age);  //因此会返回-3 ,而不是34
    
1.6 JavaScript 属性方法分类
  • 静态属性/静态方法

    • 通过构造函数访问的属性, 我们就称之为静态属性

    • 通过构造函数调用的方法, 我们就称之为静态方法

    • function Person() {
           this.name = "lnj";
           this.say = function () {
               console.log("hello world");
           }
      }
       // 构造函数也是一个"对象", 所以我们也可以给构造函数动态添加属性和方法
       Person.num = 666;
       Person.run = function () {
           console.log("run");
       }
       console.log(Person.num);
       Person.run();
      
  • 实例属性/实例方法

    • 通过实例对象访问的属性, 我们就称之为实例属性
    • 通过实例对象调用的方法, 我们就称之为实例方法

2.继承

继承方式一 : 借用原型链实现继承
  • 直接将子类的原型对象修改为父类对象, 这样就能使用原型链上的属性和方法

  •  function Person() {
         this.name = null;
         this.age = 0;
         this.say = function () {
             console.log(this.name, this.age);
         }
     }
    // 由于是直接将子类原型对象修改为了父类对象
    // 所以继承的属性值很难自定义,当父类的值需要传进去时,子类对象不能满足这个功能
     function Student() {
         
         this.score = 0;
         this.study = function () {
             console.log("day day up");
         }
     }
     Student.prototype = new Person();
     Student.prototype.constructor = Student;
     var stu1 = new Student(99);
     console.log(stu.name, stu.age, stu.gender, stu.score);
    
继承方式二 : 借用构造函数实现继承
  • 在子类中调用父类构造函数, 并且将父类构造函数的this修改为子类对象

  •  // 父类
    function Person(name, age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    // 借用构造函数只是调用了父类的构造函数, 借用了构造函数中的代码
    // 相当于动态的给子类添加了许多属性, 但是并没有修改子类的原型
    // 所以子类无法继承父类定义在prototype的方法和属性
    Person.prototype.say = function () {
        console.log(this.name, this.age, this.gender);
    }
    // 子类
    function Student(score, name, age, gender) {
        Person.call(this, name, age, gender);
        this.score = score;
    }
    
    var stu1 = new Student(99, "lnj", 33, "male");
    var stu2 = new Student(66, "zq", 18, "female");
    console.log(stu1.name, stu1.age, stu1.gender, stu1.score);
    console.log(stu2.name, stu2.age, stu2.gender, stu2.score);
    stu1.say(); // 报错
    stu2.say(); // 报错
    
继承方式三 : 借用构造函数+借用原型链组合继承
  • 通过借用构造函数实现属性继承

  • 通过借用原型链实现方法继承

  • // 父类
    function Person(name, age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    Person.prototype.say = function () {
        console.log(this.name, this.age, this.gender);
    }
    // 子类
    function Student(score, name, age, gender) {
        Person.call(this, name, age, gender);
        this.score = score;
    }
    Student.prototype = Person.prototype;
    Student.prototype.constructor = Student;
    // 由于子类的原型指向了父类的原型, 所以操作的都是同一个原型对象
    // 给子类的原型新增方法或者属性, 父类也会受到影响
    Student.prototype.study = function () {
        console.log("好好学习天天向上");
    };
    Student.prototype.type = "学生";
    
    var stu = new Student(99, "lnj", 33, "male");
    stu.say();
    stu.study();
    console.log(stu.type);
    
    var p = new Person("zq", 18, "female");
    p.say();
    p.study();
    console.log(p.type);
    
继承方式四 : 专业写法
  •  // 父类
    function Person(name, age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    Person.prototype.say = function () {
        console.log(this.name, this.age, this.gender);
    }
    // 子类
    function Student(score, name, age, gender) {
        Person.call(this, name, age, gender);
        this.score = score;
    }
    Student.prototype = new Person();  //区别就在这
    Student.prototype.constructor = Student;
    // 由于子类的原型指向一个全新的对象
    // 所以给子类的原型新增方法或者属性, 父类不会受到影响
    Student.prototype.study = function () {
        console.log("好好学习天天向上");
    };
    Student.prototype.type = "学生";
    
    var stu = new Student(99, "lnj", 33, "male");
    stu.say();
    stu.study();
    console.log(stu.type);
    
    var p = new Person("zq", 18, "female");
    p.say();
    p.study(); // 报错
    console.log(p.type); // 报错
    

3.多态

  • 3.1 什么是强类型语言:
    一般编译型语言都是强类型语言,
    强类型语言,要求变量的使用要严格符合定义
    例如定义 int num; 那么num中将来就只能够存储整型数据
  • 3.2 什么是弱类型语言:
    一般解释型语言都是弱类型语言,
    弱类型语言, 不会要求变量的使用要严格符合定义
    例如定义 let num; num中既可以存储整型, 也可以存储布尔类型等
  • 3.3 由于js语言是弱类型的语言, 所以我们==不用关注多态==
  • 3.4 多态在编程语言中的体现
    父类型变量保存子类型对象, 父类型变量当前保存的对象不同, 产生的结果也不同
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 学过java或者c#之类语言的同学,应该会对js的继承感到很困惑--不要问我怎么知道的,js的继承主要是基于原型(...
    木丿灬易阅读 254评论 0 1
  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,443评论 0 13
  • 1、原型、原型链 1.1 原型的定义:原型是function对象的一个属性,原型定义了构造函数制造出的对...
    MrLsss阅读 249评论 0 1
  • 将Student构造函数的原型对象改为Person构造函数的原型对象注意点: 要想使用Person原型对象中的属性...
    仰望_IT阅读 208评论 0 1
  • JavaScript之父:Brendan Eich 。 -基本语法:借鉴了C语言和Java语言。-数据结构:借鉴了...
    饥人谷_kule阅读 576评论 0 0