JavaScript(JS) 面向对象(封装、继承、多态)

面向对象是把事物给对象化,包括其属性和行为。面向对象编程更贴近实际生活的思想。可以简单的理解面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象。本文主要介绍JavaScript(JS)中实现面向对象(封装、继承、多态)。

1、封装

隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。

JavaScript(JS)中ES6之前没有类的概念,封装定义类相当于定义函数,写法如下:

function Person (name,age,sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
}
Pserson.prototype = {
    constructor:Person,
    sayHello:function(){
        console.log('hello');
    }
}

ES6中引入 class(类)这个概念,写法如下:

//定义类
class Person{
  // 类的静态方法,相当于Person.test = function(){console.log("类的静态方法");}
  static test() {
    console.log("类的静态方法");
  }
  //constructor构造函数
  constructor(name,age){
    console.log("调用构造函数");
    this.name = name;
    this.age = age;
  }
  //类的一般方法,定义在实例对象的原型对象上,相当于Person.prototype.show = function(){console.log("this.name,this.age");}
  show(){
    console.log(this.name,this.age);
  }
}

2、继承

提高代码复用性;继承是多态的前提。JavaScript(JS)中ES6之前继承是通过prototype(原型)实现,使父类中的属性和方法在子类实例的prototype原型链上,不同于其他语言中的继承(其他语言的继承一般是继承拷贝,也就是子类继承父类,会把父类中的属性和方法拷贝一份到子类,供子类的实例调取使用),JavaScript(JS)中把父类的原型放到子类实例的原型链上的,实例想调取这些方法,是基于__proto__原型链查找机制完成的。子类可以重写父类上的方法。但父类其他的实例也受到影响。父类中私有或者共有的属性方法都会变成子类的共有属性和方法

prototype__proto__的区别:prototype是函数才有的属性,而__proto__是每个对象都有的属性。

写法如下:

//父类
function A(x) {
    this.x=x
}
A.prototype.getX=function(){
    console.log(this.x)
}
//子类
function B(x) {
    this.y=y
}
//B的原型指向A的实例
B.prototype=new A()
B.prototype.constructor=B
B.prototype.getY = function(){
    console.log(this.y)
}
let b1=new B(100)
console.log(b1.y)//100
b1.getX()//undefined
b1.getY()//100

ES6中可以使用extend(extends和super)实现继承,写法如下:

//es6中继承
class A {
    constructor(x){
        this.x=x
    }
    getX(){
        console.log(this.x)
    }
}
class B extends A {
    //子类只要继承父类,可以不写constructor,如写了就需要使用super调用指定的父类的构造函数。
    //不写constructor 浏览器会自动默认创建constructor(...arg){}
    constructor(y) {
        //把父类当做普通方法执行,给方法传递参数,让方法中的this是子类的实例
        super()
        this.y=y
    }
    getY(){
        console.log(y)
    }
}

3、多态

父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。JavaScript(JS)中ES6之前多态用法如下:

var makeSound = function(animal) {
    animal.sound();
}
var Duck = function(){}
Duck.prototype.sound = function() {
    console.log('duck')
}
var Chicken = function() {};
Chicken.prototype.sound = function() {
    console.log('chicken')
}
makeSound(new Chicken());
makeSound(new Duck());

ES6中多态写法如下:

class Animal{
        eat(){
            throw '"' + this.constructor.name + "'类没有eat()方法";
        }
    }
    class Snake extends Animal{}
    class Dog extends Animal{
        eat(){
            console.log("dog eat");
        }
    }
    class Cat extends Animal{
        eat(){
            console.log("cat eat");
        }
}
var makeEat=function(animal){
  animal.eat();
}
makeEat(new Snake());
makeEat(new Dog());
makeEat(new Cat());

推荐阅读
cjavapy编程之路首页