用java的眼光看js的oop

前言

都知道javascript的class只是语法糖而已,所以没法去对比,不在一个层次。
但是既然有了,总会有好奇的去对比。
那就对比一下。

面向对象的三个经典特性

封装
继承
多态

封装

指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
java、php、ts等等都是 提供了 3 个访问控制符:private、 protected 和 public ,代表 3 种不同的访问级别,再加上一个默认的访问控制级别,共有 4 个访问控制级别。
但是js尚无这些修饰符,最近也就出了个static吧,但是跟权限没关系。那js如何封装呢。
一般情况下利用ts或者js的闭包来实现

继承

js现在也可以基于类的继承已经可以使用了
不过依然是es5的那套寄生式组合继承而来的语法糖而已
寄生式组合继承

function inheritPrototype(subType, superType) {
  let prototype = object(superType.prototype); // 创建对象
  prototype.constructor = subType; // 增强对象
  subType.prototype = prototype; // 赋值对象
}

function SuperType(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
  console.log(this.name);
};

function SubType(name, age) {
  SuperType.call(this, name);
  this.age = age;
}

inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function () {
  console.log(this.age);
};

es6类继承

// 人类
class Person {
    name = ‘人类‘;
    page = 20;
    say() {
        console.log(‘我是人类‘);
    };
}

// 老师类
class Teacher extends Person {
    name = ‘老师‘;
    tage = 30;
    /**
     * @overwrite
     * 子类重写父类方法
     */
    say() {
        console.log(‘我是老师‘);
    };
}

const tc = new Teacher(); // 我是老师
tc.say(); // 调用的是子类重写果的方法:我是老师
console.log(tc.name); // 调用的是子类自己的实例属性:老师
console.log(tc.tage); // 调用的是子类自己的实例属性:30
console.log(tc.page); // 调用的是继承至父类的实例属性:20
console.log(tc);// 打印结果和寄生式组合继承一样

用java的眼光看js的oop

子类会继承(有可能会重写父类属性或者方法的行为)父类所有的属性和方法
但是如果被重写了,则一切以子类为准。

多态

多态指的是相同类型的变量调用同一个方法时呈现出多种不同的行为特征。
多态的必要条件:继承、重写、向上转型。
拿java举例子

class People{
    public String name = "人类";
    public String page = "20";
    public void getName(){
        System.out.println("People"+this.name);
    }
}

class Teacher extends People{
    public String name = "老师";
    public String sage = "21";
    public void getName(){
        System.out.println("Teacher"+this.name);
    }
}

public class Main {
    public static void main(String[] args) {
        People tc = new Teacher();
        tc.getName();
        System.out.printf(tc.name);
    }
}

通过向上转型,tc可以访问父类People的独有属性、但是不能再访问Teacher类的独有属性。
可以访问被重写的父类方法,但是只能访问被重写过的,不能访问父类的

People tc = new Teacher();
System.out.printf(tc.name); // 老师
System.out.printf(tc.page); // 20
System.out.printf(tc.sage); // 报错 People的实例tc 找不到属性sage
tc.getName(); // Teacher老师

因为js压根没有类型这一说,所以根本无法向上转型。自然而然的 js是不支持多态的。

用java的眼光看js的oop

上一篇:C语言 指针 p++ / p-- - C语言零基础入门教程


下一篇:Factory method 'eurekaClient' threw exception; nested exception is java.lang.RuntimeException: Failed to initialize DiscoveryClient!