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


Posted in Javascript onJanuary 04, 2016

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 一个对象。

下面是其他网友的补充

要分享Js一些基础理论知识,但是在项目中却十分实用。回想之前一次令人心碎的面试,等了将近50分钟,可是面试却不到10分钟,我的心里受到成吨的打击与伤害,以前一直不注重扎实基础,当面试官坐下的那一刻我就感到气氛不对,首先介绍自己软件工程毕业…….然后面试官说介绍一下软件的几大特性……..我…..我说不出话,然后跳过,让我介绍一下闭包、原型、js三大特性,以及在项目中的运用……我的天……当时脑海里浮现的全是我在哪….我是谁…..我在干嘛…..我还要继续坐在这里吗……可能现在说起来比较让人想笑,可是当时的心情确实是很难受的,所以,从那以后,开始注重自己的基础理论知识,好吧,让我们回到正题,let's go!

封装
首先,我们先了解一下什么是Js封装,就是当你需要隐藏一些属性和方法是,就可以将这些属性和方法封装起来,然后通过一个外部可以调用的特定接口(也可以说是一个公共的方法)进行调用。例如:

function Person(name , age , sex){
 this.name = name ; //共有变量 
 var age = age ; //私有变量
 var sex = sex ; //私有变量
 this.show = function (){
  console.log(age+"===="+sex);
 }
}
var person = new Person('Sunshine',18,'女');
console.log(person.age); // undefined
console.log(person.name); // Sunshine
console.log(person.show());  // 18====女

请看代码后的注释,this指向的都是共有的属性和方法,而直接通过var声明的则属于私有变量(即外部不可访问变量),然后通过一个共有的show方法将私有的age和sex输出。当然show方法也要通过this声明才可以哟,否则的话show方法也是不可访问的。

继承
继承其实就是当多个方法存在相同的属性和方法是,就把这些相同的属性和方法提取到一个公共的方法中,通过原型prototype继承该方法,当然你也可以通过call或apply来继承该方法中的属性和方法。

function Person(name , age , sex){
 this.name = name ; 
 this.age = age ; 
 this.sex = sex ; 
 this.show = function (){
  console.log( this.age + "========"+ this.sex );
 }
}
function Student(name , age , sex , score){
 this.score = score ; 
 Person.apply(this,[name , age , sex]);
}
function Worker(name , age , sex , job){
 this.job = job ; 
 Person.call(this,name , age , sex);
}
Dancer.prototype = new Person('Sunshine',18,'女');
function Dancer(salary ){
 this.salary = salary ;
}
var student = new Student('Sunshine',18,'女',100);
var worker = new Worker('Sunshine',18,'女','IT');
var dancer = new Dancer(20000);
console.log(student);
console.log(worker);
console.log(dancer);

最终的结果如下:

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

当然,个人感觉那个prototype没有说的很好,如果看到这篇博客的你有更好的建议或意见的话,欢迎给我留言。还有call和apply,其实它们的作用是一样的,都是改变this指向,然后它们的区别也可以从代码中看出,传参方式不同。

多态
最后要说多态了,写这篇文章之前,自己对多态还是处于懵逼的状态,查阅了不少其他同行的博客,以及W3C 上的解释,把这些总结了一下,多态就是在执行同一操作且作用于不同对象时,返回不同的结果 。其实也就是把做什么和由谁去做分开,这样使得代码更容易维护,且条例清晰。直接上例子吧:

function dwn(s){
 document.write(s+"<br/>");
}
function Animal(){
 this.bite=function(){
  dwn("animal bite!");
 }
}
function Cat(){
 this.bite=function(){
  dwn("Cat bite!");
 }
}
Cat.prototype=new Animal(); ///inherit Animal
function Dog(){
 this.bite=function(){
  dwn("Dog bite");
 }
} 
Dog.prototype=new Animal(); ///inherit Animal
function AnimalBite(animal){
 if(animal instanceof Animal) //这里是判断animal的原型是否指向Animal
 animal.bite();
}
var cat = new Cat();
var dog = new Dog();
AnimalBite(cat);
AnimalBite(dog);
//最终输出的结果如下:
/*
 Cat bite!
 Dog bite
*/

终于写完了,如果以上有错误的话,欢迎指出~

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

Javascript 相关文章推荐
javascript 当前日期加(天、周、月、年)
Aug 09 Javascript
js获取指定日期周数以及星期几的小例子
Jun 27 Javascript
JavaScript极简入门教程(一):基础篇
Oct 25 Javascript
javascript框架设计之种子模块
Jun 23 Javascript
jquery实现鼠标悬浮停止轮播特效
Aug 20 Javascript
jQuery通过ajax请求php遍历json数组到table中的代码(推荐)
Jun 12 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
Jun 17 Javascript
Vue中使用vux的配置详解
May 05 Javascript
基于vue.js路由参数的实例讲解——简单易懂
Sep 07 Javascript
Angularjs使用过滤器完成排序功能
Sep 20 Javascript
jQuery中DOM操作原则实例分析
Aug 01 jQuery
微信小程序中weui用法解析
Oct 21 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
Jan 04 #Javascript
详解Bootstrap glyphicons字体图标
Jan 04 #Javascript
详解Bootstrap按钮
Jan 04 #Javascript
详解Bootstrap四种图片样式
Jan 04 #Javascript
学习javascript面向对象 理解javascript原型和原型链
Jan 04 #Javascript
详解Bootstrap创建表单的三种格式(一)
Jan 04 #Javascript
学习javascript面向对象 实例讲解面向对象选项卡
Jan 04 #Javascript
You might like
Windows下PHP开发环境搭建教程(Apache+PHP+MySQL)
2016/06/13 PHP
AES加解密在php接口请求过程中的应用示例
2016/10/26 PHP
PHP编译configure时常见错误的总结
2017/08/17 PHP
js判断变量是否未定义的代码
2020/03/28 Javascript
js获取当前路径的简单示例代码
2014/01/08 Javascript
使用jQuery重置(reset)表单的方法
2014/05/05 Javascript
js实现最短的XML格式化工具实例
2015/03/12 Javascript
javascript实现tab切换的四种方法
2015/11/05 Javascript
jQuery 中的 DOM 操作
2016/04/26 Javascript
JavaScript中关键字 in 的使用方法详解
2016/10/17 Javascript
JavaScript+CSS相册特效实例代码
2017/09/07 Javascript
vue router 传参获取不到的解决方式
2019/11/13 Javascript
通过实例了解Javascript柯里化流程
2020/03/03 Javascript
vue中父子组件的参数传递和应用示例
2021/01/04 Vue.js
用Python将动态GIF图片倒放播放的方法
2016/11/02 Python
python实现杨辉三角思路
2017/07/14 Python
python使用opencv按一定间隔截取视频帧
2018/03/06 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
python打包exe开机自动启动的实例(windows)
2019/06/28 Python
python openpyxl使用方法详解
2019/07/18 Python
Tensorflow 实现将图像与标签数据转化为tfRecord文件
2020/02/17 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
Html5实现iPhone开机界面示例代码
2013/06/30 HTML / CSS
信用社实习人员自我鉴定
2013/09/20 职场文书
儿科主治医生个人求职信
2013/09/23 职场文书
设计总监岗位职责
2013/12/07 职场文书
优秀教师的感人事迹
2014/02/04 职场文书
初中优秀班集体申报材料
2014/05/01 职场文书
企业安全生产演讲稿
2014/05/09 职场文书
“六查”、“三学”、“三干”查摆问题整改措施
2014/09/27 职场文书
学校政风行风整改方案
2014/10/25 职场文书
汽车销售助理岗位职责
2015/04/14 职场文书
大学三好学生主要事迹范文
2015/11/03 职场文书
2016年入党心得体会范文
2016/01/23 职场文书
导游词之阳朔遇龙河
2019/12/16 职场文书
Oracle 11g数据库使用expdp每周进行数据备份并上传到备份服务器
2022/06/28 Oracle