zoukankan      html  css  js  c++  java
  • 用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是不支持多态的。

  • 相关阅读:
    关于32位操作系统和64位操作系统对InstallShield打包的影响
    NEWS: Symantec宣布Wise Package Studio将终止
    InstallShield 2012新功能试用(2) 调用MsiGetProperty等MSI API发生变化
    Basic INFO 在命令行Build InstallShield安装包工程获得压缩安装包
    NEWS InstallShield 2012 Service Pack 1发布
    Basic INFO InstallShield Basic MSI工程中如何在SetupCompleteSuccess界面中启动Readme
    Basic INFO InstallShield的脚本编辑器中如何显示代码行号
    Basic INFO 关于在InstallShield制作的安装包界面中删除InstallShield文字的厂商回复
    Basic INFO InstallShield工程中如何让产品的快捷方式名称始终与产品名保持一致
    Basic INFO: 创建隐藏文件夹
  • 原文地址:https://www.cnblogs.com/dshvv/p/15179738.html
Copyright © 2011-2022 走看看