Skip to main content

[Java] java基础概念(中)

数组的内存图

neicun

duizhan

putong

tip

这个程序没有用到new关键字, 所以现在只看栈

程序在刚开始运行的时候, 程序主入口main方法进入栈里面, 然后从第一行开始逐行执行, 比如第一行定义a等于10,

shuzuneicun

方法

方法是程序中最小的执行单元

方法的注意事项

  • 方法不调用就不执行
  • 方法与方法之间是平级关系, 不能互相嵌套定义
  • 方法的编写顺序和执行顺序无关
  • 方法的返回值类型为void, 表示该方法没有返回值, 没有返回值的方法可以省略return语句不写. 如果要编写return, 后面不能跟具体的数据
  • return语句下面, 不能编写代码, 因为永远执行不到, 属于无效的代码

方法的重载

chongzai

  • 在同一个类中, 定义了多个同名的方法, 这些同名的方法具有同种的功能
  • 每个方法具有不同的参数类型或参数个数, 这些同名的方法, 就构成了重载关系

简单记:

在同一个类中, 方法名相同, 参数不同的方法. 与返回值无关. 参数不同: 个数不同, 类型不同, 顺序不同

方法的内存

fangfa

--------------------

面向对象

面向对象和面向过程的思想对比

  • 面向: 拿, 找

  • 对象: 能干活的东西

  • 面向对象编程: 拿东西过来做对应的事情

面向过程思想(Procedure Oriented Programming) 是一种以过程为中心的编程思想, 实现功能的每一步, 都是自己实现的

面向对象编程(Object Oriented Programming) 是一种以对象为中心的编程思想, 通过指挥对象实现具体的功能

  1. 客观存在的任何一种事物, 都可以看做为程序中的对象
  2. 使用面向对象思想可以将复杂的问题简单化
  3. 将我们从执行者的位置, 变成了指挥者

lizi

设计对象并使用

类和对象

  • 类(设计图): 是对象共同特征的描述;
  • 对象: 是真实存在的具体东西
tip

在java中, 必须先设计类, 才能获得对象

dingyi

duijie

定义类的补充事项

  • 用来描述一类事物的类, 叫做javabean类. 在javabean类, 是不写main方法的
  • 在以前, 编写main方法的类, 叫做测试类. 我们可以在测试类中创建javabean类的对象并进行赋值调用

javabean

  • 一个java文件中可以定义多个class类, 且只能一个类是public修饰, 而且public修饰的类名必须成为代码文件名. 实际开发中建议还是一个文件定义一个class类
  • 成员变量的完整定义格式是: 修饰符 数据类型 变量名 = 初始化值;, 一般无需指定初始化值, 存在默认值

对象的成员变量的默认值规则

morenzhi

面向对象三大特征

封装

继承

多态

--------------------------------

封装详解

如果在需求当中如果存在多个事物, 有的行为不知道该归属哪一类, 怎么办呢?

封装: 告诉我们, 如何正确设计对象的属性和方法

举例:

juli

上面这个设计非常简单, 可是工作中的需求远比这复杂的多. 经常会涉及多个对象, 比如下面的人画圆

circle

很多人会认为人画圆当然draw方法是人身上的, 但是更应该属于圆的方法.

因为封装中一个重要思想: 对象代表什么, 就得封装对应的数据, 并提供数据对应的行为

如何理解这句话:

既然定义了一个类来代表圆的话, 肯定涉及一些圆的属性来封装一些信息, 比如圆的半径, 直径等等.

那么画圆要根据什么画? 肯定需要半径来画, 那上面封装了半径的信息, 就要提供和半径相关的画圆的方法, 所以画圆的方法是属于圆的.

banjing

而人只是调用圆里的方法画的圆.

再举一个例子: 人关门

关门方法是门的方法, 而不是人的方法(联想弹窗开启关闭事件)

kaimen

总结

  1. 什么是封装?
  • 告诉我们, 如何正确设计对象的属性和方法

  • 原则: 对象代表什么, 就得封装对应的数据, 并提供数据对应的行为

private

private

如果此时age赋值负18, 代码不报错但是不符合正常逻辑, 如何解决这个问题?

使用private修饰符

  • 是一个权限修饰符, 可以修饰成员(成员变量和成员方法)

  • private修饰的成员只能在本类中才能访问

pri

此时解决了数据安全问题, 但是又一个新问题出现, 我现在即使赋值正确的值也会报错.

那么如何解决? 如果用if判断可不可以, 像下图

if

但是如果有很多变量, 每一次赋值都要判断这样太繁琐. 还有一个原因, GirlFriend里面封装了女朋友的属性, 那么校验属性的方法按照封装的思想也应该放在GirlFriend类里面, 所以使用if方案是不可行的.

pub

所有属性还是加上private私有关键字, 不让外界直接访问, 与此同时, 每个属性提供一个由public修饰的get和set方法

这个public修饰表示外界可以使用和访问

成员变量和局部变量

如果变量定义在方法里, 就叫做局部变量

如果定义在方法外, 就叫做成员变量

bian

  1. 就近原则

前面没有this的age, 会先到局部位置去找age, 如果局部位置有就使用局部变量, 如果局部位置没有就还到成员位置去找

而this.age就不会到局部位置去找, 而是直接使用成员位置的age

  1. this关键字的作用

可以区别成员变量和局部变量

this

构造方法

构造方法也叫做构造器, 构造函数

作用: 在创建对象的时候给成员变量进行赋值(初始化)的

gouzao

总结

gouzong

标准javaBean类

jb

对象内存图

每一款软件在运行时都会占用一块内存区域, java也不例外, 运行的时候虚拟机也会占用一块内存空间, 并且为了更好的利用这块内存空间, JVM把这块空间分成了5个部分

part

方法区

方法区本身有很多作用和功能, 其中当我们要运行一个类的时候, 这个类的字节码文件就会被加载到方法区中临时存储. 在jdk7以前, 方法区和堆空间是连在一起的, 在真实的物理空间中也是一片连续的空间. 在jdk8开始, 取消了方法区, 新增了一块叫做元空间的区域. 把它跟堆空间分开了, 把原来的方法区要做的很多的事情就进行了拆分, 有的归属到了堆当中, 有的归属到了元空间中, 而加载字节码文件的功能在jdk8以后就归属元空间了.

一个对象的内存图

当我们在创建对象的时候, 内存里至少做以下7件事

  1. 加载class文件
  • 也就是Student这个类的字节码文件加载到内存
  1. 申明局部变量
  • 也就是对等号左边的s进行申明
  1. 在堆内存中开辟一个空间
  • 说的就是等号右边, 有一个new关键字, 所以在内存中开辟一个空间, 这个空间也是我们平时所说的对象
  1. 默认初始化
  2. 显示初始化
  3. 构造方法初始化
  • 4,5,6三步都是对第3步中的变量来进行赋值的.
  1. 将堆内存中的地址值赋值给左边的局部变量

首先, 程序从main方法开始执行, 第一步把TestStudent这个类的字节码文件先加载到方法区里, 在这个方法区里先把main方法进行了临时存储, 然后虚拟机自动调用程序的主入口-main方法. 所以此时main方法被加载到栈内存里面, 然后开始执行里面的代码. 刚刚提到创建对象的这行代码, 虚拟机至少做了7件事

this的内存原理

thisyuan

之前学习过this关键字用来区分局部变量和成员变量重名的, 比如没有this的age直接打印是就近原则打印的10, 而有this的age就是用的成员变量的age

那为什么this可以区分, 它的原理是什么, 在内存中如何表示的?

  • this的本质: 所在方法调用者的地址值

集合和数组

集合和数组的对比

  1. 长度
  • 数组长度固定, 集合长度可变
  1. 存储类型区别
  • 数组可以存基本数据类型, 引用数据类型
  • 集合可以存引用数据类型, 如果存基本数据类型需要把基本数据类型变成包装类