• 用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);// 打印结果和寄生式组合继承一样
    

    image

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

    多态

    多态指的是相同类型的变量调用同一个方法时呈现出多种不同的行为特征。
    多态的必要条件:继承、重写、向上转型。
    拿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是不支持多态的。

  • 相关阅读:
    介绍 Jersey 依赖
    Jersey 2.x 分支 Java SE 兼容性
    Confluence 6 管理 Atlassian 提供的 App
    Confluence 6 针对站点维护使用只读模式
    Confluence 6 协同编辑问题解决
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
  • 原文地址:https://www.cnblogs.com/dshvv/p/15179738.html
Copyright © 2020-2023  润新知