JavaScript面向对象的三大特性
1、JavaScript面向对象的三大特性
JavaScript的三大特性:封装性、继承性、多态性。
2、JavaScript实现封装特性
在一些静态类型的语言如java中,本身语法就提供了这些功能。js当中只能依靠变量的作用域来实现封装的特性,并且只能模拟出public和private两种特性。封装实现就是是对象内部的变化对外界是透明的,不可见。这种做法使对象之间低耦合,便于维护升级,团队协作开发。
3、JavaScript实现继承特性
继承可以解决代码复用,让编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过继承父类中的属性和方法。
JS中实现继承的方式:
1、通过call或者apply实现继承
1 //1.把子类中共有的属性和方法抽取出,定义一个父类Stu 2 function Stu(name,age){ 3 //window.alert("确实被调用."); 4 this.name=name; 5 this.age=age; 6 this.show=function(){ 7 window.alert(this.name+"年龄是="+this.age); 8 } 9 } 10 //2.通过call或者apply来继承父类的属性的方法 11 function MidStu(name,age){ 12 //这里这样理解: 通过call修改了Stu构造函数的this指向, 13 //让它指向了调用者本身. 14 Stu.call(this,name,age); 15 //如果用apply实现,则可以 16 //Stu.apply(this,[name,age]); //说明传入的参数是 数组方式 17 //可以写MidStu自己的方法. 18 this.pay=function(fee){ 19 window.alert("你的学费是"+fee*0.8); 20 } 21 } 22 function Pupil(name,age){ 23 Stu.call(this,name,age);//当我们创建Pupil对象实例,Stu的构造函数会被执行,当执行后,我们Pupil对象就获取从 Stu封装的属性和方法 24 //可以写Pupil自己的方法. 25 this.pay=function(fee){ 26 window.alert("你的学费是"+fee*0.5); 27 } 28 } 29 //测试 30 var midstu=new MidStu("zs",15); 31 var pupil=new Pupil("ls",12); 32 midstu.show(); 33 midstu.pay(100); 34 pupil.show(); 35 pupil.pay(100);
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <script type="text/javascript"> 11 function Animal(name,age){ 12 this.name=name; 13 this.age=age; 14 this.shout=function(){ 15 alert("我是:"+this.name+",今年:"+this.age); 16 }; 17 this.action=function(){ 18 alert("会吃"); 19 }; 20 } 21 22 function Dog(name,age){ 23 Animal.apply(this, [name,age]); 24 } 25 26 var jack=new Dog("jack",1); 27 alert(jack.name); 28 alert(jack.age); 29 jack.shout(); 30 jack.action(); 31 </script> 32 </body> 33 </html>
2、原型继承方式实现继承
原型继承是js中最通用的继承方式,不用实例化对象,通过直接定义对象,并被其他对象引用,这样形成的一种继承关系,其中引用对象被称为原型对象。
1 function A(){ 2 this.color = 'red'; 3 } 4 function B(){} 5 function C(){} 6 B.prototype = new A(); 7 C.prototype = new B(); 8 // 测试原型继承 9 var c = new C(); 10 console.log(c.color); // red
原型继承显得很简单,不需要每次构造都调用父类的构造函数,也不需要通过复制属性的方式就能快速实现继承。但它也存在一些缺点:
① 每个类型只有一个原型,所以不支持多重继承(即一个子类继承自多个父类)。
② 不能很好的支持多参数或动态参数的父类,显得不够灵活。
③ 占用内存多,每次继承都需要实例化一个父类,这样会存在内存占用过多的问题。
4、JavaScript实现多态特性
JS的函数重载
这个是多态的基础,JS函数不支持多态,事实上JS函数是无态的,支持任意长度,类型的参数列表。如果同时定义了多个同名函数,则以最后一个函数为准。
1、js不支持重载,通过判断参数的个数来模拟重载的功能。
1 /*****************说明js不支持重载*****/ 2 function Person(){ 3 this.test1=function (a,b){ 4 window.alert('function (a,b)'); 5 } 6 this.test1=function (a){ 7 window.alert('function (a)'); 8 } 9 } 10 var p1=new Person(); 11 //js中不支持重载. 12 //但是这不会报错,js会默认是最后同名一个函数,可以看做是后面的把前面的覆盖了。 13 p1.test1("a","b"); 14 p1.test1("a");
1 //js怎么实现重载.通过判断参数的个数来实现重载 2 function Person(){ 3 this.test1=function (){ 4 if(arguments.length==1){ 5 this.show1(arguments[0]); 6 }else if(arguments.length==2){ 7 this.show2(arguments[0],arguments[1]); 8 }else if(arguments.length==3){ 9 this.show3(arguments[0],arguments[1],arguments[2]); 10 } 11 } 12 this.show1=function(a){ 13 window.alert("show1()被调用"+a); 14 } 15 this.show2=function(a,b){ 16 window.alert("show2()被调用"+"--"+a+"--"+b); 17 } 18 function show3(a,b,c){ 19 window.alert("show3()被调用"); 20 } 21 } 22 var p1=new Person(); 23 //js中不支持重载. 24 p1.test1("a","b"); 25 p1.test1("a");
2、多态基本概念
多态是指一个引用(类型)在不同情况下的多种状态。也可以理解成:多态是指通过指向父类的引用,来调用在不同子类中实现的方法。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <script type="text/javascript"> 11 function Animal(){ 12 this.say=function(){ 13 alert("我是动物"); 14 }; 15 } 16 17 function Dog(){ 18 this.say=function(){ //多态的实现需要重写父类对象的方法 19 alert("我是狗"); 20 }; 21 } 22 Dog.prototype=new Animal();//多态的实现需要原生继承 23 24 function Cat(){ 25 this.say=function(){ //多态的实现需要重写父类对象的方法 26 alert("我是猫"); 27 }; 28 } 29 Cat.prototype=new Animal(); 30 31 function say(animal){ 32 if(animal instanceof Animal){ 33 animal.say(); 34 } 35 } 36 37 var dog=new Dog(); 38 var cat=new Cat(); 39 say(dog); 40 say(cat); 41 </script> 42 </body> 43 </html>
备注:多态利于代码的维护和扩展,当我们需要使用同一类树上的对象时,只需要传入不同的参数就行了,而不需要再new 一个对象。