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 相关文章推荐
js传值 判断
Oct 26 Javascript
jquery插件validate验证的小例子
May 08 Javascript
ExtJS实现文件下载的方法实例
Nov 09 Javascript
利用js实现禁止复制文本信息
Jun 03 Javascript
jQuery验证插件validate使用详解
May 11 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
May 25 Javascript
AngularJs自定义服务之实现签名和加密
Aug 02 Javascript
Angular.js中$resource高大上的数据交互详解
Jul 30 Javascript
Angularjs自定义指令实现分页插件(DEMO)
Sep 16 Javascript
JavaScript实现QQ列表展开收缩扩展功能
Oct 30 Javascript
JavaScript this绑定过程深入详解
Dec 07 Javascript
微信小程序实现消息框弹出动画
Apr 18 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三维数组去重(示例代码)
2013/11/26 PHP
php实现的通用图片处理类
2015/03/24 PHP
javascript实现的动态文字变换
2007/07/28 Javascript
javascript 解决表单仍然提交即使监听处理函数返回false
2010/03/14 Javascript
jQuery1.6 正式版发布并提供下载
2011/05/05 Javascript
jQuery验证Checkbox是否选中的代码 推荐
2011/09/04 Javascript
jQuery获取动态生成的元素示例
2014/06/15 Javascript
jQuery中width()方法用法实例
2014/12/24 Javascript
JavaScript 里的类数组对象
2015/04/08 Javascript
require.js的用法详解
2015/10/20 Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
2015/11/17 Javascript
图文详解Javascript中的上下文和作用域
2017/02/15 Javascript
原生js FileReader对象实现图片上传本地预览效果
2020/03/27 Javascript
get  post jsonp三种数据交互形式实例详解
2017/08/25 Javascript
详解如何在vue项目中使用layui框架及采坑
2019/05/05 Javascript
原生JS与JQ获取元素的区别详解
2020/02/13 Javascript
python分析nignx访问日志脚本分享
2015/02/26 Python
状态机的概念和在Python下使用状态机的教程
2015/04/11 Python
在Python的Flask框架中实现全文搜索功能
2015/04/20 Python
python itchat实现微信自动回复的示例代码
2017/08/14 Python
matplotlib subplots 调整子图间矩的实例
2018/05/25 Python
Python GUI Tkinter简单实现个性签名设计
2018/06/19 Python
python在html中插入简单的代码并加上时间戳的方法
2018/10/16 Python
python模块导入的细节详解
2018/12/10 Python
Python中Numpy mat的使用详解
2019/05/24 Python
Python3 操作 MySQL 插入一条数据并返回主键 id的实例
2020/03/02 Python
使用CSS3制作一个简单的进度条(demo)
2017/05/23 HTML / CSS
超级英雄、电影和电视、乐队和音乐T恤:Loud Clothing
2019/09/01 全球购物
贝佳斯官方网站:Borghese
2020/05/08 全球购物
长辈证婚人证婚词
2014/01/09 职场文书
销售辞职报告范文
2014/01/12 职场文书
三八妇女节活动总结
2014/05/04 职场文书
小学兴趣小组活动总结
2014/07/07 职场文书
群众路线剖析材料范文
2014/10/09 职场文书
2014年科普工作总结
2014/12/06 职场文书
酒店收银员岗位职责
2015/04/07 职场文书