用Javascript实现面向对象编程(封装,抽象,继承,多态)

用Javascript实现面向对象编程(封装,抽象,继承,多态)

OO的特点:封装、抽象、继承、多态

封装:在 面向对象语言中,封装特性是由类来体现的,我们将现实生活中的一类实体定义成类,其中包括属性和行为(在Java中就是方法),就好像人类,可以具有 name,sex,age等属性,同时也具有eat(),sleep()等行为,我们在行为中实现一定的功能,也可操作属性,这是面向对象的封装特性;

封装在js中很容易实现:

function Man() {
this.name = "";
this.age = 18;
this.work = function() {
//coding();
}
}
var mzhou = new Man();
mzhou.name = "mzhou";
mzhou.age = 23;
以上代码用Man类封装了人这一现实生活中的一类实体。

继承:继承就像是我们现实生活中的父子关系,儿子可以遗传父亲的一些特性,在面向对象语言中,就是一个类可以继承另一个类的一些特性,从而可以代码重用,其实继承体现的是is-a关系,父类同子类在本质上还是一类实体;

function Father() {
    this.name = "father";
}
function Son() {
    this.age = 18;
}
Son.prototype = new Father();
var son = new Son();
console.log(son.name);//father
son.name = "son";
console.log(son.name);//son

javascript中类的实现

prototype创建自定义对象的例子:

// 构造函数
   function Person(name, sex) {
       this.name = name;
       this.sex = sex;
   }
// 定义Person的原型,原型中的属性可以被自定义对象引用
   Person.prototype = {
       getName: function() {
           return this.name;
       },
       getSex: function() {
           return this.sex;
       }
   }

 把函数Person称为构造函数,也就是创建自定义对象的函数。可以看出,JavaScript通过构造函数和原型的方式模拟实现了类的功能。

 创建自定义对象(实例化类)的代码:

1
2
3
4
var zhang = new Person("ZhangSan", "man");
console.log(zhang.getName()); // "ZhangSan"
var chun = new Person("ChunHua", "woman");
console.log(chun.getName()); // "ChunHua"

当代码var zhang = new Person("ZhangSan", "man")执行时,其实内部做了如下几件事情:

  • 创建一个空白对象(new Object())。
  • 拷贝Person.prototype中的属性(键值对)到这个空对象中(我们前面提到,内部实现时不是拷贝而是一个隐藏的链接)。
  • 将这个对象通过this关键字传递到构造函数中并执行构造函数。
  • 将这个对象赋值给变量zhang。

为了证明prototype模版并不是被拷贝到实例化的对象中,而是一种链接的方式,请看如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
function Person(name, sex) {
    this.name = name;
    this.sex = sex;
}
Person.prototype.age = 20;
var zhang = new Person("ZhangSan", "man");
console.log(zhang.age); // 20
// 覆盖prototype中的age属性
zhang.age = 19;
console.log(zhang.age); // 19
delete zhang.age;
// 在删除实例属性age后,此属性值又从prototype中获取
console.log(zhang.age); // 20

这种在JavaScript内部实现的隐藏的prototype链接,是JavaScript赖以生存的温润土壤, 也是模拟实现继承的基础。

多态:多态就是通过传递给父类对象引用不同的子类对象从而表现出不同的行为,多态可为程序提供更好的可扩展性,同样也可以代码重用。因为js是弱类型语言,所以不能实现多态

//Shape是Triangle的父类
public static void main(String[] args){
     Triangle tri = new Triangle();
     System.out.println("Triangle is a type of shape? " + tri.isShape());// 继承
     Shape shape = new Triangle();
     System.out.println("My shape has " + shape.getSides() + " sides."); // 多态
     Rectangle Rec = new Rectangle();
     Shape shape2 = Rec;
     System.out.println("My shape has " + shape2.getSides(Rec) + " sides."); //重载
}

抽象:抽象就是将一类实体的共同特性抽象出来,封装在一个抽象类中,所以抽象在面向对象语言是由抽象类来体现的。比如鸟就是一个抽象实体,因为抽象实体并不是一个真正的对象,它的属性还不能完全描述一个对象,所以在语言中体现为抽象类不能实例化;