类方法 & 实例方法
1 2 3 4 5 6 7 8 9
| 类方法:(静态方法) static修饰、可以通过类名直接访问、 实例方法: 无static修饰、必须通过创建的实例才能访问
类变量和实例变量同理
实例方法可以直接访问实例变量 ? 因为在实例方法中、有一个隐含的参数(当前操作的对象本身) 1. 类方法只能调用类方法、访问类变量, 不能访问实例方法和实例变量 2. 实例方法可以访问类方法、类变量、实例方法、实例变量
|
可以将类看成自定义数据类型
Note
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1. 定义一个类本身、什么都不会做、不会分配内存、也不会执行代码 2. 声明变量本身只分配存放位置的内存空间、这块空间还未指向任何实际内容 3. p = new Point(); 1) 分配内存、以存储新对象的数据(这个对象的属性、包括实例变量x|y) 2) 给实例变量设置默认值、int->0 boolean->false char->\u000 refer->null
4. 修改变量默认值 1) 定义的同时、初始化 private int x = 1; 2) 初始化代码块 private int y; {y=2} 3) 构造方法 调用顺序 1) -> 2) -> 3) 所以、若多种方式定义了默认值、前边的会被后边的覆盖
5. final修饰类变量、实例变量、表示变量只能被赋值一次、final也可以修饰实例方法
|
类和对象的生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 1. 程序运行时、第一次通过new创建一个类的对象的时候、or 直接通过类名访问类变量/类方法的时候、 Java会讲类加载进内场、为这个类分配一块空间、保护类的定义、有哪些变量和方法、 还有类的静态变量、并对静态变量赋初值 类加载进内存后一般不会释放、直到程序结束、一般情况下、只加载一次(静态变量在内存中只存在一份) 2. 对象 每次new、都会产生一个新的实例、会有一份独立的实例变量 每个对象除了保存实例变量的值、还保存着对应类的地址、即: 通过对象可以知道类、就能访问到类的变量和方法 实例方法可以理解为多了this参数的静态方法 对象的释放是被Java的垃圾回收机制管理的 a. 保存地址的部分分配在桟上、函数调用入栈就分配、出栈就释放 b. 保存内容的部分分配在堆上、无活跃变量指向对象的时候(已加载的类的类变量和桟中所有的变量)、 就可能被释放
|
类继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 1. java 使用extends表明继承关系、一个类只有一个父类 2. 子类不可访问父类的私有属性和方法、可以访问 protected 和 public 的
3. 向上转型: 子类对象赋值给父类引用变量(转换为父类类型)、
4. 多态: 变量shape可以引用任何Shape子类类型的对象、即一种类型的变量、可以引用多种实际类型对象 变量shape有两种类型、类型Shape: 称为shape的静态类型、circle/line/arrowLine 称为shape的动态类型 5. 动态绑定: shapes[i].draw() 调用的是其对应动态类型的draw方法、称为方法的动态绑定
6. 若父类只有一个带参数的构造方法、则所有子类都必须通过super调用base的带参构造
7. 若父类构造方法调用了可被重写的方法、可能会出现意想不到的结果
8. 静态绑定: 在类的内部、访问的是当前类 在类的外部、要看如何访问、静态类型是父类、则访问的是父类
9. 静态变量和方法、一般通过类名直接访问、也可以通过实例对象来访问
10. 在有多个重名函数的时候、首先按照参数类型进行匹配、然后才看变量的动态类型、进行动态绑定
11. 模板方法: 在父类定义一个实现的模板、具体实现由子类提供
12. 子类可以升级父类的可见性、不可降低
|
类加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 在Java中、类的加载时将类的相关信息加载到内存、Java是动态加载的、第一次使用时才会加载 加载一个类时、会查看其父类是否已加载、若没有、会加载其父类
类初始化代码: 1. 定义静态变量时的赋值语句 2. 静态初始化代码块
实例初始化代码: 1. 定义实例变量时的赋值语句 2. 实例初始化代码块 3. 构造方法
类加载过程: 1. 分配内存保存类的信息 2. 给类变量赋默认值 3. 加载父类 4. 设置父子关系 5. 执行类初始化代码(先执行父类 -> 子类、不过父类执行时、子类静态变量是有值的、默认值)
内存分为堆(存放动态分配的对象)和桟(存放函数的局部变量)、还有一个内存区: 方法区(存放类的信息)
创建对象: 1. 分配内存 包括本类和父类的所有实例变量、但不包括任何静态变量 实例化代码从父类开始、再执行子类 但: 在任何类执行初始化代码之前、所有的实例变量都已设置完默认值 2. 对所有的实例变量赋默认值 3. 执行实例初始化代码
**Note** 每个对象除了保存类的实例变量之外、还保存着实际类信息的引用
|
虚方法表
1 2
| 在类加载的时候、为每个类创建一个表、包括类的对象所有动态绑定的方法及地址、包括父类的方法 但同一个方法只有一条记录、子类重写之后就只会保留子类的
|
疑问:
1 2 3 4 5 6 7 8
| Q. 实例变量的初始化是在new的时候进行的、类变量的初始化呢 ?(MyNumber.class) A. Java对静态类的初始化 1) 为类里边的静态变量分配内存空间、并赋初值 2) 按照初始化的代码顺序对类变量进行初始化 Q: 父子类、同名静态变量在内存中如何保存 ? 同名实例变量呢 ? A: 对于子类来说、会保存两份、静态类型是哪个的时候、访问的就是哪个
|
参考:
https://mp.weixin.qq.com/s/u_WmkE5meMWuZ81G5gHhBQ
代码整理:
https://github.com/niujing1/javaLearn/tree/master