面向对象 - 运作逻辑

Java

如前面所述,Java中一个对象的创建语句为

1
A a = new A();

在该行定义中,A a声明了一个对象的引用a,后面new了一个对象的实例,并将该实例的地址赋值给a,让a指向该对象的实例。

而在执行new A()的过程如下:

  1. 当程序首次主动使用一个类(如创建对象、访问类的静态变量等),jvm会加载这个类。当这个类有父类时,父类先于子类被加载。

    由于除Object类外的所有类都有父类,因此基本所有类都会执行这个操作。

  2. 在验证语法符合规范后,为类的静态变量分配内存,并设置默认初始值(int为0,bool为false,引用型为null)。

    • 静态成员在对象实例化前就分配好内存了,在创建该类的实例时将不再分配空间,所有的实例将共享类的静态变量。

    • 虽然Java中没有全局变量,但这种静态变量在一个类的所有实例对象都可以访问(权限最严格能到这个程度),因此可以充当一部分全局变量的作用。

    • 使用时,直接引用类名即可,不需要引用对象的实例。

    • 由于静态方法的调用不是通过实例对象进行的,所以静态成员不能使用this指针,子类也不能重写父类的静态方法(但可以声明与父类静态方法相同的方法,从而将其 隐藏

    • main()也是一个静态方法,也是程序的入口点。在Java中main函数可以不止一个,只要运行逻辑自洽,一个工程中可以有多个main函数。

    • 可以用static修饰语句块,这类语句块在加载该类时执行且只执行一次。对象中含多个静态初始化程序块时按次序执行。

      1
      2
      3
      static {
      ...
      }
  3. 从父类开始,执行构造方法,给静态变量进行赋值,执行构造器相关操作。其中,子类初始化时为子类分配内存时也包含从父类继承的实例变量和子类自己的实例变量(子类中也包含有一份父类)。

C++

当创建一个派生类的对象时,g++也会先调用基类的构造函数,再调用派生类的构造函数。然而,与C语言类似,静态成员在程序启动时就就已经创建好静态成员变量了。若基类和派生类都定义了同名的静态成员变量,那么在派生类的范围内,会隐藏基类的静态成员变量。


面向对象 - 运作逻辑
http://example.com/2024/04/26/object-oriented-3/
作者
Ivan Chen
发布于
2024年4月26日
许可协议
IVAN