面向对象(二)—内存管理、继承、访问控制、关键字

97 阅读5分钟

1、内存管理

JVM来管理

1.1 堆

  1. 用于存储所有**new**出来的对象(包括成员变量)

  2. **成员变量**的生命周期

    创建 (new) 对象时存在堆中,对象被GC回收时一并消失

  3. 垃圾:没有任何引用所指向的对象

    垃圾回收器(GC)

    GC会不定时到堆中查看,看到垃圾则自动回收

    回收过程是透明的,并不是一看到垃圾就马上回收,

    若想让它回收的快一些(不是调用了就立即回收),可以调用**System.gc( )**

  4. 内存泄漏:不再使用的对象没有被及时的回收

1.2 栈

  1. 用于存储正在调用中方法的所有局部变量

  2. 调用方法时在栈中为该方法分配一块对应的**栈帧**,

    栈帧中包含所有的局部变量(包括参数),方法调用结束时,栈帧消失,局部变量一并消失

  3. 局部变量的生命周期:

    调用方法时存在栈中,方法调用结束时与栈帧一并消失

1.3 方法区

  1. 用于存储 .class字节码文件(包括方法)
  2. 方法只有一份,通过this来区分具体是那个引用

1.4 成员变量与局部变量的对比

  • 成员变量

    位置:类中,方法外

    生命周期:new时存在堆中,对象被回收时消失

    有默认值

  • 局部变量

    位置:方法中

    生命周期:调方法时存在栈中,方法调用结束时与栈帧一并消失

    没有默认值


2、继承

  1. 目的:避免代码重复,有利于代码的重用

  2. 通过**extends**实现继承

  3. 父类:所有子类所共有的属性和行为

    子类:子类所特有的属性和行为

  4. 子类继承父类后,子类具有: 子类+父类

  5. 一个父类可以有多个子类

    一个子类只能有一个父类(单一继承)

  6. 继承具有传递性

  7. java规定:构造子类之前必须先构造父类

    子类构造中若没有调用父类的构造,则默认使用**super()** 来调父类的无参构造

    若自己调了,则不再默认提供

    super() 调用父类构造,必须位于子类构造的第一句


3、super

  • 指代当前对象的父类对象

用法:

super.成员变量名——访问父类的成员变量

super.方法名——调用父类的方法

super() ——调用父类的构造方法


4、向上造型

  1. **父类型的引用**指向子类的对象
  2. 能点出来什么,看引用的类型

5、重写与重载

  • 方法的**重写**(override)

    1. 发生在父子类中,方法名相同,参数列表相同,方法体不同
    2. 重写方法被调时,看对象的类型
  • **重写重载**的区别

    1. 重写

      父子类中,方法名相同,参数列表相同,方法体不同

      遵循“运行期”绑定,根据对象的类型调用方法

    2. 重载

      一个类中,方法名相同,参数列表不同,方法体不同

      遵循“编译期”绑定,根据引用的类型绑定方法

  • 重写看对象,重载看引用


6、关键字和修饰词

6.1 package和import

  • package

    1. 作用:避免类的命名冲突
    2. 包名可以有层次结构
    3. 建议:包名所有字母都小写
    4. 类的完全限定名:包名.类名
  • import

    1. 作用:声明类/引入类

    2. 同包中的类可以直接访问

      不同包中的类想访问

      1. 先import声明类再访问(建议)
      2. 类的全称—太繁琐(不建议)

6.2 访问控制修饰符

  • public:公开的

    任何类可以访问

  • private:私有的

    本类可以访问

  • protected:受保护的

    本类、子类、同包类可以访问

  • 默认的:什么也不写

    本类、同包类可以访问

类的访问修饰:public默认的

类成员的访问修饰:四种都可以


6.3 成员变量

  • 实例变量:

    1. 属于对象的,存在堆中
    2. 有几个对象就有几份实例变量
    3. 必须通过**对象名.** 来访问
  • 静态变量:

    1. 属于类的,存在方法区中
    2. 只有一份
    3. 常常通过**类名.** 来访问

6.4 static

静态的

  • 静态变量

    1. static修饰
    2. 属于类的,存在方法区中,只有一份
    3. 常常通过**类名.** 来访问
    4. 何时用:所有对象的数据都一样时使用,只有一份

  • 静态方法

    1. static修饰
    2. 属于类的,存在方法区中,只有一份
    3. 常常通过**类名.** 来访问
    4. 没有隐式的this传递

    静态方法中不能直接访问实例成员

    1. 何时用:方法的操作仅与参数相关而与对象无关时使用
  • 静态块

    1. static修饰
    2. 属于类的,类被加载期间自动执行

    类只被加载一次,所以静态块也只执行一次

    1. 何时用:常常用于加载静态资源(图片、音频、视频....)

6.5 final

不能变的

  • 修饰变量:变量不能被改变
  • 修饰方法:方法不能被重写
  • 修饰类:类不能被继承

6.5 static final 常量

  1. 必须声明同时初始化
  2. 通过**类名.** 来访问,不能改变
  3. 建议:常量名所有字母都大写
  4. 在编译时会自动替换为具体的值,效率高