js的面向对象的三大特征

来源:互联网 发布:西安企业预算软件 编辑:程序博客网 时间:2024/06/02 17:44


封装性
所谓封装,就是把我们抽象出的属性和对属性的操作写到类的定义中,

称为封装. 
js 中实现封装主要有两种封装( 公开,私有) 
class Person(name,sal)

{  this.name=name; //公开 

var sal=sal;//私有   this.showInfo=function()

{ //公开  window.alert(this.name+” ”+sal);

showInfo2(){ //把函数私有化.

window.alert(“你好”+this.name+” ”+sal)
} } 

通过构造函数添加成员方法和通过原型法添加成员方法的区别
1. 通过原型法分配的函数是所有对象共享的.
2. 通过原型法分配的属性是独立.(如果你不修改属性,他们是共享)
3. 建议,如果我们希望所有的对象使用同一一个函数,最好使用原型法添加函

数,这样比较节省内存

function Dog(){
 this.shout=function(){ } }

//原型法
Dog.prototype.shout=function ()

{    window.alert("小狗尖叫"+this.name);   }   

//通过原型也可以给每个对象,分配属性  

Dog.prototype.color="red";   

var dog1=new Dog("aa");  

var dog2=new Dog("bb");     

if(dog1.shout==dog2.shout)

{    window.alert("dog1.shout==dog2.shout");   }  

dog1.color="黑色";  

window.alert(dog1.color+" "+dog2.color); 


4. 请大家看一个题: 
function Person(){       }   

// 创建对象  

var p1=new Person();  

// p1.say(); [错误]

// 这时用原型法分配  

Person.prototype.say=function()

{    window.alert("ok");   }   

p1.say(); 
结论是 类.prototype.函数=function (){}; 称为后置绑定.



js面相对象的继承
看一段代码->问题是什么? 
①对象冒充 
代码如下:

<html> <head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/> 
<script type="text/javascript">

//中学生
/* function MidStu(name,age){   this.name=name;  

this.age=age;   

this.show=function()

{    window.alert(this.name+"年龄是="+this.age);   }   

this.pay=function(fee)

{    window.alert("你的学费是"+fee*0.8);  

 } 

  }  

//小学生 

function Pupil(name,age)

{   this.name=name;  

    this.age=age;   

    this.show=function(){

    window.alert(this.name+"年龄是="+this.age);   }   

    this.pay=function(fee)

    {    window.alert("你的学费是"+fee*0.5);   } 

}*/  

//代码的复用性不高. 

//修改如下: 

//1. 把子类中共有的属性和方法抽取出,定义一个父类Stu 

function Stu(name,age)

{      this.name=name;  

       this.age=age;     

       this.show=function()

   {    window.alert(this.name+"年龄是="+this.age);   } 

//2.通过对象冒充来继承父类的属性的方法  

function MidStu(name,age)

{      this.stu=Stu;

//这里相当于把Stu构造函数(类)赋值给我们的属性this.stu  

//调用this.stu方法   this.stu(name,age);

//这个表示初始化MidStu,相当于执行Stu(name,age),

这句话必须有,否则无法实现集成的效果   

//可以写MidStu自己的方法.  

this.pay=function(fee)

{    window.alert("你的学费是"+fee*0.8);   }

  }  

function Pupil(name,age)

{   this.stu=Stu;//这里只是把码继承.  

//初始化一把  

this.stu(name,age);   

//可以写Pupil自己的方法.  

this.pay=function(fee)

{    window.alert("你的学费是"+fee*0.5);   }

}  

 //测试  

var midstu=new MidStu("贾宝玉",15); 

var pupil=new Pupil("贾环",12);  

midstu.show();  

midstu.pay(100);  

pupil.show(); 

pupil.pay(100); 
</script> </html>

②通过call 或者apply来实现 
<html> <head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/> 
<script type="text/javascript">    

//中学生
/* function MidStu(name,age)

{  

this.name=name;  

this.age=age;   

this.show=function()

{    window.alert(this.name+"年龄是="+this.age);   }

this.pay=function(fee)

{    window.alert("你的学费是"+fee*0.5);   } 

}*/

//代码的复用性不高. 

//修改如下:
 //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("孙悟空",15); 

var pupil=new Pupil("猪八戒",12);   

midstu.show();  

midstu.pay(100);   

pupil.show(); 

pupil.pay(100);

</script> </html>

js的继承小结
(1) js对象可以通过对象冒充,实现多重继承

(2) Object 类是所有js类的基类


多态的特性
① js的函数的重载文件 
js默认不支持重载,我们可以通过,判断参数的个数来实现重载

<html> <head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/> 
<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中不支持重载. 

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> 

② 覆盖 
当子类有一个方法和父类一样,则我们称子类的方法覆盖了父类的方法 。

//父类
function Stu()

{      this.show=function(){    window.alert("stu show");   }

  }

//子类 

function MidStu()

{     

this.stu=Stu;   this.stu();  

//一定要放在类定义的后面  

this.show=function()

{    window.alert("midstu show");   }

  }

var midstu=new MidStu();  

midstu.show(); 

☞ 要实现覆盖,需要把子类的方法,防止类定义的后面


 多态的基本概念

① 所谓多态,我们可以简单的理解就是一个引用类型 (对象/变量) 在不同情况下的多种状态

② js 本身是无态,js天生就支持多态. 
    js的多态的一个案例:

    <script type="text/javascript">  

    //人类 

    function Person()

    {   this.test1=function ()

    {   window.alert("Person test1");  } 

     }  

    //猫类 

    function Cat()

    {   this.test1=function()

    {    window.alert("Cat test1()");  }

      }  

     var v=new Person();

  var p=v;  //防止后面v被猫类替代后,

  v代表person这个类被垃圾回收机制回收。

  v.test1(); 

  //v的类型 

  if(v instanceof Person)

  {   window.alert("23 行 v变量是人类");  }   

   v=new Cat();   v.test1();

   if(v instanceof Cat)

   {   window.alert("30 行 v变量是猫类");  }

   //在这里,v是猫类,而同时,其以前代表的人类被回收机制给收走了。

   如果要让其恢复,只要按上面的红色加背景文字处理即可,定义var p=v  
</script>

js的多态的经典案例

<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 master=new Master("韩顺平");

        master.feed(dog,bone); 

       //扩展 

        var monkey=new Monkey("金丝猴");

        var peach=new Peach("仙桃");

</script>
总结:多态有利于代码的维护和扩展,这里我们可以考虑,

如果食物 加入  桃子,动物加入 猴子,可以看到,Master的feed函数不需要的变化。 

0 0