javascript 面向对象编程

                                                                javascript 面向对象编程
1、面向对象的特性
1.1封装
封装(Encapsulation)是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。理解封装性的一个方法就是把他想成一个黑匣子,它可以阻止在外部定义的代码随意访问内部代码和数据。对黑匣子内代码和数据的访问通过一个适当定义的接口严格控制。
类中的每个方法或属性都可以被标记为私有(private)或公有(public)。既然类的私有成员仅能被程序中的其他部分通过该类的公共方法访问,那么你就能保证不希望发生的事情一定不会发生。
1.2继承
继承(Inheritance)是一个对象获得另一个对象的属性的过程。使用了继承,一个对象就只需要定义使它在所属类中独一无二的属性即可,因为它可以从它的父类那儿继承所有的通用属性。继承实现了代码的重用,降低了程序的复杂性。

1.3多态性
多态性(Polymorphism)是允许一个接口被多个同类动作使用的特性,具体使用哪个动作与应用场合有关。即“一个接口,多种方法。”
子类重写了父类的一个方法,运行时多态。多态能够让对象在运行时决定实际调用的方法体。
或者类的内部方法的重载,静态多态。编译时多态。
2、Js的面向对象原理
2.1 对象的创建
在javascript里有几种创建对象的方法,在不同的场合可用不同的方法.
var person = new Object()
person.name = "Tim Scarfe";
person.height = "6Ft";
person.run = function() {
this.state = "running";
this.speed = "4ms^-1";
}
我们在这个例子里定义了person这个对象,然后加入了它的属性和方法.在这个例子里,自定义的方法里有两个属性.

JavaScript还支持内部构造函数,它们以另一种简洁的方式初始化新创建的对象。
var now = new Date();

对象直接量提供了另一种创建并初始化新对象的方法。
Var person = {
name : "Tim Scarfe",
height : "6Ft",
address : ["联航路1588号", “54325000”, "201112"],
work : function(){alert("我正在工作!")}
};
对象直接量可以是数组,也可以是任意的javascript表达式或值。

思考
但它最大的缺点就是结果不可复用,也不能很容易的用不同的版本初始化创建对象。
在OOP的世界里,用先前的方法定义对象在许多场合都有限制。我们需要一种创建对象的方法,类型可以被多次使用而不用重新定义,对象在实例化时每次都可以按需分配不同的值,实现这个目标的标准方法是用构造函数。
2.2自定义类
一个构造函数只不过是个有规则的javascript函数,它就象一个容器(定义参数,调用其他函数等等).它们两者所不同的是:
构造函数是由 new 操作符调用的.(你将在下面的例子中看到).
传递给它的是一个对新创建的空对象的引用,将该引用作为关键字this的值,而且它还要对新创建的对象进行适当的初始化。
2.3缺点?
每个属性和方法都占用一定的内存空间,这里假如定义了三个对象就占用三倍的内存空间。Java里也是这样,但JavaScript里提供了一个更好的解决方法。
解决方法:原型(prototype)。
2.4原型
看个例子。

JavaScript对象都继承原型对象的属性。每个对象都有原型对象。
一个对象的原型是由创建并初始化该对象的构造函数定义的。JavaScript中的所有函数都有prototype属性,它引用了一个对象。虽然原型对象初始化时是空的,但是你在其中定义的任何属性都会被该构造函数创建的所有对象继承。

读写属性的不对称性:

3、Js中的封装
3.1 public和private访问限定的实现
作用域
该例子演示了public和private访问限定的实现。本例子中,共有两个属性和两个方法。注意到PrivateName的声明,它并没有绑定到这个类,因此只具有局部作用域,生命期仅在本类中,如果在类的方法中调用它的话,是可以正常调用的(调用的时候不加this关键字)。同理,没有绑定的方法也只能在类的内部调用。因此,js中的public与private限定可以通过这种方式来实现。

3.2实例属性、实例方法
JavaScript中的实例属性是那些在对象中用构造函数创建的或初始化的属性。
实例方法和实例属性非常相似,只不过它是方法而不是数值,每个实例方法都是由类的所有实例共享的。
3.3类属性、类方法
当类被实例化,所能够访问的仅仅是在类中定义的普通属性。当不实例化,通过类名访问的时候,可以访问类中的静态方法和静态属性,静态方法只能访问静态属性。与C++类似,静态成员的初始化需要在类的外面进行。

思考1:
顺便讨论一下protected限定,它的作用是使得被限定的变量或方法不能被类的实例调用,但是能够被派生类调用。后来发现,既然public跟private限定是通过指定绑定来实现的,那么,没法创建一种介于绑定和不绑定之间的关系,也就不好用这种方式模拟。再转念一想,protected限定几乎都是实现在编译型的语言中。在目标代码或者中间代码层次,这种限定非常重要,它能够有效配合软件工程理论进行开发,但是js是纯解释型语言,源代码公开的级别,不存在有效的模块保护机制,任何人可以随意修改代码,这样,protected关键字完全没有用武之地。
思考2:
另外有一点比较困惑,整个class中都是public的,没有关键字private之类的可以控制某些方法是否隐藏,那么在我们编写代码实现的规范中,我看国外一些程序员都是使用_functionName这样子为函数命的方法来区分,但是在调用过程中实际还可以调用的。
4、Js中的继承
JavaScript采用的是以原型对象为基础的继承机制,而不是采用以类为基础的继承机制。
4.1超类和子类
在JavaScript中,类Object是最通用的类,其他类都是Object的子类。
原型对象本身就是一个对象,他是由构造函数Object()创建的。这意味着原型对象继承了Object.prototype属性。
创建一个子类,只需要确保子类的原型对象是父类的一个实例,这样子类就继承了父类的所有属性:

我们明确地把MoreComplex.prototype设成了我们所创建的一个对象,所以就覆盖了JavaScript提供地原型对象,而且抛弃了给定地constructor属性,但是继承了他的超类的constructor属性,它自己并没有这个属性。明确的设置这一属性可以解决这一问题:
MoreComplex.prototype.constructor = MoreComplex;

调用的传递:
moreComplex.toString()->moreComplex.prototype.toString()->Complex.toString()->Complex.prototype.toString()->Object.toSring()->Object.prototype.toString();
看来是不是很奇妙呢。
4.2类似引用的方法
子类中创建了基类的对象,为它添加了新的属性和方法,然后将它作为子类构造函数的结果返回出去,得到子类对象。子类对象比基类对象多了一些属性和方法,分配到了更多内存空间。注意到每次输出的constructor属性的值,发现它们两次返回的都是基类的构造函数,这并不奇怪,因为子类的构造函数最后返回的是添加了新属性、新方法的基类对象,js执行环境仍然会认为它是一个基类对象。           
4.3通过function 实现继承
下面一个例子演示了如何通过function 继承.

4.4多重继承
该例子演示了从两个不同基类派生出一个子类的方法。子类中分别创建了两个基类的对象,将其中一个的所有属性和方法添加到另外一个上,然后将后者作为子类构造函数的结果返回出去,得到子类对象。通过这种途径,变相地实现了多重继承。这里有一个注意点,不同的基类中如果包含同名变量或方法,需要自己指定以哪个作为实际绑定。
       
5、Js中的多态
多态能够让对象在运行时决定实际调用的方法体。由于js是一种动态语言,支持运行时绑定,讨论它的多态实际上并没有太大意义。Js不支持virtual关键字,而virtual关键字在现在的js里面也不会有明显用处。最根本的一点,js能够在运行时改变数据类型,可以随时根据新类型来取得它所拥有的方法,而忽视原有类型的影响。

示例3-1:该例子创建了一个基类跟一个子类,拥有一个同名方法,分别将基类和子类实例化并调用这个方法,显示的结果将随着方法所属类的不同而不同。
原因很简单,因为例子使用的这种“继承”机制本身就是利用js语言的动态特性实现的,在一个类实例化的时候,它已经知道自己拥有哪些方法,而且,它也不关心这些方法从哪个类继承,只是将它们作为普通的成员方法来调用,所以,每一个类调用的同名方法都是属于自己的那个。
再者,js是弱类型语言,它的变量声明的时候并不知道自己的类型,也并不知道将要被初始化成什么类型,赋予它什么类型的值,它就是什么类型的变量。本例子中分别注释掉的两段语句就说明了这个问题:Js在运行时既能够将子类变量赋给基类变量(这个特性在C++等语言中正是实现多态的关键),也可以将基类变量赋给子类变量(一般在静态语言中不允许,因为缺少附加信息)。
  
6、类库:
面向对象的语言之所以强大,还有一个原因,有大量的类库。
<http://www.prototypejs.org/>
<http://script.aculo.us/>
<http://moofx.mad4milk.net/>
<http://developer.yahoo.com/yui/>
<http://bennolan.com/behaviour/>
  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值