java体系: -java基础 -java oop 重点 -java api -java web 前端和后端 -java 框架 -互联网架构 -大量的数据 java基础: 环境搭建: -安装jdk 有两个文件夹 jdk -jre -jvm -lib rt.jar -bin 命令 javac 和 java命令 -src.zip 源代码
jre: -jvm java的虚拟机 -lib 类库 rt.jar -安装eclipse -解压即可 -中文路径和空格不在 -启动时会自动搜索jre -有工作空间.metadata所有的文件夹都存储在文件夹中eclipse配置(建议:定期清洗) -eclipse跟jre绑定,改为内部绑定jre window-preferences-java-installed jres- add(standard vm)--选择一个jdk中的jre -eclipse整个工作空间的编码配置 window-preferences-general-workspace-text file encoding-UTF-8 java详细介绍开发环境: java的命名规范: -帕斯卡命名法:所有单词的第一个字母都是大写的 一般用于定义类名 -骆驼(驼峰)命名法:从第二个单词开始,所有单词的第一个字母都要大写,其余的都要小写 一般来说,骆驼命名法用于变量名和方法名 将帕斯卡和骆驼命名合并成都称为骆驼命名法 用eclipse创建java工程 在project explore右键单击空白处,右键单击选择-new-project- java project 出现一个create a java project窗口 project name:填入java 项目的名称 use defalut location:当前项目存储位置一般默认为启动eclipse指定的工作空间 jre:指定当前项目所依赖的指定jre类库版本 -一般指某个版本jre -只为当前项目指定固定版本jre -使用当前工作空间中指定的工作空间jre工作空间中的版本jre随项目的目的而变更jre还有工作空间jre同步 project layout:项目的布局 -目前项目的源代码不在src目录中,即src目录不存在 -当前项目的所有源代码都必须放置在src目录中 点击next 出现java setting窗口 source:当前项目源代码的位置,即src目录 project:目前的项目依赖于其他项目 libraies:目前项目依赖的类库 点击finish 创建工程结束
创建package包,在需要创建的地方,比如src右键单击文件夹--new-package -在java中称之为package包,在window系统称为文件夹 -name:package名字,只能是小写,一般是网站倒写 -在java中包名之间使用.符号分割,在window代表文件夹和子文件夹
比如: 网址 包名 163.com com.163 tedu.cn cn.tedu tarena.com.cn cn.com.tarena ...
这个定义可以按模块划分 cn.tedu.module1.submodulename cn.tedu.module2.submodulename
用clipse创建java类 右键单击package名称--new --class 出现创建java类的窗口 source folder:存储在哪个元代码的文件夹下的当前类 package:当前类别放置在哪个包中? name:类名称符合帕斯卡命名法 modifieres:此单词圆形modify(修改,修饰) 这里使用的引申义可以编辑和修改 -public:公有 public class A -private:私有 private class A -protected:保护 protected class A -package/default/friendly:默认 clas A -abstract:抽象 abstract class A -final:最终 final class A -static 静态类 super class:长辈类,指定当前类要继承哪个长辈类,不指定的,默认继承java.lang.Object interface:指定当前长辈界面是什么, which method...在指定类中需要添加哪些方法? do you want to add comment:是否向当前类别添加注释? 点击finish,创建类完毕
类创建别后,在类别中写作java根据需要编写代码
运行java代码: 方式一 单击文件中中的任何位置--run as--java application 方式二: 右键单击包中的文件名称--run as --java appliaction 方式三: 在工具栏中选择执行按钮
一种常用的开发技巧: 点击eclipse窗口中的project 菜单项--clean(清理) 若实施此项目.eclipse在当前的项目中bin编译在目录中class文件删掉 然后重新编译java源代码文件.生成class存储文件bin目录中
注意两个名词: 运行路径:java运行路径在项目中bin在目录中,实际run as执的是bin目录中的class文件 开发源代码路径:java中的开发路径在src中
eclipse常用的快捷键: ctrl+c 复制 ctrl+v 粘贴 ctrl+a 全选
ctrl+z 撤销 ctrl+y 取消撤销 ctrl+x 剪切 ctrl+d 删除光标所在的行,删除所选择的内容 ctrl+/ 注释和取消注释 ctrl+shift+/ 多行注释 ctrl+f 打开查找和替换的窗口 ctrl+h 打开复杂查找窗口 ctrl+w 关闭当前文档 ctrl+shift+w 关闭所有已经打开的文档窗口 ctrl+s 保存当前文档 ctrl+shift+s 全部保存
ctrl+-> 光标右移一个单词,遇到空格就移动一个空格 shift+-> 选择一个字符 ctrl+shift+-> 右移一个单词,且选中
shift+home 从当前光标位置一直选择到行头 shift+end 从当前光标位置一直选择到行尾
home 定位光标到行头 end 定位光标到行尾
ctrl+shift+home 从当前光标位置一直选择到文件头 ctrl+shift+end 从当前光标位置一直选择到文件尾
ctrl+shift+o 导入类所需要包 ctrl+shift+f 格式化源代码 alt+shift+z 给选择代码添加模板 f2 选择后按f2是更名
在实际开发中,必须注意一个配置 java的编译等级设置:指定.java文件用什么版本来编译 方式一:统一对当前工作空间中的所有的项目做编译等级的设置 window-preferences-java-complier-jdk compliance level
方式二:对指定的项目做编译等级设置 右键单击要设置的项目名称--properties--java complier--java compliance level
注意: 编译等级的设置原则: 实际使用的jre的版本和编译等级的版本相同即可 只能降级编译,不能升级编译 应用场景,在开发中可以用户各个版本测试
在开发中项目名称有红叉,但java代码没有红叉 一定要打开,window--show view --problem标签 然后看标签中的提示
java基础语法:
java是什么:java就是一门语言 公有类的名字必须跟文件名一致,一个java文件中可以写多个类,但公有类只能有一个 每个类中都可以写main方法,说明main方法可以有很多,运行哪个main方法取决于使用者
注意:一百个写代码有一百种写法,没有最优的写法,只有适合不适合 任何一段代码的好和坏一定是有前提
操作技巧: -双击代码的标签,标签会放大,再次双击会变小 -拖拽代码的标签,可以在eclipse中分屏显示 -右键单击代码的标签,可以有各种关闭
如何恢复eclipse的视图窗口 每种视图都很多的标签 方式一:全部恢复 window--perspective--reset prespective 重置视图 方式二:只恢复个别的标签 window--show view--选择具体的视图
导入别人的工程到当前的eclipse中 右键单击project explorer --import--import--general--existing projects into workspace 导入别人工程的时候注意在本eclipse下project--clean
任何语言做项目开发: 1.准备数据/获取数据 2.处理数据 3.显示处理完数据的结果
从现在开始,所有精力都要放在如何利用java语言来存储数据, 计算机中最小的单位是bit 比特 计算机中最小的存储单位byte 字节
一个字节由8个bit组成, 一个bit要么是0要么是1
1kbyte=1024byte 1mbyte=1024kbyte 1gb=1024mb 1tb=1024gb 1peta byte=1024tbyte 1exa byte=1024pb 1zeta byte=1024eb 1yotta byte=1024zb
java中的八种基本数据类型 byte 1个字节 用来存储字节数据
short 2个字节 用来存储短整型数据 int 4个字节 用来存储整型数据 long 8个字节 用来存储长整型的数据(可以用l或L结尾)
float 4个字节 用来存储浮点数据(可以用f或F结尾) double8个字节 用来存储浮点数据(可以用d或D结尾)
char 2个字节 用来存储字符型数据(必须用单引号引起来) 注意java中一个汉字是一个字符
boolean 根据jdk版本的不同,占用的字节也不同 用来存储布尔类型数据(true或false)
规定8种基本数据类型的目的: -限定数据的范围 -占用内存的实际的大小 -申请内存空间中只能放置指定类型的数据(java是强类型语言,任何数据必须指定类型)
变量的命名规范: 变量名中可以包含字母,数字,_,$,但就是不能以数字开头 用变量来存储数据: 语法: 数据类型 变量名称; 比如: int age;//是以age为理由跟内存申请4个字节的内存空间,但空间中没有数据 语法: 数据类型 变量名称=值; 比如 int age=20;//是以age为理由跟内存申请4个字节的内存空间,但空间中有数据20 float price=100.111F;//是以price为理由跟内存申请4个字节的内存空间,但空间中有数据100.111
The local variable age may not have been initialized 本地 变量 age 没有被初始化
Syntax error on token "%", delete this token 语法 错误 关于符号 % 删除这个 符号
Duplicate local variable age 重复 本地 变量 age
运算符: 赋值运算符 = 从右往左 把等号右边的结果赋值给等号左边的变量 算术运算符 + - * / % ++ -- int i=3; i++;//等价于i=i+1 int i=3; //先用i值后加一 System.out.println(i++);//输出的结果是3,输出完后是4
int i=3 ++i;//等价于i=i+1 int i=3; //先加一,后用i值 System.out.println(++i);//输出的结果是4,输出完的结果是4
类型转换问题: 大容器和小容器的关系 大容器=小容器;把小容器中的数据赋值给大的容器,自然转换 ,所谓向上造型 小容器=大容器;把大容器中的数据赋值给小的容器,强制转换(慎用),所谓向下造型
逻辑运算符: 结果是boolean类型 & 与 且 | 或 或者 ! 非 取反 false & false=false false & true=false true & false=false true & true=true 结论: 只要有一个为假值,结果就为假值 只有两个同时为真值,结果就为真值 false | false=false false | true=true true | false=true true | true=true 结论: 只要有一个为真值,结果就为真值 只有两个同时为假值,结果就为假值 && 短路与 且 || 短路或 或者 false && false=false false && true=false true && false=false true && true=true 结论: 只要有一个为假值,结果就为假值 只有两个同时为真值,结果就为真值 false || false=false false || true=true true || false=true true || true=true 结论: 只要有一个为真值,结果就为真值 只有两个同时为假值,结果就为假值 双符号和单符号的区别:结果都是一样,但是使用cpu是不一样的 双符号的特点: && 短路与: 双符号&&左边为假值,那么双符号右边就不进行运算 双符号&&左边为真值,那么双符号右边就进行运算 || 短路或: 双符号||左边为真值,那么双符号右边就不进行运算 双符号||左边为假值,那么双符号右边就进行运算 在实际的开发中,单符号和双符号都可以使用,但推荐用双符号 因为这样可以减少cpu的使用率,提高cpu的运行效率
关系运算符: 结果是boolean类型 > >= < <= == != 运算符的优先级顺序
最高()>!>算术运算符>关系运算符>&&>||> =
程序的三种基本结构: 顺序结构:代码按照顺序从上至下逐行运行 选择分支结构:基于顺序结构,根据某种条件选择性执行某些代码 循环结构:基于顺序结构,根据某种条件,重复执行某些代码 结论: 程序的整体执行时顺序结构执行 选择分支结构和循环结构,更适合做处理数据 if结构: 语法: if(条件){ //代码块 } 说明: if在java中是"如果"的意思 条件的结果是boolean类型数据 如果条件为真值,就执行代码块 如果条件为假值,执行if结构的右大括号后面的代码 语法: if(条件){ //代码块1 }else{ //代码块2 } 说明: if条件的结果为boolean 如果条件为真值,就执行代码块1 如果条件为假值,就执行代码块2 最终只能选择其中某个代码块执行 if嵌套: if中嵌套if-else else中嵌套if-else
if(性别nv){ //是女 if(年龄>60){ //是nv的且年龄大于60 }else{ //是女的且年龄小于60 if(体重300){ //是女小于60岁且体重300斤 if(身价过亿){ //是女小于60岁且体重300斤,身价过亿 } }else{ //是女小于60岁且体重小于300斤 if(很丑){ //是女的小于60岁体重小于300,长很难看 }else{ if(很穷){ 是女的小于60岁体重小于300,长很很好看,但很穷 } } } } }else{ //是男的 }
java的方法: 为什么需要方法:就是为了代码的重用,对于程序员来说 写一次代码,可以使用多次 有利于程序的维护 有利于程序功能的扩展 满足单一职责,每个方法只做一件事,符合此原则复用率高 提高开发效率 结论:一个好的程序 满足: 可复用性 可维护性 可扩展性 方法的语法: 方法的返回数据类型 方法的名称(参数列表){ //方法体的代码块 return 返回数据; } 说明: 方法的返回数据类型:可以是任意的已知的类型, 比如:八种基本数据类型,String类型 还有后续的类类型 注意:有一个特殊的类型 void void代表无类型 方法的名称:可以由程序员自定义任何名称,但必须见名知意 必须符合骆驼命名法 比如: public String getName(); public void setName(String name); 参数列表:必须放在小括号中,参数的个数可以是0个,也可以是多个 参数之间用逗号间隔,但也不能太多,多个的标准没有固定 的数值,定义方法的人和调用方法的人能就收可以 public int sum(int a,int b,int c,int d) 方法体: 是由若干java代码组成,能够完成某一种功能 一般情况下,方法体功能的简称就是方法的名称 如果参数列表有参数,那么就可以在方法体中使用参数的数据 但是在方法体外是不能使用方法的参数的 return 返回数据: 返回数据的类型,就是方法的返回类型,两者之间类型必须一致 返回数据只能返回䘝数据,不能返回多个数据
如果需要返回多个数据,就把多个数据打包 打包的方式:用数组的方式打包 用类来打包 返回数据可以省略,只有return关键字,那么方法的返回必须是void 类型, 如果返回类型是void,那么return关键字可以省略 如果返回类型是void,写return和不写return都可以 语法: return 返回数据; return; 不写return关键字 return的说明: 上面的的写法,不一定非要写在方法的最后一条语句 方法体中可以写多个return关键字,并放在方法体中任意位置 如果在方法体中出现了return关键字,并执行到此关键字 相当于结束(终止)方法的执行 如果return带有返回数据,相当于结束/终止方法的执行,同时返回一个数据 结论:return是结束方法的执行,如果有数据就返回数据
switch结构: 语法: switch(表达式){ case 常量1: 代码块 break; case 常量2: 代码块 break; ... case 常量n: 代码块 break; defualt: 代码块 break;//default放在最后,此break可以省略 } 说明: 表达式:表达式的结果类型,只能是整型数据,字符型数据,枚举类型 也可以是字符串类型,但必须注意jre的版本 jre版本1.7及以上 switch的表达式可以使用字符串类型 jre版本1.6及以下 switch的表达式是不能使用字符串类型 注意:虽然使用的jre的1.7以上,但编译等设置为1.6,同样 不能使用字符串 常量:整型,字符型,枚举,字符串 代码块:是符合常量时,需要执行的代码块 可以是多行代码,但一定不要用大括号 break:是终止的意思,如果执行到break语句,那么\ 终止当前switch结构,跳出switch结构,执行后面的语句 如果没有break语句,那么找到符合的常量的时候,执行对应 代码块,但执行完代码块后,后续常量对应的代码块中的代码 一并执行,直到碰到break语句跳出switch结构 default: 如果没有任何一个case常量符合,则执行default后代码块 default块可以放在switch中任何位置,但不能放在case中 default和case是平级关系,但一般情况下default放在switch 的最后,且break可以不写 switch和if的区别: 都是分支结构 switch适合做等值判断 if结构更适合做范围判断,也能做等值判断 所有的switch结构,都可以用if来替换 不是所有的if都能用switch替代
三元运算符: 语法: 类型名 变量名=(条件表达式)? 表达示1 :表达式2; 说明: 条件表达式的结果为boolean类型 条件表达式为真值,则把表达式1的结果赋值给变量名 条件表达式为假值,则把表达式2的结果赋值给变量名 表达式1和表达式2的结果类型必须相同,且跟变量的类型相同 三元运算符的本质就是一个if-esle 比如: int totaPage=(totalCount%pageSize==0)? (totalCount/pageSize) :(totalCount/pageSize)+1; 等价于: if(totalCount%pageSize==0){ totalPage=totalCount/pageSize; }else{ totalPage=totalCont/pageSize+1; }
循环结构:循环结构一定是有规律的,没有规律的是不能用循环的 循环就是重复的执行一段代码,最好根据某种条件退出循环 循环要慎用,因为循环最浪费cpu的时间 要用循环,就尽量减少循环次数 循环的分类: while循环,do while循环,for循环(普通for循环和增强的for循环) while循环: 语法: while(条件){ 循环体代码块 } 说明: 条件:可以是逻辑表达式,也可以是关系表达式, 但表达式的结果一定是boolean类型 循环体代码块: 完成某一个特定功能的若干代码, 一定是由规律的
读循环或写循环循环的技巧: 要完整的推导出来前三次循环规律 如果在推导的过程中记不住步骤 建议写在纸上和电脑的记事本上 while循环的三要素: 循环变量的初值:用于记录循环次数的,达到一定的循环次数就退出循环 循环变量的终值:用判断何时退出循环 循环变量的增量或减量:没有增量或减量就是死循环
while(条件)和while(true)区别 while(条件){ //此循环是否退出,取决于条件 //一般情况下有固定的循环次数,用此循环 } while(true){ //没有明确循环次数 //一定要配合一个if使用,根据if条件来决定何时退出循环 if(条件){ break;//终止当前循环 return://直接终止当前循环所在的方法,直接退出当前方法 } } 重要 重要 重要 程序的调试:是程序员的必备技能,也是程序员的必杀技 做程序的目的,就是为了明确程序每一个步骤都是执行正确的 即,保证程序能够满足现实需求 程序实际执行过程中,从头执行到尾,程序员是看不到中间的 执行过程,需要在程序的中间的某个位置,设置断点,程序执行 到断点,程序就会暂停,由程序员通过某些按键逐步执行代码 以便于检查代码执行是否正确 程序调试中,重要的几个操作按键 F5:碰到函数或方法,则进入方法 step into F6:单步执行 step over F8:继续执行,恢复执行, resume F8恢复执行,如果之后还有断点则会停到断点上, 如果之后没有断点则程序执行到最后 debug调试程序的技巧:就是设置断点的技巧 首先,先判断可能会出现问题的代码部分,把断点放在 可能出现问题代码前面 其次,根据错误提示,在console控制台中查看出现的错误提示 然后错误提示,设置断点 如果上面两种都不符合,恭喜你,需要把断点设置到程序的第一条语句 如果程序执行到断点,程序暂停,需要按F5或F6或F8 最终,会找到程序的错误的地方, 即使程序没有错误,也可以通过断点,逐行执行,来更好的读代码
没有写代码的高手,只有调试程序的高手
do while(条件); 循环侧重是至少执行一次循环,然后才判断条件 while(条件),侧重先判断条件,条件成立才执行循环体
for循环: 语法: for(数据的初始化;条件;循环变量的增量或减量){ //循环体代码块 } 说明: 数据的初始化:可以定义多个变量,中间用逗号间隔, 但类型必须是同一种类型 且在第一次循环的时候执行一次 条件表达式: 可以是关系表达式,也可以是逻辑表达式,总之结果是boolean类型 且表达式有且只有一个 条件为真值则进入循环体 条件为假值则退出循环 循环变量的增量或减量: 当循环条件为真值,执行循环体 然后执行循环变量的增量或减量 然后判断条件表达式是否为真 如果为真,则继续循环体 然后还是执行循环变量的增量或减量 如此往复 直到循环条件为假,则退出循环 执行for循环后面的语句 break:终止 break用在switch机构,用于退出或终止switch结构 继续执行switch结构后面的语句 break用在循环(while,do while,for) 用户退出当前循环,继续执行当前循环结构后面的语句 break能够改变程序的执行流程
continue:继续 continue:只能用循环中,用于结束当前的循环,继续执行下一次循环
循环嵌套: 循环里套循环 外层循环一次,内层循环多次 建议不要超过3层循环 读或写循环,一定要针对最外层循环认真推导3个循环
Unreachable code 就是指定的代码是永远无法执行的
数组: 由于单个变量只能存储一个数据,如果数据量多了,起变量名 变得麻烦 用数组可以存储很多相同数据类型的数据
数据结构:按照什么样的结构来组织数据 为什么非要按照数据结构来组织数据,因为cpu使用这些数据的 时候能够更好的存储,读取,操作数据 数据结构的分类: 物理数据结构:数据在内存中的或外存中的真实的存储结构 不需要程序员关注 逻辑数据结构:就是人们按照某种想象的逻辑来组织数据的结构 java开发人员更多关注逻辑结构 jvm能够识别逻辑结构 数组就是人们想象出来的一种逻辑结构 这种逻辑结构要存储到内存中, 由jvm来控制,程序员只需要关注数据的逻辑结构用法即可
数组的的特点: 数组是一组数据的集合体 -必须是同一类型的多个数据(具体个数由程序员根据需求定义) -在内存中必须是连续的空间,(由jvm来控制) 数组的优缺点: 优点:存储同一类型的多个数据 缺点:不能存储不同数据类型的数据, 数组申请完内存空间后,就不能动态增长空间 (解决方案:重新申请一个更大的新的数组空间, 把原来数据中的数据复制到新的数组空间中) 数组的使用: 1.定义数组(声明数组) 语法: 数据类型[] 数组的名称; 或者 数据类型 数组的名称[];//不建议 说明: 数据类型:是所有的java中的已知任何类型(八种基本数据类型,类类型) []:推荐放在数据类型的后面,数组名称的前面, 注意:[]可以放在数组名称的后面,但不建议 比如: int[] aa;//不占用堆内存,但程序中可以使用,运行时报空指针异常 java.lang.NullPointerException 2.给数组申请内存空间(堆内存) 先声明数组 int[] aa;//此时没有申请堆空间 给数组申请内存空间,且给默认初值 aa=new int[5]; 能使用的数组元素有5个,每个数组元素占用4个字节空间 且每个数组元素初值是0 aa[0] aa[1] aa[2] aa[3] aa[4] 申请5个空间下标索引为0--4,如果超出下标索引 会报数组下标越界异常 java.lang.ArrayIndexOutofBoundsException 3.给数据的元素赋值 如果没有明确给赋初值,则按照数据类型来给默认值 数字类型(int,float,double,short,byte,long) 默认值0 字符型默认 \u0000 对象类型 默认null 可以人为给赋值 aa[1]=100; 4.使用数组中的数据 数组名称[下标索引] 来取出数组元素的数据,并根据业务处理他 补充增强for循环:是从jdk1.5版本及以上的版本才可以使用 语法: for(数据类型 变量名 : 数组名或集合名){ //循环体代码块 } 说明: 从数组或集合中取出第一个数据,赋值给变量名, 然后在循环体代码块中使用此变量名中的数据(变量名的作用域 仅在循环体范围内),执行完循环体,后再次从数组或集合中 取出第二个数据赋值给变量名,然后在循环体中使用变量名中的数据 以此往复,直到把数组或集合中的所有的数据都取出,循环执行完毕 注意:变量名所对应的数据类型,必须跟数组或集合中的数据类型相同 其他几种数据的声明和申请空间写法 int[] ages=new int[10];//声明数组的同时就申请了内存空间,有初值0 int[] ages={20,22,30,35,25};//声明数组的同时申请了内存空间,有初值但不是默认值 int[] ages=new int[]{20,22,30,35,25};[]里不能给数字
获取数组的长度: int length=数组的名称.length; 比如: int[] ages={20,22,30,35,25} ages.length;//5
数组的排序: 排序的算法: 冒泡排序 插入排序 快速排序 等... 数组元素的排序: 在java.util.Arrays.sort(要排序的数组的名称); 会对源数组做升序排序,会改变源数组 比如: int[] ages={20,22,30,35,25} java.util.Arrays.sort(ages); //20 22 25 30 35
数组的复制: 使用System.arraycopy()方法可以实现数组的复制 方法的定义: public static void arraycopy(Object src, int srcpos, Object dest, int destpos, int length) 方法的说明: src:源数组 srcpos:源数组中的起始位置 dest:目标数组 destpos:目标数组中的起始位置 length:要复制的数组元素的数量 比如: int[] a=new int[]{1,2,3,4,5}; int[] a1=new int[8]; System.arraycopy(a,1,a1,0,4); 结果: a1数组中 2,3,4,5,0,0,0,0 使用java.util.Arrays类中的copyOf方法对数组进行复制 方法的定义: 类型[] newArrayName=Arrays.copyOf(类型[] original, int newLength); 特点: 生成的新数组是源数组的副本 newLength小于源数组,则进行截取 newLength大于源数组,则用0或null进行填充 所产生的新数组可以大于源数组的长度,属于数组扩容, 所产生的新数据可以小于源数组的长度,属于数组缩容 比如: int[] a={1,2,3,4,5}; int[] a1=Arrays.copyOf(a,6); 结果: a1数组中的内容: 1,2,3,4,5,0
二维数组: 语法: 数据类型[][] 二维数组的名称=new 数据类型[行数][列数]; 比如: int[][] a=new int[3][4];//声明数组并在堆空间中申请12整型空间
a[0] a[0][0] a[0][1] a[0][2] a[0][3] a[1] a[1][0] a[1][1] a[1][2] a[1][3] a[2] a[2][0] a[2][1] a[2][2] a[2][3] 二维数组实际上是由多个一维数组组成 实际上上面的二维数组是由 a[0] a[1] a[2]三个一维数组组成
用对象存储不同类型的数据,至少比数组的方式更进一步 面向对象: 重要的引言: 面向对象不是某个阶段就能学习精通的,但是要面向对象的基本 知识点要理解,只是用的不灵活,也会应用到某个实际项目中 无论什么样的项目,都可以用面向象+设计模式+面向对象的设计原则 可以设计出很好的程序的架构. 为什么要学习面向对象 -能够把现实世界物或事转到计算机中 如何掌握面向对象 首先要掌握类: 类: 类是一种数据结构(逻辑结构),组织多个数据类型的一种结构 数组做不到的,类能做到,对数据管理的一种进步 类中只存储数据过于单一,所以需要在类中放置方法, 由方法来操作数据 类的特点: 封装:用类把数据和操作数据的方法封装在一起 继承:类和类之间是有继承关系,是为让子类复用父类的属性或方法 多态:是面向对象的灵魂
什么是类(class):就是一个普通的名词 1.类就是一个数据结构(逻辑结构) 变量只能存储一个数据类型的数据: int i=100; 数组能存储多个相同数据类型的数据 int[] a=new int[10]; 数组也是一种数据结构 类能存储多个不同类型的数据,还可以有操作数据的多个方法 比如: public class Student{ int age;//学生的年龄 String name;//学生的名字 String stuNo;//学生的学号 public void study(){}//学生具备学习的能力 public void dajia(){}//学生具备打架的能力 }
2.类是一种特殊的由程序员自定义的数据类型 int i=3;以i为理由申请int类型大小的内存空间,存储的值是3 int[] a=new int[10];以a为理由,申请int类型的10个空间,有默认值0 public class Student{ int age;//学生的年龄 String name;//学生的名字 String stuNo;//学生的学号 public void study(){}//学生具备学习的能力 public void dajia(){}//学生具备打架的能力 } Student stu1=new Student();以stu1为理由,申请Student类类型这么大空间 stu1里的age值是0 stu1里的name值是null stu1里的stuNo值是null 3.有类这种数据类型,可以通过这种数据类型在堆空间中申请空间 Student stu=new Student(); 可以用类类型申请无数个内存空间,且每个空间对应一个学生信息 4.基于前三点,可以把现实世界的物或事转到计算机中的类上 用类这种类型,在内存中申请内存空间,用于存储数据 使用面向对象或类,最难的事是把现实世界的物或事转换到计算机中 通俗的说法,就是把现实世界的物或事对应到计算机中的"类"上 如果了解或理解了现实世界的物或事,做成java的类就很容易 如果不了解或理解现实世界的物或事,做成java的类就很困难 实际java语法,创建一个类是很简单 public class 类名{ //最难的是在类中写属性或方法 //多个属性 //多个方法 //符合单一职责 此类只表达一件事 } 类的定义用java语法写起来很简单,难的是写什么样的属性和方法
结论: 现实世界物或事--->通过程序员的抽象成类(属性和方法) --->用类在内存中申请(new)内存空间,并存储数据 --->从内存中取出对象的数据,根据需求处理数据 --->把处理后的结果现实在界面(控制台,网页,安卓app等...) ----------------------------------------------------- 程序员要做面向对象, 首先要考虑的是在类中放置什么样的属性和方法 类里能放: 多个属性:代表数据 多个方法:代表功能 其次要掌握对象 对象和类在jvm内存中的存储机制: jvm把内存分为三个主要部分 方法区:存储的是类的定义,静态数据,常量池,由jvm来控制管理 堆区:数组申请的空间,对象申请的空间,总之new出来的空间 堆空间中存储的是数组数据,对象的数据,可以通过程序操作的 栈区:堆中的对象空间中存储的是属性数据,没有方法, 判断对象是否相等,主要判断的是对象中的属性的值是否相等 所以对象就是数据的载体,对象中没有方法,只有数据 通过对象打点调用方法,实际上使用的方法区中的类定义里方法 方法中使用哪个对象的数据,取决于方法是被哪个对象调用的 ----------------------------------------------------------- 第一段: 为什么要使用面向对象 为什么要有类 什么是类 第二段: 类和对象在内存中的存储机制 第三段 解决数据如何存储 解决数据的安全问题 数据如何存储: 类中的属性变成私有数据 私有数据通过公有的方法来访问,因为方法可以写逻辑 公有的方法是有规律的 getter and setter getXXX and setXXX 数据的安全性问题: 在公有方法中的逻辑,来保证私有数据正确性和安全性 --------------------------------------------------------- 程序: 获取数据/准备数据 基于数据,处理 显示处理的结果 在内存中如果申请空间 1.用变量存储数据 int age=20; 2.数组:能存储一组相同数据类型的数据 3.类:能组织一批不同数据类型的数据 内存中的有了数据了 用顺序,分支,循环 可以组织很复杂的逻辑 掺杂着运算符, 有数据了,有逻辑了,可以表达现实世界的事和物 用类来存储复杂的数据,用类和类之间的关系,来表达现实世界的复杂关系 程序员能写程序能帮助人们做很多的事情
给对象存储数据的方式有两种: 1.用setter方式存储数据 2.用构造函数的方式存储数据
从对象中获取数据方法有一种: getter方式 构造函数/构造器/构造方法 constructor: 构造函数不能有返回类型 构造函数的名称必须跟类名称一样 如果类中没有明确写出构造方法,系统会给出一个默认的构造函数 默认的构造函数 无参数的的空方法,简称空的无参构造 构造函数可以有参数,如果书写了有参构造,那么就建议写一个 空的无参构造 在当前的构造方法中调用本类的其他的构造 请用this(参数列表); 参数列表中的参数可以是0个或多个,但this(参数列表)调用 构造方法的时候,本类必须存在这个构造 成员变量: 类中的属性数据,就是成员变量,作用域整个类 成员变量会给默认初值,具体的值根据数据类型来决定 局部变量: 类中的方法中定义的变量就是局部变量,作用域在声明变量开始 到第一个右大括号结束,使用局部变量必须给初值 如果不使用局部变量就不需要给初值 面向对象的主线: 1.为什么要有面向对象 a.可以用类组织一批不同类型的数据 b.把现实世界的物和事转换到计算中 现实世界的对象--->计算机中的类-->计算机内存中的对象 2.要实现面向对象的手段和途径,关键是类 类:就是一个名字 就是一个模型 就是一个数据结构 就是一种数据类型 用类可以在内存中实例化若干对象 3.有了类,还有内存中用类实例化的对象 类和对象在内存中如何存储 方法区:类定义 堆区:类的对象 栈区:对象的地址 4.保证数据在堆区中存储是安全的且正确的 属性数据是私有的 方法是公有的 用settter和构造给对象存数据 用getter来取出数据
有了上面的知识的铺垫 程序员写的常规类: 就有两种类模型: 第一种: 类中只有私有属性,只有公用的getter and setter 或者有,有参数的构造函数 此种类适合存储数据的 第二种: 类中只有方法,没有属性 此种类适合做功能,而方法所需要操作的数据, 可以通过方法的参数传递进入方法
值传递:(基本数据类型的数据的传递,栈中的数据) 基本数据类型的数据作为方法的参数进行传递 那么在方法中会另外开辟一个新的内存空间, 跟原来的内存空间不是一个内存空间 如果在方法中对参数的值进行更改 不会影响原来的内存空间的值 如果非要获取方法中修改后的值 则需要把修改后的值返回出来
引用传递:(数组的传递,对象的传递,堆中的数据) 如果传递的是对象或数组 实际上是把对象或数组的引用传递到方法中 如果在方法中对引用的对象或数组做任何修改 都会影响原来的内存空间的值,即修改了原来内存 空间,其实操作的是同一份内存空间
this用法: this有两种形式的用法 -this. 访问当前对象的属性或方法 -this(参数列表) 调用本类的其他构造函数 this指的是当前对象 如何判断this指向的是哪个对象: this在哪个方法里,这个方法被哪个对象调用 那么this就指向那个对象,这个原则适用于this. 不适用this();
代码块: 代码块就是一对{}括起来的代码段 代码块有两种: -在类中用代码块括起来的一段代码 类中的代码块在new 构造函数之前执行\ -在方法中用代码块括起来的一段代码 方法中的代码块用于限定某些变量的作用域 类中的代码块的应用场景: 在构造函数之前需要初始化一些数据的时候
final关键字: final 最后 final关键字可以修饰在成员变量,和局部变量 final关键字可以修饰在方法上 final关键字可以修饰在类上
final修饰在变量上,最后的量值,量值不能修改,所以是常量 比如: final int i=3; final修饰的变量,只能赋值一次 final int i; i=10; i=100;//报错 final修饰在成员变量上,必须直接给初值 比给初值是语法错,不是运行错 final修饰在局部变量上,可以先声明,后给初值,初值只能赋值一次 final修饰在方法上,那么这个方法就变成最后的方法,是不能重写 final修饰在类上,这个类就是最后的类,final类不能被继承 String类就是final类 静态: 所有静态相关,都是用static关键字修饰 -static关键字可以修饰成员变量,不能修饰局部变量 -static关键字可以修饰方法 -static关键字可以修饰一段代码,静态块/静态代码块 static{代码段} static修饰的成员变量开辟空间在方法区 所以就是一份内存空间,任何方法都可以修改这个静态 变量,一般静态变量做一些公用或共用的计数,要慎用 ,尽量变量做成局部变量,作用域越小,受干扰的可能性 就越小.一般情况下static final 共同修饰成员变量 static修饰在方法,方法也储存在方法区中 非静态方法和静态方法在方法区中存储是没有区别的 都是存储在方法区中,但调用上是有区别的, 非静态方法被调用,必须先实例化此方法所对应的类的对象 然后通过对象打点来调用这个非静态方法 静态方法可以类名直接调用, 如果想频繁的调用一个方法,这个方法不需要操作某个对象 的数据时,这个方法最好设置成静态方法 在静态方法中不能使用this,this属于对象,而不属于类 静态的属于类,而不属于对象 static修饰代码块 static{} 代码块就是包含一些代码逻辑,所以静态块还是存储在方法区 但是静态代码块执行的时机是由区别的; 能写代码逻辑的地方,方法和静态块和代码块中都可以写代码逻辑 方法中的代码逻辑是否被执行,取决于程序员是否调用 静态代码块,在类加载到方法区后,就自动执行静态代码块 代码块,是在静态代码块后,构造函数前执行 执行的顺序,先执行静态代码块,然后执行类代码块,然后执行构造函数块 总结: 静态的方法只能访问静态的变量和静态的方法 即,静态的只能访问静态的 非静态的方法可以访问静态变量和静态的方法 也可以访问非静态的方法和非静态的变量 静态的方法即可以用对象调用(不建议),也可以用类名调用(建议)
a. 第一个类加载,执行性第一个类的静态代码块 b. 第一个类中包含第二个类作为第一个类的属性(注意,new和不new ) new:第二个类加载,执行第二个类的静态代码块 执行第二个类的类代码块 执行第二个类的构造方法 不new:不加载第二个类 c. 执行第一个类的类代码块,注意c步骤和b步骤的顺序 b在c前, 执行顺序是 a,b,c,d c在b前,执行顺序是 a,c,b,d d. 执行第一个来了的构造函数 Cannot make a static reference to the non-static field temp 不能用静态的访问/引用非静态的 静态+常量 static final 同时修饰 同时修饰static和final关键字 一般情况下是公有的静态的final的量 比如: public static final int FILE_BLOCK_SIZE=4*1024*1024; 公有的静态的final修饰的量的名字都是大写,且单词间 用下划线分隔,这是一种约定俗成
static+final的量一般出现在这样的类中 public class SysConstant{ public static final int FILE_BLOCK_SIZE=4*1024*1024; ... //整个项目中所有用到的固定的常量,且值不需要改变的 //都可以放在此类中 } 使用的时候: SysConstant.FILE_BLOCK_SIZE来取出值即可
方法的重载: 在同一个类内,有相同的方法的名字, 但参数的个数和类型不同 跟方法的返回值无关 比如:都是求和的功能 //此类是重载的写法 public class calc{ public int sum(int a,int b){ return a+b; } public float sum(float a,int b){ return a+b; } } 使用: calc c=new calc(); int result1=c.sum(1,2); float result2=c.sum(1.2F,3);
//此类不是重载的写法 public class calc{ public int sum1(int a,int b){ return a+b; } public float sum2(float a,int b){ return a+b; } } 使用: calc c=new calc(); int result1=c.sum1(1,2); float reulut2=c.sum2(1.2F,3); 重载的应用场景: 功能相似,但功能有一些细微的差异 封装:之前的内容是封装, 把私有的数据封装,用公有的getter and setter 和构造 存储数据和取出数据,适合存储数据 类中只封装功能,适合做功能的 最终把现实世界的物和事转到计