类与对象

  • 类是抽象的,是一种泛指。
  • 对象是具体的,是一个特指。
  • 类是对象的模板,对象是类的一个个体,对应一个实例。

    对象在内存中的存在形式

    image.png
    执行创建对象时,会先加载类的信息(如:属性,方法信息)
    在内存中,引用类型会存放在方法区的常量池中,只在堆中存放一个地址;而基本数据类型存放在堆中。

    关于常量池

    在JDK1.6及之前 运行时常量池逻辑包含字符串常量池存放在方法区(位于堆内存中)。
    在JDK1.7 字符串常量池被从方法区拿到了堆中, 字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区。
    在JDK1.8 不变,只不过方法区的实现从永久代变成了元空间(堆外内存)。

    属性/成员变量/字段

  • 理解上可等价,个人习惯叫属性。

  • 属性是类的组成部分,类型任意。
  • 定义方法同变量,但多了权限修饰符等。
  • 有默认值(隐式赋值),规则同数组。

    成员方法

  • 即方法,是完成某种功能的一段代码块。

  • 可提高代码复用,封装细节提供调用。
  • 由访问权限、返回类型、方法名、参数、方法体等构成。
  • 返回值非必须,否则只能有一个,且类型要与声明时保持一致。
  • 没有访问修饰符则为默认。

    1. public [static] void/类型 print(String str){
    2. ...;
    3. //return 返回值;
    4. }

    方法的调用机制原理

    image.png

    使用方法

  • 方法参数要保持一致。

  • 同类中可以直接使用方法名调用。
  • 跨类调用:static 修饰,则直接 类名.方法名否则需要创建对象 对象名.方法名

    方法传参机制

    Java 是值传递而非引用传递,基本数据类型传递的是值(即实参的副本),形参的改变不影响实参。
    表面上看,引用类型传递的是引用,对实参进行操作时(如数组内容的修改)会影响到实参。但若是进行赋值操作(如新数组赋值实参数组),此时不会影响到实参。引用本质上是地址,是一个值。

    方法递归调用

    简单来说,就是方法自己调用自己。
    image.png
    image.png

    创建对象

  • 先声明再创建

    1. A a;
    2. A = new A();
  • 直接创建

    1. A a = new A();

    类和对象的内存分配机制

  • 栈: 一般存放基本数据类型(局部变量)

  • 堆: 存放对象(Cat cat , 数组等)
  • 方法区:常量池(常量,比如字符串), 类加载信息

    创建对象的流程分析

  1. 先加载类信息(属性和方法信息),且只加载一次。
  2. 堆中分配空间,进行默认初始胡
  3. 把地址赋给对象变量,此时该对象变量指向对象。
  4. 进行指定初始化(get/set)

    关于 new

    使用 new 关键字是在堆中开辟空间。

    关于 this

  • this 关键字可以用来访问并区分本类的属性、方法、构造器。都是this.属性/方法/构造器
  • 只能在构造器中访问另外一个构造器,且必须放在第一条语句。
  • this 不能在类定义的外部使用,只能在类定义的方法中使用。

    构造方法/构造器

    创建对象时,系统自动调用构造器,完成新对象初始化,可以给对象指定一些值,本质是一个方法,可重载。
    构造器与类同名,权限修饰符可以是四种之一,没有返回值 。调用由系统完成。
    若没有定义构造器,系统会自动生成一个无参构造(也叫默认构造器)。一旦定义了自己的构造器,除非再显式定义,否则无法使用无参构造。

    方法重载(Overload)

    同类中,存在多个同名不同参(类型、个数)的方法。(返回类型无要求)

    可变参数

    同类中,同名同功能,但参数个数不同的方法,通过可变参数实现。
    只需将参数列表修改为 参数类型... 形参名形参当作一个数组使用
    1. public int sum(int... nums){
    2. int numsSum = 0;
    3. for(int temp : nums){
    4. numsSum += temp;
    5. }
    6. return numsSum;
    7. }
    image.png

    作用域

    image.png
    image.png