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动态添加与删除select中的Option对象(示例代码)
Dec 20 Javascript
jQuery实现当按下回车键时绑定点击事件
Jan 28 Javascript
JavaScript 模块化编程(笔记)
Apr 08 Javascript
jquery实现的美女拼图游戏实例
May 04 Javascript
AngularJS中实现动画效果的方法
Jul 28 Javascript
可输入文字查找ajax下拉框控件 ComBox的实现方法
Oct 25 Javascript
Bootstrap CSS布局之按钮
Dec 17 Javascript
详解如何使用webpack+es6开发angular1.x
Aug 16 Javascript
详解HTML5 使用video标签实现选择摄像头功能
Oct 25 Javascript
如何去除富文本中的html标签及vue、react、微信小程序中的过滤器
Nov 21 Javascript
vue打包之后生成一个配置文件修改接口的方法
Dec 09 Javascript
解读Vue组件注册方式
May 15 Vue.js
详解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
zen cart新进商品的随机排序修改方法
2010/09/10 PHP
php采用session实现防止页面重复刷新
2015/12/24 PHP
redirect_uri参数错误的解决方法(必看)
2017/02/16 PHP
Code: write(s,d) 输出连续字符串
2007/08/19 Javascript
jquery中输入验证中一个不错的效果
2010/08/21 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
2012/03/15 Javascript
基于KMP算法JavaScript的实现方法分析
2013/05/03 Javascript
javascript读写XML实现广告轮换(兼容IE、FF)
2013/08/09 Javascript
JavaScript中常用的六种互动方法示例
2015/03/13 Javascript
最简单的JavaScript验证整数、小数、实数、有效位小数正则表达式
2015/04/17 Javascript
教你使用javascript简单写一个页面模板引擎
2015/05/05 Javascript
JS图片等比例缩放方法完整示例
2016/08/03 Javascript
Vue服务端渲染和Vue浏览器端渲染的性能对比(实例PK )
2017/03/31 Javascript
nodejs和C语言插入mysql数据库乱码问题的解决方法
2017/04/14 NodeJs
vue实现数据控制视图的原理解析
2020/01/07 Javascript
Python魔术方法详解
2015/02/14 Python
python通过pil将图片转换成黑白效果的方法
2015/03/16 Python
python取代netcat过程分析
2018/02/10 Python
Python 网络爬虫--关于简单的模拟登录实例讲解
2018/06/01 Python
python检测主机的连通性并记录到文件的实例
2018/06/21 Python
Python3.5基础之变量、数据结构、条件和循环语句、break与continue语句实例详解
2019/04/26 Python
python面试题之列表声明实例分析
2019/07/08 Python
基于h5py的使用及数据封装代码
2019/12/26 Python
如何查看Django ORM执行的SQL语句的实现
2020/04/20 Python
static关键字的用法
2013/10/07 面试题
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?
2016/08/18 面试题
个人收入证明范本
2014/01/12 职场文书
《穷人》教学反思
2014/04/08 职场文书
党的群众路线教育实践活动个人对照检查材料(四风)
2014/11/05 职场文书
中小企业员工手册范本
2015/05/14 职场文书
《我们的民族小学》教学反思
2016/02/19 职场文书
八年级作文之感悟亲情
2019/11/20 职场文书
浅谈Mysql多表连接查询的执行细节
2021/04/24 MySQL
总结几个非常实用的Python库
2021/06/26 Python
使用Python获取字典键对应值的方法
2022/04/26 Python
Spring Boot项目如何优雅实现Excel导入与导出功能
2022/06/10 Java/Android