JavaScript面向对象——实现多态

这个是从一个大佬的博客学来的,看了看例子不太难,可能了解的不够透彻。
大佬博客地址
多态

大佬例子:

    function add() {
        var arg = arguments,
            len = arguments.length
        switch (len) {
            case 0:
                return 10
            case 1:
                return 10 + arg[0]
            case 2:
                return arg[0] + arg[1]
        }
    }
    // test
    console.log(add())
    console.log(add(7))
    console.log(add(7, 9))

结果:
在这里插入图片描述

类的形式:

    function Add() {
        function zero() {
            return 10
        }
        function one(num) {
            return 10 + num
        }
        function two(num1, num2) {
            return num1 + num2
        }
        this.add = function () {
            var arg = arguments,
                len = arguments.length
            switch (len) {
                case 0:
                    return zero()
                case 1:
                    return one(arg[0])
                case 2:
                    return two(arg[0], arg[1])
            }
        }
    }
    // test
    var a = new Add()
    console.log(a.add())
    console.log(a.add(7))
    console.log(a.add(7, 9))

结果:
在这里插入图片描述
  面向对象编程中的多态主要是通过抽象类和抽象函数实现的,js中也可以从这两个方面实现多态。传统意义上的多态,是通过派生类继承并实现基类中的抽象(虚)函数来实现的,含有抽象函数的类是抽象类,抽象类是不能够实例化的,同时,抽象函数没有函数体,也不能够直接调用,只能有派生类继承并实现。在高级程序语言中,上述这些检测均在程序编译时进行,不符合要求的程序编译将不通过,但是在js中,有了些许变化:

1. js是解释性语言,不需要进行预编译,所以js中抽象类和抽象函数的使用并没有那么严格的要求。

2. js中可以对未定义的方法进行调用,当然这一过程会报错,而检测时在执行调用时进行的。

所以,js中的抽象类可以定义实例,但就其意义而言,我们可以定义一个空的没有成员的类来代替,同样,js中的抽象函数,我们可以不必在基类中声明,直接进行调用,在派生类中实现即可,当然,也可以通过在基类中定义一个空的抽象方法实现,代码如下:

function ClassA() {
    //抽象类,类的实现过程为空
}
ClassA.prototype = {
    sayColor: function() {
        //直接调用抽象方法
        this.initial();
    },
    //定义一个空的抽象方法由派生类去实现,也可以不定义
    initial: function() { }
}

//ClassA作为基类派生出ClassB
var ClassB = ClassA.extend(function(name) {
    this.name = name;
}, {
    //实现基类中的抽象方法
    initial: function() {
        console.log(this.name);
    }
},
{
    //无静态成员
});

这样的实现与真正意义上的多态相差有点大,可能会让人疑惑这种必要性,为了最大程度的满足严格意义上的多态,我们改写上面的代码如下:

//抽象类
function ClassA() { throw new Error("can't instantiate abstract classes."); }
ClassA.prototype = {
    initial: function() { throw new Error("can't call abstract methods."); }
}

//ClassA作为基类派生出ClassB
var ClassB = ClassA.extend(function(name) {
    this.name = name;
}, {
    //实现基类中的抽象方法
    initial: function() {
        console.log(this.name);
    }
},
{
    //无静态成员
});

为了不让抽象类实例化,我们直接在其构造函数中抛出异常,为了不能直接调用抽象方法,我们也直接在其抽象方法中抛出异常,这样我们就满足了抽象类/方法的严格要求。

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值