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 相关文章推荐
B/S开发中常用javaScript技术与代码
Mar 09 Javascript
JavaScript lastIndexOf方法入门实例(计算指定字符在字符串中最后一次出现的位置)
Oct 17 Javascript
浅谈jquery.fn.extend与jquery.extend区别
Jul 13 Javascript
果断收藏9个Javascript代码高亮脚本
Jan 06 Javascript
javascript中去除数组重复元素的实现方法【实例】
Apr 12 Javascript
Bootstrap编写导航栏和登陆框
May 30 Javascript
JavaScript与ActionScript3两者的同性与差异性
Sep 22 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
Aug 14 jQuery
详述 Sublime Text 打开 GBK 格式中文乱码的解决方法
Oct 26 Javascript
JS常见面试试题总结【去重、遍历、闭包、继承等】
Aug 27 Javascript
javascript实现贪吃蛇经典游戏
Apr 10 Javascript
Element Dropdown下拉菜单的使用方法
Jul 26 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
php 在线打包_支持子目录
2008/06/28 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
2011/10/29 PHP
php 团购折扣计算公式
2011/11/24 PHP
php采用curl实现伪造IP来源的方法
2014/11/21 PHP
php将access数据库转换到mysql数据库的方法
2014/12/24 PHP
PHP的Yii框架中过滤器相关的使用总结
2016/03/29 PHP
PHP实现文件上传功能实例代码
2017/05/18 PHP
php+js实现的无刷新下载文件功能示例
2019/08/23 PHP
js实现GridView单选效果自动设置交替行、选中行、鼠标移动行背景色
2010/05/27 Javascript
JavaScript 操作table,可以新增行和列并且隔一行换背景色代码分享
2013/07/05 Javascript
js写的方法实现上传图片之后查看大图
2014/03/05 Javascript
jQuery判断元素是否存在的可靠方法
2014/05/06 Javascript
js判断当页面无法回退时关闭网页否则就history.go(-1)
2014/08/07 Javascript
JavaScript常用脚本汇总(二)
2015/03/04 Javascript
JavaScript实现打字效果的方法
2015/07/10 Javascript
Bootstrap的图片轮播示例代码
2015/08/31 Javascript
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
在Docker快速部署Node.js应用的详细步骤
2016/09/02 Javascript
JavaScript 数组的深度复制解析
2016/11/02 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
很棒的一组js图片轮播特效
2017/01/12 Javascript
nodejs中解决异步嵌套循环和循环嵌套异步的问题
2017/07/12 NodeJs
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
vue.js购物车添加商品组件的方法
2019/09/17 Javascript
JS脚本实现定时到网站上签到/签退功能
2020/04/22 Javascript
[50:54]完美世界DOTA2联赛 GXR vs IO 第三场 11.07
2020/11/10 DOTA
Python中的asyncio代码详解
2019/06/10 Python
澳大利亚玩具剧场:Toy Playhouse
2019/03/03 全球购物
js实现弹框效果
2021/03/24 Javascript
公司授权委托书格式范文
2014/10/02 职场文书
解除劳动合同协议书(样本)
2014/10/02 职场文书
2015年社区创卫工作总结
2015/04/21 职场文书
主题班会开场白
2015/06/01 职场文书
2019个人半年工作总结
2019/06/21 职场文书
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis
Java并发编程之原子性-Atomic的使用
2022/03/16 Java/Android