(2)Class类的基本使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(2)Class类的基本使用相关的知识,希望对你有一定的参考价值。

参考技术A 于是接下来class内容会按照下面的几个方面来讲解:

这种方法只适用于引用类型:

输出结果如下:

这种方式适用于原生类型和引用类型:

输出结果如下:

只适合在引用类型,需要给出一个全限定的类的名称

输出结果如下:

输出结果如下:

输出结果如下:

输出结果如下:

输出结果如下:这里的输出结果比上面的输出结果多了一个私有的java.lang.Character$CharacterCache内部类

结果如下:

结果为: State为Thread的一个内部类,需要先得到

一个类可以有一个或多个修饰符,这些修饰符会影响运行时的行为,从下面几个方面讲解:

这里引用官方的例子,该类的作用是是实现了类中的修饰符的扫描

输出结果如下:

这里在引用官方的例子:

输出结果如下: 可以发现String 的构造函数重载的有很多, 方法中Methods输出结果中,默认隐式包含了Object对象中的方法 , 如果是接口的话,方法是不会默认继承Object对象,这些Object对象的方法并不会输出 。这些 成员默认继承了Member这个对象 。

构造函数是私有时会抛出InstantiationException

由于class.newInstance(),只能调用public的构造函数,但是Cls类中的构造函数私有化,会导致实例失败
java.lang.reflect.AccessibleObject 提供了一种控制访问检查,Class这个类并没有继承这个类,所以不能正常的工作,解决方法可以使用 Constructor.newInstance() ,Constructor这个对象继承了AccessibleObject这个类,解决方法如下:

Class类的使用和背后实现的原理

在ES6以前,类的声明都是用function构造函数实现的,自ES6开始,可以使用class关键字来创建对象,但是 class只是构造函数定义类的语法糖,内部本质还是构造函数,原型,原型链这一套东西。

类的基本使用

类的创建方法

class关键字创建一个类,和定义function一样,存在声明式和表达式创建

// 方式一:声明式创建
class Person {}

// 方法二:表达式创建
var Student = class {};

类的构造器

在class创建的类中,传递参数用到了构造器 constructor,创建实例时会自动调用这个方法。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

创建类的实例

创建类的实例还是通过new关键字

const person = new Person("fzb", 21);
console.log(person); // Person { name: 'fzb', age: 21 }

constructor内创建对象过程和构造函数一样:

  • 创建一个新的对象
  • 将新对象的隐式原型赋值为类的原型(显示原型)
  • 修改内部this指向
  • 执行constructor内的代码
  • 返回创建的对象

定义类的方法

实例方法

实例方法是放在类的原型上的

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sleepping() {
    console.log(this.name + " 在睡觉~");
  }
}

const person = new Person("fzb", 21);
person.sleepping(); // fzb 在睡觉~
console.log(Object.getOwnPropertyDescriptors(Person.prototype));

访问器方法

访问器方法是放在类的原型上的

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  set _age(newAge) {
    this.age = newAge;
  }
  get _age() {
    return this.age;
  }
}

const person = new Person("fzb", 21);

person._age = 22;
console.log(person._age);
console.log(Object.getOwnPropertyDescriptors(Person.prototype));

静态方法

静态方法是在类的隐式原型上的,通过静态方法可以通过类名.函数名的方式调用类的方法。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  static createPerson() {
    return new Person("fzb", 21);
  }
}

const person = Person.createPerson();
console.log(person);
console.log(Object.getOwnPropertyDescriptors(Person.__proto__));

类的继承

使用extends关键字,可以继承父类的代码和方法,同时可以对父类内的方法进行重写,使用。

在子类构造器类内使用this和返回默认对象之前,必须使用super调用父类构造器!不然会报错

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  eatting() {
    console.log(this.name + " 在吃饭~");
  }
  sleepping() {
    console.log(this.name + " 在睡觉~");
  }
}

class Student extends Person {
  constructor(sno, name, age) {
    super(name, age);
    this.sno = sno;
  }
  sleepping() {
    super.sleepping();
    console.log("----------------------");
  }
}

const student = new Student(2021, "fzb", 21);
// 调用父类内的方法,也是可以使用父类内的静态方法的
student.eatting(); // fzb 在吃饭~

// 重新父类的方法,并且通过super关键字复用父类对应代码
student.sleepping();
// fzb 在睡觉~
// ----------------------

类的深度解析

通过babel转换,看语法糖class内部是如何用原型,原型链实现的。

上方代码经过babel转换后是这样的

"use strict";

function _typeof(obj) {
  "@babel/helpers - typeof";
  if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
    _typeof = function _typeof(obj) {
      return typeof obj;
    };
  } else {
    _typeof = function _typeof(obj) {
      return obj &&
        typeof Symbol === "function" &&
        obj.constructor === Symbol &&
        obj !== Symbol.prototype
        ? "symbol"
        : typeof obj;
    };
  }
  return _typeof(obj);
}

function _get(target, property, receiver) {
  if (typeof Reflect !== "undefined" && Reflect.get) {
    _get = Reflect.get;
  } else {
    _get = function _get(target, property, receiver) {
      var base = _superPropBase(target, property);
      if (!base) return;
      var desc = Object.getOwnPropertyDescriptor(base, property);
      if (desc.get) {
        return desc.get.call(receiver);
      }
      return desc.value;
    };
  }
  return _get(target, property, receiver || target);
}

function _superPropBase(object, property) {
  while (!Object.prototype.hasOwnProperty.call(object, property)) {
    object = _getPrototypeOf(object);
    if (object === null) break;
  }
  return object;
}

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  // 和 寄生组合式继承思想一样,创建一个新的,新对象的隐式原型执行父类的原型对象,=
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: { value: subClass, writable: true, configurable: true },
  });
  // 子类的隐式原型指向父类,实现静态方法继承
  if (superClass) _setPrototypeOf(subClass, superClass);
}

// 相当于 o.__proto__ = p 实际为例静态实例继承
function _setPrototypeOf(o, p) {
  _setPrototypeOf =
    Object.setPrototypeOf ||
    function _setPrototypeOf(o, p) {
      o.__proto__ = p;
      return o;
    };
  return _setPrototypeOf(o, p);
}

// Derived:Student子类
function _createSuper(Derived) {
  var hasNativeReflectConstruct = _isNativeReflectConstruct();
  return function _createSuperInternal() {
    // 获取Student.__proto__,然而此时的Student.__proto__ = Person
    var Super = _getPrototypeOf(Derived),
      result;
    if (hasNativeReflectConstruct) {
      // this其实在执行时是子类实例,NewTarget = Student
      var NewTarget = _getPrototypeOf(this).constructor;
      result = Reflect.construct(Super, arguments, NewTarget);
      // Super类的实例的__proto__指向NewTarget,并将这个实例返回
    } else {
      result = Super.apply(this, arguments);
    }
    return _possibleConstructorReturn(this, result);
  };
}

function _possibleConstructorReturn(self, call) {
  if (call && (_typeof(call) === "object" || typeof call === "function")) {
    return call;
  } else if (call !== void 0) {
    throw new TypeError(
      "Derived constructors may only return object or undefined"
    );
  }
  return _assertThisInitialized(self);
}

function _assertThisInitialized(self) {
  if (self === void 0) {
    throw new ReferenceError(
      "this hasn't been initialised - super() hasn't been called"
    );
  }
  return self;
}

function _isNativeReflectConstruct() {
  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  if (Reflect.construct.sham) return false;
  if (typeof Proxy === "function") return true;
  try {
    Boolean.prototype.valueOf.call(
      Reflect.construct(Boolean, [], function () {})
    );
    return true;
  } catch (e) {
    return false;
  }
}

// 获取对象的o.__proto__
function _getPrototypeOf(o) {
  _getPrototypeOf = Object.setPrototypeOf
    ? Object.getPrototypeOf
    : function _getPrototypeOf(o) {
        return o.__proto__ || Object.getPrototypeOf(o);
      };
  return _getPrototypeOf(o);
}

// 判断构造函数的调用方式,如果不是通过new调用的方式,就报错
function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

// 将props传过来的属性数组,通过描述符加入的 target
function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

// 对类里边的方法进行出合理
function _createClass(Constructor, protoProps, staticProps) {
  // 实例函数 将实例函数加入到原型对象上
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  // 静态函数加入到对象本身
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}
// Person父类,使用了一个自执行函数,clas本质上还是童通过构造函数实现
var Person = /*#__PURE__*/ (function () {
  function Person(name, age) {
    _classCallCheck(this, Person);
    this.name = name;
    this.age = age;
  }
  // 处理内中的方法
  _createClass(Person, [
    {
      key: "eatting",
      value: function eatting() {
        console.log(this.name + " 在吃饭~");
      },
    },
    {
      key: "sleepping",
      value: function sleepping() {
        console.log(this.name + " 在睡觉~");
      },
    },
  ]);

  return Person;
})();

// Student子类,使用了一个自执行函数
var Student = /*#__PURE__*/ (function (_Person) {
  _inherits(Student, _Person);

  var _super = _createSuper(Student);

  function Student(sno, name, age) {
    var _this;

    _classCallCheck(this, Student);
    // 获取返回的创建的实例,实际上这个实例是 Person创建出来的,但是改变的this指向
    _this = _super.call(this, name, age);
    _this.sno = sno;
    return _this;
  }
  // 处理内中的方法
  _createClass(Student, [
    {
      key: "sleepping",
      value: function sleepping() {
        _get(_getPrototypeOf(Student.prototype), "sleepping", this).call(this);

        console.log("----------------------");
      },
    },
  ]);

  return Student;
})(Person);

以上是关于(2)Class类的基本使用的主要内容,如果未能解决你的问题,请参考以下文章

类的基本形式2(有this关键字的使用)

python-类的基本使用

python-类的基本使用

class的基本使用

Complex 类的基本函数

synchronized 基本用法