Javascript基于对象三大特性(封装性、继承性、多态性)

Javascript基于对象的三大特征和C++,Java面向对象的三大特征一样,都是封装(encapsulation)、继承(inheritance )和多态(polymorphism )。只不过实现的方式不同,其基本概念是差不多的。其实除三大特征之外,还有一个常见的特征叫做抽象(abstract),这也就是我们在一些书上有时候会看到面向对象四大特征的原因了。
一、封装性
    封装就是把抽象出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法),才能对数据进行操作。
案例:

<html>
  <head>
    <script type="text/javascript">
      function Person(name, agei, sal){
        // 公开
        this.name = name;
        // 私有
        var age = agei;
        var salary = sal;
      }
      var p1 = new Person('zs', 20, 10000);
      window.alert(p1.name + p1.age);
    </script>
  </head>
  <body>
  </body>
</html>

PS:JS封装只有两种状态,一种是公开的,一种是私有的。

通过构造函数添加成员方法和通过原型法添加成员方法的区别
1、通过原型法分配的函数是所有对象共享的.
2、通过原型法分配的属性是独立.(如果你不修改属性,他们是共享)
3、建议,如果我们希望所有的对象使用同一一个函数,最好使用原型法添加函数,这样比较节省内存.

案例:

function Person(){
  this.name="zs";
  var age=20;
  this.abc=function(){
    window.alert("abc");
  }
  function abc2(){
    window.alert("abc");
  }
}
Person.prototype.fun1=function(){
  window.alert(this.name);//ok
  //window.alert(age);//no ok
  //abc2();//no ok
  this.abc();//ok
}
var p1=new Person();
p1.fun1();

特别强调:我们前面学习的通过prototype给所有的对象添加方法,但是这种方式不能去访问类的私有变量和方法。

二、继承性
继承可以解决代码复用,让编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过继承父类中的属性和方法。
JS中实现继承的方式
1、对象冒充
案例:

<html>
  <head>
    <script type="text/javascript">
      function Stu(name, age){
        this.name = name;
        this.age = age;
        this.show = function(){
          window.alert(this.name + " " + this.age);
        }
      }
      function MidStu(name, age) {
        this.stu = Stu;
        // 通过对象冒充来实现继承的
        // 对象冒充的意思就是获取那个类的所有成员,因为js是谁调用那个成员就是谁的,这样MidStu就有了Stu的成员了
        this.stu(name, age);
        this.payFee = function(){
          window.alert("缴费" + money * 0.8);
        }
      }
      function Pupil(name, age) {
        this.stu = Stu;
        // 通过对象冒充来实现继承的
        this.stu(name, age);
        this.payFee = function(){
          window.alert("缴费" + money * 0.5);
        }
      } 

      var midStu = new MidStu("zs", 13);
      midStu.show();
      var pupil = new Pupil("ls", 10);
      pupil.show();
    </script>
  </head>
  <body>
  </body>
</html>

2、通过call或者apply实现
案例:

<html>
<head>
<script type="text/javascript">
  //1. 把子类中共有的属性和方法抽取出,定义一个父类Stu
  function Stu(name,age){
    // window.alert("确实被调用.");
    this.name=name;
    this.age=age;
    this.show=function(){
      window.alert(this.name+"年龄是="+this.age);
    }
  }
  //2.通过对象冒充来继承父类的属性的方法
  function MidStu(name,age){
    //这里这样理解: 通过call修改了Stu构造函数的this指向,
    //让它指向了调用者本身.
    Stu.call(this,name,age);
    //如果用apply实现,则可以
    //Stu.apply(this,[name,age]); //说明传入的参数是 数组方式
    //可以写MidStu自己的方法.
    this.pay=function(fee){
      window.alert("你的学费是"+fee*0.8);
    }
  }
  function Pupil(name,age){
    Stu.call(this,name,age);//当我们创建Pupil对象实例,Stu的构造函数会被执行,当执行后,我们Pupil对象就获取从 Stu封装的属性和方法
    //可以写Pupil自己的方法.
    this.pay=function(fee){
      window.alert("你的学费是"+fee*0.5);
    }
  }
  //测试
  var midstu=new MidStu("zs",15);
  var pupil=new Pupil("ls",12);
  midstu.show();
  midstu.pay(100);
  pupil.show();
  pupil.pay(100);
</script>
</html>

小结:
1、JS对象可以通过对象冒充,实现多重继承
2、Object类是所有Js类的基类

三、多态性
JS的函数重载
这个是多态的基础,在之前的Javascript入门已经说过了,JS函数不支持多态,但是事实上JS函数是无态的,支持任意长度,类型的参数列表。如果同时定义了多个同名函数,则以最后一个函数为准。
案例:

<html>
<head>
<script type="text/javascript">
  //*****************说明js不支持重载*****
  /*function Person(){
    this.test1=function (a,b){
      window.alert('function (a,b)');
    }
    this.test1=function (a){
      window.alert('function (a)');
    }
  }
  var p1=new Person();
  //js中不支持重载.
  //但是这不会报错,js会默认是最后同名一个函数,可以看做是后面的把前面的覆盖了。
  p1.test1("a","b");
  p1.test1("a");*/ 

  //js怎么实现重载.通过判断参数的个数来实现重载
  function Person(){
    this.test1=function (){
      if(arguments.length==1){
        this.show1(arguments[0]);
      }else if(arguments.length==2){
        this.show2(arguments[0],arguments[1]);
      }else if(arguments.length==3){
        this.show3(arguments[0],arguments[1],arguments[2]);
      }
    }
    this.show1=function(a){
      window.alert("show1()被调用"+a);
    }
    this.show2=function(a,b){
      window.alert("show2()被调用"+"--"+a+"--"+b);
    }
    function show3(a,b,c){
      window.alert("show3()被调用");
    }
  }
  var p1=new Person();
  //js中不支持重载.
  p1.test1("a","b");
  p1.test1("a");
</script>
</html>

1、多态基本概念
多态是指一个引用(类型)在不同情况下的多种状态。也可以理解成:多态是指通过指向父类的引用,来调用在不同子类中实现的方法。
案例:

<script type="text/javascript">
  // Master类
  function Master(name){
    this.nam=name;
    //方法[给动物喂食物]
  }
  //原型法添加成员函数
  Master.prototype.feed=function (animal,food){
    window.alert("给"+animal.name+" 喂"+ food.name);
  }
  function Food(name){
    this.name=name;
  }
  //鱼类
  function Fish(name){
    this.food=Food;
    this.food(name);
  }
  //骨头
  function Bone(name){
    this.food=Food;
    this.food(name);
  }
  function Peach(name){
    this.food=Food;
    this.food(name);
  }
  //动物类
  function Animal(name){
    this.name=name;
  }
  //猫猫
  function Cat(name){
    this.animal=Animal;
    this.animal(name);
  }
  //狗狗
  function Dog(name){
    this.animal=Animal;
    this.animal(name);
  }
  //猴子
  function Monkey(name){
    this.animal=Animal;
    this.animal(name);
  }
  var cat=new Cat("猫");
  var fish=new Fish("鱼"); 

  var dog=new Dog("狗");
  var bone=new Bone("骨头"); 

  var monkey=new Monkey("猴");
  var peach=new Peach("桃"); 

  //创建一个主人
  var master=new Master("zs");
  master.feed(dog,bone);
  master.feed(cat,fish);
  master.feed(monkey,peach);
</script>

多态利于代码的维护和扩展,当我们需要使用同一类树上的对象时,只需要传入不同的参数就行了,而不需要再new 一个对象。

以上就是Javascript基于对象三大特性,希望对大家的学习有所帮助。

(0)

相关推荐

  • Javascript面向对象编程(三) 非构造函数的继承

    今天是最后一个部分,介绍不使用构造函数实现"继承". 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". 复制代码 代码如下: var Chinese = { nation:'中国' }; 还有一个对象,叫做"医生". 复制代码 代码如下: var Doctor ={ career:'医生' } 请问怎样才能让"医生"去继承"中国人",也就是说,我怎样才能生成一个&

  • javascript 面向对象全新理练之原型继承

    首先创建一个父类的实例化对象,然后将该对象赋给子类的 prototype 属性. 这样,父类中的所有公有实例成员都会被子类继承.并且用 instanceof 运算符判断时,子类的实例化对象既属于子类,也属于父类. 然后将子类本身赋值给它的 prototype 的 constructor 属性.(注意:这里赋值的时候是没有 () 的!) 这一步是为了保证在查看子类的实例化对象的 constructor 属性时,看到的是子类的定义,而不是其父类的定义. 接下来,通过对 o.method1() 调用的

  • javascript 面向对象,实现namespace,class,继承,重载

    由于组里项目大多的javascript,css等客户端工作是另一同事在负责,该同事又特忙无法重构,老大也就只是提建议并未立即实施重构.但是我前些日子也改过些许客户端的小bug,确实那代码看得让人有些云里雾里,不知身在哪山,轻易不敢动代码,于是就自己动手鼓捣起我曾又爱又恨的javascript来,自己写一个简单的js实现namespace,继承,重载等面向对象的特性.欢迎拍砖灌水 .定义namespace Namesapce.js 复制代码 代码如下: Namespace = new Object

  • 前端开发必须知道的JS之原型和继承

    一. 原型与构造函数 Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型.这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型.譬如普通函数: 复制代码 代码如下: function F(){ alert(F.prototype instanceof Object) //true; } 构造函数,也即构造对象.首先了解下通过构造函数实例化对象的过程. 复制代码 代码如下: function A(x){ this.x

  • JS继承--原型链继承和类式继承

    什么是继承啊?答:别人白给你的过程就叫继承. 为什么要用继承呢?答:捡现成的呗. 好吧,既然大家都想捡现成的,那就要学会怎么继承! 在了解之前,你需要先了解构造函数.对象.原型链等概念...... JS里常用的两种继承方式: 原型链继承(对象间的继承)类式继承(构造函数间的继承) 原型链继承: 复制代码 代码如下: //要继承的对象var parent={name : "baba" say : function(){ alert("I am baba");}} //

  • JavaScript面向对象之Prototypes和继承

    一.前言 本文翻译自微软的牛人Scott Allen Prototypes and Inheritance in JavaScript ,本文对到底什么是Prototype和为什么通过Prototype能实现继承做了详细的分析和阐述,是理解JS OO 的佳作之一.翻译不好的地方望大家修改补充. 二.正文 JavaScript中的面向对象不同于其他语言,在学习前最好忘掉你所熟知的面向对象的概念.JS中的OO更强大.更值得讨论(arguably).更灵活. 1.类和对象 JS从传统观点来说是面向对象

  • JavaScript的原型继承详解

    JavaScript是一门面向对象的语言.在JavaScript中有一句很经典的话,万物皆对象.既然是面向对象的,那就有面向对象的三大特征:封装.继承.多态.这里讲的是JavaScript的继承,其他两个容后再讲. JavaScript的继承和C++的继承不大一样,C++的继承是基于类的,而JavaScript的继承是基于原型的. 现在问题来了. 原型是什么?原型我们可以参照C++里的类,同样的保存了对象的属性和方法.例如我们写一个简单的对象 复制代码 代码如下: function Animal

  • javascript的函数、创建对象、封装、属性和方法、继承

    一,function 从一开始接触到js就感觉好灵活,每个人的写法都不一样,比如一个function就有N种写法 如:function showMsg(){},var showMsg=function(){},showMsg=function(){} 似乎没有什么区别,都是一样的嘛,真的是一样的吗,大家看看下面的例子 复制代码 代码如下: ///----------------------------------------------------------------------------

  • JavaScript使用原型和原型链实现对象继承的方法详解

    本文实例讲述了JavaScript使用原型和原型链实现对象继承的方法.分享给大家供大家参考,具体如下: 实际上JavaScript并不是一门面向对象的语言,不过JavaScript基于原型链的继承方式.函数式语法,使得编程相当灵活,所以可以利用原型链来实现面向对象的编程. 之前对JavaScript一直都是一知半解,这两天看了一下原型链这一块知识,综合练习了一下JavaScript的对象继承方式. 以下就是原型链和原型的关系,引用网上的一张图 在Javascript中,每个函数都有一个原型属性p

  • javascript 面向对象编程基础:继承

    我们看到这里继承的概念是多么的直白,"拷贝一个类的prototype 到另外一个类",好,Code is cheap,看代码: function class1() { } function class2() { } class2.prototype = class1.prototype; class2.moreProperty1 = " class 2 additional string " ; class2.moreMethod1 = function () {

  • Javascript面向对象编程(二) 构造函数的继承

    今天要介绍的是,如何生成一个"继承"多个对象的实例. 比如,现在有一个"动物"对象的构造函数, 复制代码 代码如下: function Animal(){ this.species = "动物"; } 还有一个"猫"对象的构造函数, 复制代码 代码如下: function Cat(name,color){ this.name = name; this.color = color; } 怎样才能使"猫"继承&

  • js对象的构造和继承实现代码

    复制代码 代码如下: <script> //定义js的user对象 function User(name,age){ this.name=name, this.age=age, this.getName=function(){ return this.name; }, this.getAge=function(){ return this.age; } } //实例化一个对象 var use=new User("aa",21); alert(use.name); alert

  • javascript 面向对象全新理练之继承与多态

    1 又是几个基本概念 为什么要说又呢? 在讨论继承时,我们已经列出了一些基本概念了,那些概念是跟封装密切相关的概念,今天我们要讨论的基本概念,主要是跟继承与多态相关的,但是它们跟封装也有一些联系. 1.1 定义和赋值 变量定义是指用 var a; 这种形式来声明变量. 函数定义是指用 function a(...) {...} 这种形式来声明函数. var a = 1; 是两个过程.第一个过程是定义变量 a,第二个过程是给变量 a 赋值. 同样 var a = function(...) {};

随机推荐