美文网首页
JavaScript封装 继承 多态0711

JavaScript封装 继承 多态0711

作者: 煤球快到碗里来 | 来源:发表于2019-07-11 21:19 被阅读0次

    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 多态在编程语言中的体现
      父类型变量保存子类型对象, 父类型变量当前保存的对象不同, 产生的结果也不同

    相关文章

      网友评论

          本文标题:JavaScript封装 继承 多态0711

          本文链接:https://www.haomeiwen.com/subject/iqujkctx.html