1 ,什么是面向对象?
正如每个人心中都有一个哈姆雷特一样,每个人都有对面向对象的不一样的理解
OO (Object Oriented, 面向对象)是当前计算机界关心的重点,它是90年代软件开发的主流。面向对象的概念和应用已经超越了程序设计和软件开发,扩展到很宽的范围。如数据库系统、交互式界面、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。
OO方法(Object-Oriented Method,面向对象方法)面向对象的方法是一种把面向对象的实现应用于软件开发过程中,指导开发活动的系统方法,简称OO(Object-Oriented)方法,Object Oriented是建立在“对象”概念基础上的方法学。对象是由数据和容许的操作组成的封装体,与客观实体有直接对应关系,一个对象类定义了具有相识性质的一组对象。而每继承性是具有层次关系的类的属性和操作进行共享的一种方式。所谓的面向对象就是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解刻画客观世界和设计、构建相应的软件系统。
(我会在介绍完js中对象的特征后面继续介绍面向对象方法,转的一句话说明什么事面向对象方法,让你对面向对象有一个更深入的了解!)
2 ,JS中的面向对象的基本特征
面向对象的三个基本特征是:封装、继承、多态。在js中面向对象只有封装和继承,没有多态。
封装:通过将一个方法或者属性声明为私用的,可以让对象的实现细节对其他对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束这样可以使代码更可靠,更易于调试。封装是面向对象的设计的基石。
JavaScript是一门面向对象的语言,可它并不具备将成员声明为公共或私用的任何内部机制,所以我们只能自己想办法实现这种特性。下面还是通过一台完整的代码去分析,介绍什么是私有属性和方法,什么是特权属性和方法,什么是公有属性和方法,什么是公有静态属性和方法。
私有静态属性和方法: 函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量。
特权属性和方法:创建属性和方法时使用的this关键字,因为这些方法定义在构造器的作用域中,所以它们可以访问到私有属性和方法;只有那些需要直接访问私有成员的方法才应该被设计为特权方法。
公有属性和方法:直接书写在原型prototype上的属性和方法,不可以访问构造器内的私有成员,可以访问特权成员,子类会继承所有的公有方法。
公有静态属性和方法:最好理解的方式就是把它想象成一个命名空间,实际上相当于把构造器作为命名空间使用。
/* -- 封装 -- */
var _packaging =function(){
//私有属性和方法
var name ='Darren';
var method1 =function(){
//...
}
//特权属性和方法
this.title ='JavaScript Design Patterns' ;
this.getName =function(){
return name;
}
}
//公有静态属性和方法
_packaging._name ='Darren code';
_packaging.alertName =function(){
alert(_packaging._name);
}
//公有属性和方法
_packaging.prototype = {
init:function(){
//...
}
}
继承:继承是指这样一种能力:他可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
通过继承创建的新类称为 “子类” 或 “派生类”。
被继承的类称为“基类”、“父类” 或者 “超类”。
① 构造函数绑定
这一种方法最简单,使用call 或者 apply 方法,将父对象的构造函数绑定在子对象上,既在子对象构造元素中加一行代码:
父类构造函数名.apply(this, arguments);
Person.prototype.getName = function(){
returnthis.name;
}
function Programmer(name,sex) {
Person.call(this,name); //在这里添加
this.sex = sex;
}
② 原型式继承 让子类的prototype对象指向父类的实例,相当于完全删除了prototype对象的原来的值,但是我们需要在原型继承js语句后面加上段代码 : 子类. prototype.constructor = 子类 ,不然子类的原型对象的构造函数属性就会指向所继承的父类prototype上的constructor(直接继承父类的原型的时候),继承父类的实例的时候回丢失constructor属性,继承完成之后当前这个子类的实例也都可以继承父类的prototype上的方法
//直接继承父类原型
function Parent(name) {
this.name = name;
}
Parent.prototype.sayHello = function() {
console.log("hello");
}
function Son(name) {
this.name = name;
}
Son.prototype = Parent.prototype;
Son.prototype.constructor = Son;//不加这句话Son.prototype.constructor指向Parent
var s = new Son();
s.sayHello()//hello
// 原型式继承改进
function Parent(name) {
this.name = name;
}
Parent.prototype.sayHello = function() {
console.log("hello");
}
function Son(name, age) {
this.name = name;
this.age = age;
}
Son.prototype.sayHi = function() {
console.log("hi");
}
Son.prototype = new Parent(); //原型继承改进继承父类的实例
Son.prototype.constructor = Son;//不加这句话Son.prototype.constructor会丢失
var s = new Son();
var p = new Parent();
s.sayHello()//hello
console.log(Son.prototype)
p.sayHi()// Uncaught TypeError: p.sayHi is not a function,父类的实例不可以调用子类的方法了
js中对象的组成
方法——函数:过程、动态的
属性——变量:状态、静态的
下面列举一些别人描述面向对象的思想
1 ,把一组数据结构和处理它们的方法组成对象(object),把相同的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的特化(specialization) / 泛化 (generalization),通过多态(polymorphism)实现基于对象类型的动态分派(dynamic dispatch)。
2,一种尽量降低后续扩展代码引入 side-effect 可能的代码组织手段
3,封装:把属性值、红蓝条、攻击、走位、放技能、清兵、游走等行为都塞在一个英雄里。
,继承:攻击+10 的装备可以升级到攻击+20,以后还可能升级到攻击+30 并带有吸血效果。不管升级成什么,都携带着攻击+10 这部分属性。
多态:一个团队需要一个辅助,我们只需要一个辅助英雄,并不关心来的是哪个辅助英雄,能加血就行。
具备这三种特性的编程思想,叫做面向对象。