lJava是什么?
Java是sun公司开发的,面向对象的,跨平台的,代码安全的开源的编程语言。
lJava的应用领域
1. javaSE:java standard edition:标准版本。是Java语言的基础,可用于做C/S结构的桌面软件。
2. JavaEE:java enterprise edition:企业版。在javaSe的基础上,用于企业级的开发。比如JSP, Servlet..
3. JavaME:java micro edition:微缩版。主要用于嵌入式,电子消费品的开发。
主要学习JavaSE,JavaEE。
lJava语言的运行机制:
lJava语言的特点:
1、可跨平台
–Java跨平台主要依靠jvm来实现的。
–Jvm可以看作由软件构建的,运行在某个操作系统上的java平台。
–运行java程序必须在jre环境。
–每个操作系统都有相应的jvm。
2、垃圾回收机制
–Java中,垃圾回收机制是由jvm自动完成。
3、代码安全
–xx.java->.class;.class加载后,字节码校验;解释执行字节码;
xx.java文件中,编写的是遵守Java语法的程序。如果在该文件中,java语法编写错误,则不能够编译成xx.class文件。
xx.class文件来说,如果自定义一个xx.class文件,类加载器将其加载到JVM后,通过bytecode verifier 对该文件校验。
l环境变量:
–window:dos
•查看:set:查看所有的环境变量;set 环境变量名:查看指定名称的环境变量
•如何设置环境变量:
–set 环境变量名=环境变量值
–set 环境变量名=%环境变量名%;追加的路径
–Linux:
•查看:env:查看所有的环境变量;echo $环境变量名。
•设置环境:
–export 环境变量名=值
–export 环境变量名=$环境变量名:追加的路径
l配置开发环境
需要安装JDK。
1、下载JDK
2、安装JDK
–bin:开发人员所需的工具均在此。
–lib:类库
–jre(bin,lib):java运行时环境,运行Java程序,必须要有jre(JVM和类库)
–src.zip:源码包 执行Java程序都是.class文件,src.zip有对应的源文件。
3、配置环境变量
–JAVA_HOME=D:\jdk1.6.0_10
•为了其他java程序能够找到JRE
–PATH=D:\jdk1.6.0_10\bin或者PATH=%JAVA_HOME%/bin
•为了找到java的开发工具命令
–CLASSPATH=.; D:\jdk1.6.0_10\lib\dt.jar; D:\jdk1.6.0_10\lib\tools.jar
•提供java运行时所需要的资源的路径
4、验证JDK配置是否正确
–在dos或者终端下,输入javac或java,如果显示当前配置信息,则表示配置正确
l开发第一个Java程序
1、新建一个xxx.java文件,编写java代码
–必须符合java的规范,且java是大小写敏感的
–xxx.java文件中,有且只有一个public修饰的类,且该类的名称要和xxx完全一样。
–一个文件中可以包含多个default(无关键字)修饰的类。class 类名{}
2、将xxx.java编译成xxx.class文件
–编译使用javac命令,通过配置的path变量可以得到。
–1、2步骤属于编译时
3、通过java命令运行java程序
–java命令通过path得到,而.class文件通过配置的classpath或通过java命令的参数-classpath指定路径,找到xxx.class文件
–java xxx:运行程序。java命令相当于启动了虚拟机,且将xxx加载到虚拟机中
javac,java命令通过path= C:\Java\jdk1.6.0_43\bin路径找到的。
javac命令后的.java文件可以根据路径直接找到。
java命令后面跟的.class文件,不能通过指定的路径找到。是通过CLASSPATH=.;找到的。第一种方式:java -classpath ./hao FirstA;第二种方式,就是配置CLASSPATH环境变量的值
lJava集成开发工具
记事本就可以编写Java程序。如果涉及到很多的类时,需要自己管理,很麻烦。为了提高效率,可以使用集成开发环境:IDE= Integreter Development Environment。
集成开发环境有很多。C,C++有VC6.0,对于Java的开发环境,经常使用的是Eclipse。
Eclipse是IBM使用Java语言开发的免费的IDE。
Eclipse自定义编码格式与快捷键 1. 在Eclipse的显示界面称之为透视图,每一个独立的窗口称为视图。透视图是由多个视图组成,一个透视图可以包含多个视图。视图可通过右上角菜单的open Perspective来打开新的工作视图,也可以通过主菜单栏的window->show view 来打开我们想要的视图,利用视图,我们可以很方便的查看到我们代码,以及调试的结果。当我们不小心删除了某一个视图,想要进行恢复的时候,在window->reset perspective可以还原我们最初的视图。
2.自定义编码 在Eclipse软件中,通常在主菜单window下设置编码的字体,编码的格式。 (1)定义字体 window->preferences->General->Apperance->Colors and Fonts->双击Java Editor Text Font来自定义编码的字体
(2)定义代码的样式 window->preferences->Java->Code Style->Formatter->New在新建的配置文件里面可以自定义编码的格式,输入profile name之后->Braces->除了最后一项不变,其他项都选择Nextline->apply->ok 利用profile可以统一编码规范,让代码变得更加易于管理和更新,在实际的工作中,将预定义的profile文件导入就可以统一编码格式了。可通过ctrl+shift+f快捷键将我们自己编写的代码按照设置的格式化样式进行格式化。
3.导入项目 点击左上角的菜单的第一个选项file,点击import->General->Existing project into workplace->在set root directory中添加要导入project的绝对路径->next->finish
4.删除project 选中该project,点击右键,选择delete,就可以删除该project,在这里,可以在删除project时选择是否保留在该project的java源文件。
5.改变当前的workplace 点击左上角的菜单的第一个选项file,点击switch workplace->other->在workplace下填写新的路径,点击ok,Eclipse将会重新启动,然后切换到我们新指定的workplace。
6.快捷键 当我们的工作区没有project的时候,用control+n来新建project,利用向导来选择project的类型,点击next,输入project name用tab键来切换不同的选项,在这个页面中,我们要在project layout中选择create separate folders for sources and class files选项,(系统会自动创建src目录,并且在scr目录下生成两个子目录,src目录放源文件,bin目录放class文件)这样方便我们以后发布.class文件。新建好project之后,我们选中project,再次按下control+n,这次就自动在该project下新建一个类,选择class,点击next,输入类名Hello,点击finish,这样一个project和一个class就建好了 下面的快捷键要在具体的代码中实现 public class Hello{ public static void main(String[] args){ System.out.println("Hello World"); } } (1)ALT+/ 自动补全命令 (2)ALT+方向键 移动语句到指定的位置 (3)shift+home 定位到该语句的首部 shift+end 定位到该语句的尾部 (4)control+c 复制一条语句 (5)control+/ 单行注释,同时可以删除单行注释 (6)control+shift+/ 多行注释 (7)control+shift+f 根据profile格式化编码格式 (8)control+shift+\ 删除多行注释 (9)control+d 删除光标,删除一行 (10)control+z 撤销刚刚的操作 (11)control+F11 执行语句 |
lJava语言的组成:
语句;注释;关键字;标识符;常量;变量;运算符;流程控制(顺序,分支,循环);函数;数组;类;接口
l注释:
•几乎任何语言,都有注释:java,c#,c,c++,html,javascrip,jsp
•主要是解释程序的含义,帮助程序员阅读代码。
•调试,修改代码时,可以使用注释。
•在实际项目中,注释一般会占代码量的1/3到1/4
•在.java文件,注释的信息,将不会被编译。
•如何注释
–//-----------单行注释
–/* */多行注释
–/** */文档注释,一般,文档注释都是在类或方法或属性的前面。当通过javadoc命令将程序,生成一个文档,对类或方法等信息进行解释说明。
注意:
对代码注释,可以使用:
ctrl + / 对光标所在行或选中的多行进行单行注释,再操作一次,相反。
ctrl+shift+/ 对选中的代码进行多行注释
ctrl+shift+\ 对选中的已经被多行注释的代码取消注释。
l关键字:
–keyword,Java中赋予了特殊含义的单词。因为具有了特殊含义,所以在后续命名中,不能使用。
–关键字有很多,比如public class private protected…..
在eclipse中,默认显示为红色的,都是关键字。
–goto const: 保留字
–特点:
•1-不是固定的,随着java的发展,关键字也在发展。
•2-关键字全部小写。
l标识符:
–主要用于为Java中的类名,包名,属性名,方法名,变量名…命名。
–标识符的组成:
•只能由数字(0-9),字母(a-zA-Z),$,_ 组成。且数字不能开头。
•以下哪些标识符合法
–abc123_a8; $23bdc.exe; _123; A; 1ab3; wud&bc;
–注意点:
•1-标识符可以以$开头,但不建议使用。
•2-标示符可以使用中文,但禁止使用。
•3-标识符不能使用关键字。
•4-Java中,大小写敏感的。可以使用A和a分别表示不同的名称,但是,最好不要仅仅以大小写区分。
–命名建议:
•1-命名要有意义,最好做到见名知意。
int age = 20; String name = “jack”;
int a = 10; String n = “rose”;
•2-类名,接口名的命名,单词首字母大写。HelloWorld, Student
•3-属性名和变量名:如果有一个单词,则该单词全部小写;如果有多个单词,第一个单词全部小写,第二个单词及以后,首字母大写。age, name, totalScore
•4-方法名:如果有一个单词,则单词全部小写;如果有多个单词,则第一个单词小写,第二个单词及以后,首字母大写。一般情况下,一个单词的方法,该单词是动词get;两个或多个单词,一般是动宾结构getName
lJava中整数表示形式
–二进制:
0, 1
八位无符号二进制范围:00000000~11111111
八位有符号二进制范围:11111111~01111111
三位无符号二进制范围:000~111 转换成十进制:0~7
–八进制:
0~7 八进制的标志:0开头。023 八进制。
一位八进制相当于是3位二进制。
0271转换成二进制: 10111001
11011011000101010:0333052
–十进制:
0~9表示。
–十六进制:
0~9 A~F(a~f) 十六进制的标志: 0X或 0x
四位无符号的二进制范围:0000~1111 转换成十进制: 0~15
一位十六进制相当于4位二进制
0x9F: 10011111
0X3ABF:11101010111111
1101111011100010101:0X6F715
十六进制常常用于表示颜色:RGB(Red, Green, Blue)在表示颜色的时候,每一种颜色用两位的十六进制表示。表示形式#00FFAA #FF0000 #00FF00 #0000FF #000000 #FFFFFF
l进制转换
l整数在内存中的存储
•数据在内存中,以何种形式存储:
–数据存储是以补码的形式存储:
int类型用4个字节存储数据。也就是说32位。
正数:原码,反码,补码相同。
负数的原码,是它的绝对值的二进制的最高位为1,反码是原码符号位不变,其他位取反;补码是反码末尾+1。
l字面常量(值不能改变的)
–整型常量: 10, 100 type: int
–小数常量:10.0; 100.54; type: double
–布尔型常量:true fasle; type: boolean
–字符常量: java中,字符常量用’a’,单引号中只能有单个字符。 type: char
–null 只有一个值。
–字符串常量: “abcdefg”,””; “ “; 由双引号括起来的0个或多个字符。
“” “a” “Aaaaaa” type: String类型
l变量:
–就是数值可以变化。变量是一块内存存储空间。
–如何定义和使用变量:
•type name = value;
•int age = 10;
l数据类型:
–就是为计算机中的数据进行分类。
–Java中有哪些数据类型:
•基本数据类型
–byte 1B -128~127
–short 2B
–int 4B
–long 8B
–char 2B
–float 4B
–double 8B
–boolean 1B(1bit)
•引用数据类型
–数组
–接口
–类---String
lJava基本数据类型
–数值型
•定点型:byte short int long
•浮点型:float double
•字符型:char
–逻辑型
•boolean
lJava基本数据类型-定点型
•定点型:
–byte 1 -27~27-1 (-128~127) 较常用 0
–short 2 -215~215-1 0
–int 4 -231~231-1 很常用 0
–long 8 -263~263-1 较常用 0L
–四种数值类型的区别?
•表示范围不同,视情况选择相应类型。
–整数类型中,整型常量默认的是int类型。
–一个数值表示long,该值必须后面加上l或L
•long a = 10L;
–注意:
•整型常量默认为int,如果是为byte, short,char赋值,如果整型常量的范围在byte,short,char表示的范围,会自动向下转换成byte,short,char,并存储在byte,short变量表示的内存空间中。
•如果为long类型的变量赋值,则可以指定常量10L表示long型;如果使用整型常量,如long l = 100;,则int类型的100会自动向上转换为long类型。如果后面的常量值,超过了int表示的范围,则必须在常量后面加上L或l.
lJava基本数据类型-浮点型
–float:单精度 4B 0.0f或0.0F
–double:双精度 8B 0.0
–一个小数常量,默认是double类型。10.0
–浮点型表示形式:
•十进制形式表示:
•科学计数法: 小数E整数
–//注意:精确的小数运算,使用BigDecimal类
–System.out.println(2.0-1.1);//小数在计算机中,无法表示1/10数值。0.899...
lJava基本数据类型-字符型
–表示字符类型,长度2B。默认值 ‘\u0000’
–在java中,字符类型以unicode编码方式进行编码。以2个字节表示一个字符。
•java中的char类型能否存放中文?为什么?
–在java中,char类型是以unicode编码方式存放,unicode编码是以2个字节表示一个字符。中文,占用2个字节,所以,char能够存放汉字。
–char常量是在’’内,且只能有一个字符。
•‘’,必须有一个字符; ‘a’; ‘中’; ‘ab’;
–char表示的范围:0~65535
–转义字符
•在Java中,有些字符比较特殊。必须要经过转义才可以使用
•如何转义---- \字符
•常见的转义字符?
–\n—换行
–\t----制表符
–\r-----回车
–\\-------\
–\’-------’
–\”-------”
lJava基本数据类型-逻辑性
–仅表示两种状态。boolean的值只有true,false;
–布尔型默认值是false;
l特殊的引用类型- String类型
–表示字符串。由“”括起来,且0个或多个字符。
•“”; “a”; “aaa”;
–String str = “”; String str = “a”; String str = “aaa”;
–注意:
•1-String不是基本数据类型,是引用类型。
•2-String默认的值是null
–String s1 = “”;
–String s2 = null;
l类型转换规则
–1-boolean不能与任何基本数据类型转换。
–2-byte,short,char一般不互相转换。如果参与其他运算,会先自动转换成int类型,再运算.
–3-任何基本数据类型,都可以与String相加.基本类型会先转换成String,与String类型拼接.
–4-类型自动转换(隐式转换):字节数小的可以自动转换成字节数大。
–5-类型强制转换(显式转换),如果字节数大的转换成小的,必须强制转换。强制转换,有可能发生数据溢出,造成错误。
•type1 t = (type1)值;
•如果是浮点型的数据转换成整型,则会出现截尾操作。
–6-多种数据类型混合运算时,小类型自动转换成大类型。
l声明和赋值
–1-可以声明的同时,对变量赋值:int x = 10;
–2-可以先声明,再赋值:int x; x = 10;
–3-可以一行声明多个变量: int x, y, z;由,分隔
–4-一行声明多个变量,且为所有变量或部分变量赋值:由,分隔
int x, y = 10, z, w = 10;
–5-建议:一行只声明一个变量,且在声明的同时,为其初始化。
–6-变量在使用前一定要初始化。
int ii1;//局部变量,在使用前,必须为其赋初始值。
//ii1 = 100;
System.out.println(ii1);//如果不为局部变量赋初始值,则在使用时,编译错误。
–7-变量的命名规则:
•不能用关键字
•最好不要以$,_开头。
•一个单词时,单词小写,多个单词时,第一个单词全部小写,第二个单词首字母大写。
l字符串拼接
字符串拼接,要清楚哪些是可变的,哪些是不变的。可变的要放在“”之外。
ex:
int a = 100; int b = 5; //a+b=15; System.out.println("a + b = " + a + b);//a + b = 105 System.out.println(a + b + " = a + b");//15 = a + b System.out.println("a + b = " + (a + b));//a + b = 15
//10 + 5 = 15 System.out.println(a + " + " + b + " = " + (a + b));
//字符串拼接,要清楚哪些是可变的,哪些是不变的。可变的要放在""之外。 //(a) + (b) = [reslut]; //"(" + a + ") + (" + b + ") = [" + (a + b) + "]"; System.out.println("(" + a + ") + (" + b + ") = [" + (a + b) + "]");
|
l再说常量:
–常量定义的两种形式:
–常量的定义第一种形式:在声明常量时,直接为常量赋值。以后该常量不允许改变 final int AGE = 10; 建议使用此种方式。
–//常量第二种形式:先声明,只允许赋值一次,不能再改变该常量的值。
final int SCORE; SCORE = 90;
–常量的命名规则:
•常量的名称全部大写,如果有多个单词,则多个单词之间用_连接。
final int SCORE = 10; final int MY_SCORE = 100;
–注意:
•以后定义常量,一般是在类中定义。习惯加上static关键字
public static final XXX_XXX_XXX = value;
l运算符:
–赋值运算符
–算术运算符
–关系运算符(比较运算符)
–逻辑运算符
–位运算符
–位移运算符
–条件运算符(三目运算符)
l赋值运算符
–= 将=号右边的值,赋值给=左边的变量。将value存放入变量指向的内存中。
–赋值运算符优先级很低。
–int a = 10;
l算术运算符
–+, -, *, /, %(取模), + , -
•%:可以判断是否能够被整除;判断是某个数的倍数。
•两个整型算除法,结果整型
–自增和自减 ++ 或 --
•a = a + 1;相当于 a++或++a;
•a = a - 1;相当于 a--或--a;
•//++或--位于变量之前,变量先自增或自减,再参与运算
•//++或--位于变量之后,先使用当前变量的值参与运算,变量再自增或自减
–+= -= *= /= %=
•a += b è a = a + b;
•byte,short变量 b1 += b2==》b1 = (byte)(b1 + b2)
l关系运算符
–>, >=, <, <=, ==, !=, instanceof
–比较之后,返回的结果true或false
–== 与 = 区别?
l逻辑运算符
–有短路的逻辑运算符: ! && ||
•! 非: !(10 > 5) – 取反;
•&& condition1 && condition2 --两个条件同时为true,结果为true
•|| condition1 || condition2 –两个条件同时为false,结果为false
–无短路的逻辑运算符: ^ & |
•^:表示异或,两个条件相同为false,不同为true
•&:逻辑与,两个条件,同时为true,结果为true
•|:逻辑或,两个条件,同时为false,结果为false
–比较
•condition1 && condition2:如果1为false,则不再执行2的代码。
•condition1 & condition2:不管1是否为false,2照常执行。
•condition1 || condition2:如果1为true,则不再执行2的代码。
•condition1 | condition2:不管1是否为true,2照常执行。
–condition1 &&(||) condition2 &&(||) condition3….
l位运算符
–~,^,&,|
•~:按位取反
•^:按位异或
•&:按位与
•|:按位或
–位运算符过程
~ 对a的值按位取反,5转换成32位的二进制,按位取反(将二进制位数0-1互换) 运算过程:5=00000000000000000000000000000101 ~5=11111111111111111111111111111010//补码反码 =11111111111111111111111111111001 原码=10000000000000000000000000000110-> -6 & * 5=00000000000000000000000000000101 * 7=00000000000000000000000000000111 *& =00000000000000000000000000000101 | * 5=00000000000000000000000000000101 * 7=00000000000000000000000000000111 *| =00000000000000000000000000000111 ^ -----加密和解密 如果两个数异或的结果,与其中任意一个数异或,则结果是另外一个数。 a = b ^ c, 则 a ^ b = c 或 a ^ c = b 5=00000000000000000000000000000101 7=00000000000000000000000000000111 ^ =00000000000000000000000000000010 a ^ b = c; c ^ a = b; c ^ b = a; |
l移位运算符
–<<, >>, >>>
–<< 有符号的左移 x << n
•高位去掉n位,低位以0补n位,相当于x乘以n个2;
–>> 有符号的右移
•低位去掉n位,高位以符号位补n位,相当于x除以n个2;
–>>>无符号右移
•低位去掉n位,高位以0补n位,相当于x除以n个2;
面试题: 62 - 63 = 1
面试题:使用最有效率的方式,将2变成64 2 << 5
l条件运算符(三目运算符)
–表达式?表达式1(返回值1):表达式2(返回值2);
表达式结果必须为boolean类型。true, false
表达式1和表达式2数据类型必须相同或兼容
如果表达式成立(true),会返回表达式1的值,否则(表达式为false),则返回表达式2的值。
l运算符优先级及总结
运算符的划分:
•+,-,~, ! :单目运算符
•算术运算符,比较运算符… a operator b; 双目运算符
•表达式?value1:value2: 三目运算符。
运算符优先级:
• 优先级不同的,优先级高的先运算;优先级相同的,看结合性。
• 以后在编写代码中,最好使用(),分隔执行的先后顺序。
l流程控制语句
–顺序流程
–选择流程、分支流程
–循环流程
l顺序流程
–main开始,一行一行执行,main方法执行结束,程序退出。
l选择流程
–if(条件表达式)//表达式值为boolean类型
{
//语句…
}
–if(条件表达式)//条件成立,运行语句1;否则,运行语句2
{
//语句1
}
else
{
//语句2
} // ?:
–if(条件)
{
//语句1
}
else if(条件)
{
//语句2
}
else if(条件)
{
//语句3;
}
….
else
{
//语句n
}
•选择流程语句注意点:
–1-if(条件表达式),条件返回true或false。
–2-if或else 后面,可以不使用{},但此时仅仅只对if或else下第一行语句有效。以后,哪怕只有一行语句,必须使用大括号。
•练习:
–1- 通过键盘输入学生的学号,根据学号打印输出名字。1,张三;2,李四;3,王五;其他,不存在。
– 2- 获取键盘输入的分数,根据以下条件打印输出
[100, 90],输出A;
[70, 90), 输出B;
[60, 70), 输出C;
其他 输出D。
l分支结构(选择)
–switch(表达式)//是一个byte,short,char,int类型的值
{
case 常量值1:
语句;
break;
case 常量值2:
语句;
break;
case 常量值3:
语句;
break;
……
default:
语句;
[break;]//可有可无
}
•switch语句使用注意:
–1-option类型只能是byte,short,char, int;在JDK5.0后,enum可以;7.0后String
–2-case子句后面的常量值,必须是char,int类型,在JDK5.0后,enum也可以;7.0后String
–3-case语句块中,根据实际情况,使用break。一般在每个case语句块中都会加上break。break语句用于跳出switch语句块。
–4-default子句,当表达式与case后的常量不匹配的时候,会执行default子句。一般default子句位于最后。default子句后,break语句可有可无。
–5-多个case子句,default子句没有顺序限制。如果default子句不在最末尾,则必须加上break语句。以后不能这么写。
–6-switch语句只能比较离散的数值。if(条件语句),条件语句可以表示一段范围。
•练习:
–1- 获取键盘输入的分数,根据以下条件打印输出
[100, 90],输出A;
[70, 90), 输出B;
[60, 70), 输出C;
其他 输出D。
使用switch语句实现。
f / 10 = 10
[90,99] / 10 = 9
[80,89] / 10 = 8
...
l循环流程
–while
–do…while
–for
–for增强(foreach)
lfor循环
1-先执行表达式1;一般表达式1是初始化变量。
2-再执行条件表达式2;判断循环条件是否成立
3-循环体执行后,执行表达式3;是控制循环变量的。
for循环注意点:
1-表达式1, 2, 3可有可无。for(;;){}表示死循环
2-表达式1, 3可以有多个语句,中间以,分隔。
for(int aa = 0, b = 10; aa < b ; b++, aa++)
{ }
3- 注意循环变量是否仅仅用于控制循环。
lwhile循环和do..while循环
•while
–while(条件表达式)//控制循环条件的,true,则继续循环,否则,退出
{
//循环体,循环的代码
}
•do…while
–do
{
//循环体
}while(条件表达式);
•while循环和do..while循环的区别?
–while循环先判断条件,如果条件成立,则执行循环体,否则,不执行循环体;而do…while,先执行一次循环体,再判断条件。也就说,不管如何,do…while至少会执行一遍循环体。
三种循环语句: for, while, do...while
1- 最常用的是for, while循环
2- 三种循环语句是相通。(同一需求,三种循环都可以实现)
3- while和do..while区别
while循环先判断循环条件,然后再执行循环体。可能一次循环体都不执行。
do..while循环,先执行一遍循环体,然后再判断循环条件。至少会执行一遍循环体。
l循环作业:
–使用while循环和for循环完成以下作业:
•1-打印输出1~100之间偶数的和
•2-打印输出1~100之间3的倍数的值。
•3-打印输出1~100之间7的倍数的和。
•4-打印输出1~1000之间6的倍数的个数。
•5-打印输出1~1000之间3的倍数和7的倍数的和
•6-打印输出1~1000既是3的倍数又是7的倍数的数值。
•7-打印输出1000~2050年中所有的闰年。
–条件: 能被4整除但不能被100整除 或 能被400整除
lbreak, continue
break:
在switch语句中,用于跳出switch语句块。
在循环语句中,用于跳出循环。
continue:
只在循环语句中,表示结束本次循环,进行下次循环。
练习:
求1~1000所有的7的倍数且不能是8的倍数的和,如果和大于200,则退出循环。如果不大于200,则继续循环,累加
分析:
1-使用循环,取得1~1000的数值;
2-判断取得值,是否是7的倍数,如果是,则累加。不是,则判断累加值是否已经超过200。超过200,终止循环;不超200,继续循环,判断。
l循环嵌套
–循环里面,还有循环:
–规律:外循环循环一次,内循环循环一遍。
–通过如右图形式,解释循环嵌套
n循环嵌套练习:
–1- 输出一个长方形-宽10个*,五行。
************
************
************
************
************
–2- 打印输出一个直角三角形
*
**
***
****
*****
–3- 打印9*9乘法表
–4- 输出以下图形。
l流程控制语句练习:
–声明一个double类型变量a,一个float类型变量b,给a赋值2.5,b赋值7.5,计算平方和
–编写程序,采用适当的循环和流控制语句实现下述功能:打印输出0~200之间能被7整除但不能被4整除的所有整数;要求每行显示6个数据
–将下列代数式写成Java表达式
•Ax2+bx+c A*X*X + B*X + C
•(x+y)3
•(a+b)/(a-b)
–编写一个商场用来计算优惠券的程序:创建一个变量totalCost表示消费金额,给totalCost赋值后,使用if-else计算用户可以获得的优惠券,计算规则为:
•当消费金额大于等于200,小于300,可以获20元优惠券
•当消费金额大于等于300,小于500,可以获50元
•当消费金额大于500,可获100元
–打印出100-1000范围内的所有水仙花数。所谓水仙花数是指一个3位数,其各位数字立方和等于该数本身。
例如 153 提示:先取出每位的值
1*1*1 + 5*5*5 + 3*3*3 = 153
–通过编写Java程序,求13-23+33- 43+.......+973-983+993-1003的值
提示:先求出13,33,...993相加总和,再求出23,43,1003总和,相减。
–求1-1000之间可以同时被3、5、7整除的数
l数组
–属于引用类型。String类就是引用类型。
–数组定义:
•具有相同数据类型的,定长的,有序的集合。
•特点:类型必须相同,长度固定,索引。查询快,增删慢。
–数组分类:
•一维数组,二维数组,….
–一维数组:
•数组声明:type[] name; 或 type name[]; 建议使用前者。
•数组的创建:
–1- type[] name = new type[length]; int[] arrs = new int[5];
–2-type[] name = new type[]{元素1, 元素2,…}; int[] arrs = new int[]{1, 2, 3}
»此种情况,创建数组的时候,为数组元素初始化。不能指定长度
–3-type[] name = {元素1, 元素2, …}; int[] arrs = {1, 2, 3, 4};
»此种形式,必须在声明的同时对其初始化。不能够先声明,再静态初始化
•内存结构分析:
–基本数据类型,只在栈上分配内存空间:
–引用数据类型:数组,接口,类。
•数组:type[] name = new type[length];
•声明type[] name –会在栈上分配一块空间。且指定类型为type[];
•创建new type[length]—会在堆上开辟一块连续的length个内存空间。
•= :将堆内存中分配的空间的首地址,存放入栈中。
l数组的说明:
•数组的说明:
–数组是引用类型,其真实值存放在堆内存中。如果不指定堆内存的地址,则值为null。int[] arr = null;
–int[] arr = new int[5]; int[] 表示的是int数组类型,int表示该数组元素的值的类型。且声明数组时,不能指定数组个数int[不能有任何值] arr。
–数组的三种定义方式:
–1- type[] name = new type[length]; int[] arrs = new int[5];
–2-type[] name = new type[]{ 元素1, 元素2,…}; int[] arrs = new int[]{1, 2, 3}
–3-type[] name = { 元素1, 元素2, …}; int[] arrs = {1, 2, 3, 4};
•一旦创建完成,都不可以如下操作: name = { 值1, 值2,….};但可以通过动态的方式重新赋值:name = new int[10];
–int[] arr = new int[5]; 创建数组,如果不为数组中的元素赋初始值,则会使用类型对应的默认值初始化。
byte,short,int,long 0;
float, double 0.0;
boolean false;
char ‘\u0000’
引用类型 null
–数组是有序的,其有序的含义是数组有索引。数组的索引从0开始,数组最大的索引,是其数组长度-1。操作数组,可以通过索引对数组进行赋值和取值。
–使用索引操作数组元素的值时,一定要注意数值的范围[0, length-1],如果超过了数组索引的范围,则会报java.lang.ArrayIndexOutOfBoundsException异常。
–数组对象由一个属性,可以取得数组的长度。 对象.length;
•作业:
–int[] arrs = {8, 7, 9, 3, 5, 6, 1, 2}:求数组中最大值,最小值,最大值索引,最小值索引,数组的和。
–int[] arrs = {8, 7, 9, 3, 5, 6, 1, 2};查找数组中是否包含5这个元素,如果不包含,则程序结束。如果包含,则在第一次5所在位置的前面,插入一个值,该值为10。
–int[] arrs = {8, 7, 9, 3, 5, 6, 1, 2};查找数组中是否包含5这个元素,如果不包含,则程序结束。如果包含,将第一个5删除。
–int[] arrs = {8, 7, 9, 3, 5, 6, 1, 2};查找数组中是否包含5这个元素,如果不包含,则程序结束。如果包含,将数组中第一个5的位置修改成10
•数组的排序:
–冒泡排序
–选择排序
–插入排序
•在实际应用中,很少使用自己的排序方法。Arrays类中,有sort方法。专门对数组进行排序的。该方法效率较高。Arrays.sort(数组);
l二维数组
–Java中,二维数组就是一个一维数组,该一维数组的元素类型是一个数组类型。int[][] arrs ; arrs对象是一个一维数组对象,该对象中的元素类型是int[]。
–二维数组的创建:
•1-int[][] name = new int[3][];//3表示name的长度,即name有三个元素。
•2-int[][] name = new int[3][4];//name长度为3,即name中有三个一维数组元素,每个一维数组元素长度为4。
•3-int[][] name = { {1, 2, 3}, {2}, {2, 3, 4, 5, 6}};
•4-int[][] dimArr4 = new int[][]{ {1, 2}, {2}, {2, 3, 4, 5, 6}};
–二维数组的遍历和赋值。
int[][] name = new int[3][];
•int[][] name = new int[3][4];
int[][] name = { {1, 2}, {2}, {7, 6, 4}};
lString类
–String是个引用类型。表示字符串。由””括起来的0个或多个字符。
–String对象的创建
•1-String s = “abc”;//在常量池中分配内存空间
•2-String s = new String(“abc”);//在堆内存中分配空间
–String对象创建后,不能修改。
•String类是final修饰的,所以其值不能改变。每次为其赋值,都会重新开辟一块内存空间。
–== 和equals方法
•==,如果是两个基本数据类型,比较的是其真实值;如果是两个引用类型,比较的是对应的堆上的内存地址。
•比较两个引用类型真实值是否相同。使用equals方法。
•注意:对于引用类型,如果==为true,则equals一定为true。
–关于String s = “abc”;的说明:String常量池:
•当使用String s = “xxx”;时,首先会在String pool中,寻找是否已经存在”xxx”字符串,如果存在,则将找到的”xxx”字符串所在内存的地址赋值给s;如果不存在,则在pool中,重新分配一块内存,创建该对象,然后,将该内存的地址,赋给s。
•String方法
–length()。数组中,通过length属性,可以得到数组元素的个数;而在字符串中,通过字符串对象的length方法,得到字符串的长度。
•作业:
– 1-统计字符串“2130155974304532604948767654109410457806239”每个元素出现的次数,并打印输出,格式:比如0出现10次, 0-----10
–2-统计字符串”aoipuewqytppewhksdfahkvclkjlksgjdfasdlkncczcvmvcxzmbnsldfsaolifdsajhdfswuretpyoiqyuqlaldsfdskfjkdszlap”每个元素出现的次数。打印如上。
–" aBc EFg " --------> "GFE abc"
•StringBuffer/StringBuilder
–StringBuffer对象可存放允许修改的字符串。使用StringBuffer对象进行字符串的操作更快、效率更高。在一个大的循环里,一般使用StringBuffer代替String
–当对字符串频繁进行连接时,使用StringBuffer或StringBuilder。
reverse():对字符串进行翻转。
•作业
–0- 熟悉StringBuffer, StringBuilder中的方法。
–1- 十进制 -> 二进制。
–2- “102a0d9103kjd98209103n498201mc9304”过滤掉其中的字母,然后将数字倒序显示输出。比如过滤字母后为”123”,显示为”321”
–3-" aBc EFg " --------> "GFE abc"
l类和对象
• 类: 是一组具有相同特性的事物的抽象。类相当于模板。
• 对象:类的一个具体实现。从模板中得到一个实实在在的个体。
• 面向对象编程:在实现逻辑时,都是通过对象来操作的。一切皆对象。
• 对象和类的关系:一个类可以创建多个对象,而一个对象肯定属于某一个类。
•创建类,必须抽取相似事物的共性。共性包含描述(属性,成员变量),功能(成员函数,方法)
Phone(手机类)
实际手机对象的描述信息:静态属性
brand(品牌)
width(宽)
height(高)
num(编号)
price(价格)
color(颜色)
实际手机对象的功能信息:动态方法
call(打电话)
send(发短信)
takePicture(照相)
playGame(玩游戏)
根据以上的抽取,可以创建手机类。
练习:创建一个Car类。
l一个.java文件包含哪些内容?
–package—包
–import ---引入的其它包
–类的定义
{
//属性(类变量(static修饰的属性),和成员变量)
//方法(函数, 静态函数, 构造函数)
//代码块(静态的代码块,代码块)
}
l包
–包在硬盘中,就是文件夹。包主要用于组织和管理类。
–好处:
•1-层级显示类的组织结构,易于查找和使用
•2-可以避免类的重名。在不同包中,可以有相同的文件名。
–包定义:
•使用关键字package。
–package com.itany.basejava……;
–定义包注意点:
•在.java文件中,只能有一个包的声明。
•package只能位于文件的开头。第一行。
•包名全部小写。在实际使用中,一般公司域名倒写。
–com.itany.项目名.模块名..
–com.itany.sms.login
–com.itany.sms.main
–JDK中,常见的包:
•java.lang:基本包,默认在每个.java文件中,已经存在。
•java.io:对流操作
•java.net:网络相关。
•java.sql:与数据库相关
•java.util:工具包
•java.awt:图形界面
•javax.swing:图形界面。
l引入包
–当需要使用其他包中的类时,则通过import引入其他包的类。
•import java.util.Date;
–使用规则:
•1-:可以在使用时,直接通过包名.类名,使用其他包中的类。
–java.util.Date date = new java.util.Date();
–java.util.Arrays.sort(数组);
–此种情况,适合较少使用该类时。
•2-通过Import引入
–import java.util.Date;
–如果当前类,使用很多java.util包中的类。import java.util.*;
–注意:
•1-import语句一般在package之后,在类定义之前。
•2-import可以引入单个类,也可以通过*,引入包中所有的类。
•3-import子句可有可无。
l类定义
–[访问修饰符] [修饰符] class 类名
{
//类的内容
//构造函数,属性,方法,代码块
}
–访问修饰符:private, default, protected, public四种。对于访问修饰符来说,普通定义类的形式只需要使用default,public。如果是内部类,四种访问修饰符都可以使用。.java中,如果一个类由public修饰,则该类的名字要与文件名相同。
–修饰符:描述类的某些特征。在类前,可以使用final, abstract。修饰符可有可无。
–类名:符合标识符的命名规范。首字母大写。
–{}:必须要有{},表示类中的元素。将类的属性,方法,构造函数,代码块均存放与{}中,体现出封装的思想。
l方法简介
–对象所具有的动态功能。在Java中,方法,也叫函数。是实现特定功能的一段代码。
–方法的定义:
[访问修饰符] [修饰符] 返回值类型 方法名(type t1, type t2…)
{
//方法体
}
ex:public static void main(String[] args){}
•访问修饰符:private,default,protected,public。四种均可使用。如果一个方法仅在当前类中使用,一般用private修饰。
•修饰符:一般可以static, final, abstract。可有可无。
•返回值:如果方法有返回值,则在方法体中必须使用”return 返回值“。如果方法没有返回值,则在方法的返回值位置,用void标示。
•方法名:可以为任意的合法标识符。一般一个单词时,使用动词;如果两个或以上时,使用动宾结构,且第二个单词开始,首字母大写。有意义。
•参数列表:可以有0个或多个参数。多个参数时,以”,”分隔。
•{}:大括号中存放方法体。实现该方法功能的具体的代码。
一般将重复性的代码,抽取成方法。可以提高代码复用。
l属性
–对一类事物的静态的描述信息。
–属性,也叫成员变量或实例变量。属性必须定义在类中,可以在类中的任意地方,一般在类的开头部分。
–属性定义:
[访问修饰符] [修饰符] 类型 属性名 = 初始值;
•访问修饰符:private, default, protected, public,四个都可以。一般情况下,属性使用private修饰,然后通过getter和setter得到私有的属性和设置私有的属性值。
•修饰符:描述属性特性的。一般static, final。修饰符可有可无。
•类型:必须存在。可以是任意的类型。
•属性名:符合标识符规则,且有意义。如果有一个单词,单词全部小写;如果有2个或以上的单词组成,第二个单词开始,首字母大写。
•初始值:java中,变量必须要有初始值才能使用。在类中,如果不为属性赋初始值,则系统会自动为其指定初始值。(byte,short,int,long-0; float, double-0.0; char – ‘\u0000’, boolean-false; 引用类型-null )。还可以使用构造方法为其初始化。
•new的时候,会先为类中的属性分配空间,然后再运行构造方法。
l构造函数
–作用:主要在创建对象时,初始化类中的属性。
–定义:
[访问修饰符] 类名([参数列表])
{
//方法体
}
•1-访问修饰符:private,default,protected,public。一般使用public修饰,也可以private修饰。
•2-类名:构造函数的函数名与类名相同。
•3-参数列表:可有可无。有的话,主要为属性初始化。
•4-方法体:构造函数的方法体一般用于为属性赋值。
–构造方法特点:
–1-构造方法主要用于初始化对象。
–2-构造方法无返回值,且方法名与类名相同。
–3-构造方法通常public修饰,也可以由其他访问修饰符修饰。
–4-构造方法可以重载。
–5-构造方法无法手动调用,在new对象时,自动调用构造函数。
–6-每个类中,至少有一个构造方法。如果不显式的写构造方法,则编译器会自动提供一个默认的空的构造方法。提供的该方法没有参数,没有方法体。一旦自定义了一个构造方法,则编译器不再提供空的构造方法。
l创建对象
•创建对象—new
–当需要使用类中的属性或方法时,则需要通过对象访问。
–Student s = new Student([传入的参数值]);通过new关键字创建对象。
–new时:1-在堆上为对象分配内存空间,2-使用类型的默认值为属性赋值,3-调用构造函数,初始化类中的属性值。4- 通过=将堆上的内存地址,存入栈中。
•如何访问类中属性和方法
–一旦对象创建成功后,通过.访问类中的属性和方法。
–每次创建一个对象,则该对象拥有自己的属性。
•Java程序运行的顺序:
–1-程序从main方法开始运行。
–2-如果使用了其他类的方法,则会去执行其他类中的方法,结束后,回到方法调用处,继续向下执行
–…..
–3-main方法运行结束后,程序结束。
ldebug
•Java的调试-debug:进入debug透视图,添加断点,查看变量的值。实际应用中,如果有逻辑上的bug,可以使用断点调试,可以查看变量的值的变化,定位错误。
–作业:编写一个循环语句,通过断点调试,跟踪变量值。
lthis关键字
–this表示当前类的对象或实例(instance)。
–new Student();此时会创建this对象。
–Student s = new Student();先执行new Student();会创建this对象,然后执行=,将this对象指向的堆内存的地址,赋值给s。此时可以说,s就是this对象。
–this关键字的用法:
•1- 取得类中的属性和方法。点取成员。
•2- 构造函数或方法的参数名称与属性名称相同时,通过this点取属性,可以区分同名变量。
•3- 可以作为构造方法,实现初始化属性。在构造方法中,this必须位于第一行。
l成员变量和本地变量
•成员变量(实例变量,属性)和本地变量(局部变量)
成员变量:(在类中定义,访问修饰符 修饰符 type name = value)
–什么是成员变量?
成员变量就是类中的属性。当new对象的时候,每个对象都有一份属性。一个对象中的属性就是成员变量。
–作用范围?
在类内部,任何地方都可以访问成员变量。
–生命周期?(在内存中存在的时间)
出生: new对象的时候,开辟内存空间。
死亡:堆内存地址没有引用,变成垃圾,被垃圾回收器回收后。
局部变量:(修饰符 type name = value)
–什么是局部变量?
方法的形式参数以及在方法中定义的变量。
–作用范围?
形参:在方法体中任何位置都可以访问。
方法中定义变量:从定义处开始,直到所在代码块结束。
–生命周期?(在内存中存在的时间)
出生:运行到创建变量的语句时。
死亡:超过了其作用范围。总结:
注意:
–无论是成员变量或本地变量,在使用前,必须初始化;如果成员变量不为其指定初始值,则用成员变量的类型的对应默认值初始化。但对于局部变量,不会自动使用默认值对其初始化。所以,局部变量在使用前,必须手动初始化。
–成员变量在类中会有访问修饰符;而局部变量不能使用访问修饰符。但两者都可以使用修饰符。
l再说方法(函数)
•方法(函数)详解
–定义:封装特定功能一段代码,用于提高代码的复用以及便于代码管理。
–方法必须在类中定义,方法中不能再定义方法。方法中可以调用其他方法。
•特点
–方法只有被调用的时候,才会执行。如果方法有返回值,则方法执行结束后,返回值交由调用处处理。
–方法的返回值:如果方法有返回值,则在方法体中,必须返回与返回值类型一致的值;如果方法的返回值为void,在方法体中,可以使用return控制方法执行流程,如果return在最后一行,则可以省略不写。
–方法的参数:
•方法定义时的参数,叫形式参数,简称形参。方法在调用处,传入的参数叫做实际参数,简称实参。在调用方法的时候,会将实参赋值给形参,当执行到方法时,会为形参开辟内存空间。
•如何抽取出方法?
–根据功能需求,将不变的共同代码写在方法体中,将可变的内容抽取出,作为方法的参数,值由外部指定。根据需求,判断是否需要返回值以及返回值类型是什么?
–作业:-使用方法实现。
•判断某个数组中是否包含指定值,如果包含,则将该指定值的索引返回,否则返回-1.
•判断某个数组中是否包含指定的值,如果包含,则在该值第一次出现的位置插入10。
•统计字符串中的数值字符出现的次数(如果不是数值字符,过滤掉)
并按照如下格式打印输出
0出现5次
1出现3次
...
•十进制转换成二进制
•判断某个字符串中a出现的次数。
•判断指定的某一年是否为润年
•方法重载
–重载概念:在一个类中,允许函数名相同但参数不同的多个方法。主要为了方便阅读,优化程序设计。
–重载规则:
•方法的名称相同,方法的参数列表不同(参数的类型,参数的个数不同,参数的顺序不同)。
–注意:
•形参的名称不同,不能作为重载的标识。
•函数的返回值不同,也不能作为重载的标识。
–在方法调用时,根据实参的类型,自动匹配调用哪个重载的方法。
构造方法也可以重载。
•注意:以后所有的实现,一定要通过方法实现。不能直接写在main方法中了。
–作业:
•使用面向对象的方式,实现两个数之和。比如10 + 5
l方法的形参和实参
–方法在类中定义时的参数叫形式参数,简称形参。
•形参不分配内存。
–方法在调用时,传入的参数叫实际参数,简称实参
•相当于为形参赋值,此时会分配内存空间。
l值传递和引用传递
–不管哪种传递,都可以看做是栈内存中的值的传递。所以,也可以说,java中所有的传递都是值传递;只是值传递传递的是栈内存中的真实值,而引用传递传递的是栈中堆内存的地址。
–值传递:不改变外部的值。
–引用传递:改变外部的值。
–String是引用类型,但因为String是不可变的。所以,虽然是引用传递,但并不改变外部String的值。
l关键字break,continue,return区别?
–break:在循环和switch语句中使用,表示跳出循环或分支的语句块。
–continue:在循环中使用,表示终止本次循环,继续下次循环。
–return:在方法(函数)中使用,表示方法返回值,犯法的返回值,一定要与方法的返回值类型保持一致。一旦运行到return,方法中,return之后的代码不再执行。
l代码块(非静态代码块)
–在类中通过{}括起来的部分,叫代码块。在代码块中,可以编写程序代码。
–创建对象时,先执行代码块,再执行构造方法。
–每创建一个对象,都会先于构造函数执行一次非静态的代码块。
new对象的时候全部执行过程:
1- 开辟堆内存空间,该对象中自已一份属性以默认值填充
2- 如果有属性赋值语句,执行属性赋值语句,将值赋值给该对象中的属性.否则,不执行。
3- 如果有语句块,再执行语句块,否则,不执行。
4- 再执行构造方法,为对象的属性赋与外部指定的值。
l面向对象三大特性- 封装,继承,多态
l访问修饰符
–访问修饰符:private, default, public
private: 私有的,所有private修饰的类中的元素,只能在本类中使用。
default: 默认的(不写),本类中以及同包的其他类中可以访问。
public: 公有的,项目的任何位置都可以访问。
–设置Java类中属性,方法,构造函数等访问权限。
l封装
–什么是封装?
•Java中将数据封装起来,可以通过提供的公共接口访问。
–Java中封装的体现:
•Java中的类,方法本身就体现封装性。
•通过private封装属性,使用public修饰getter和setter方法访问私有的属性。
–封装的好处?
•1-隐藏对象的实现细节。
•2-保护用户的数据。
•3-方便代码的维护。
l继承
–一个类Son,继承了Father,则该Son就拥有Father类中的能够让其继承下来的属性,方法。
–继承的功能,提高了代码的复用。
–Son类叫子类或派生类;Father叫父类,或超类。
–如何实现继承?
•通过extends关键字实现继承
public class Son extends Father
{
//此时,默认Son中有Father的可被继承下来的属性和方法。
}
•ex:
–类如何抽取?将相似对象中共同的属性和方法抽取,形成类。
–父类:将同一体系中多个类的共性抽取到父类中,个性保留到子类中。
–继承-创建子类对象时,程序的执行顺序。
–如果父类和子类中都包含代码块的话。new Son()对象,执行的顺序是Father中代码块->Father构造方法(相当于创建了一个Fahter对象,super)->Son的代码块->Son的构造方法(创建子类对象)。
–通过继承顺序的分析:在继承中,创建子类对象,必须先创建父类对象,然后再创建子类对象。也就说,创建子类对象,现有父类对象,才能创建子类对象。
–super关键字
–表示当前类的父类对象。通过super可以引用父类的方法,成员变量,以及构造函数。
–super作用:
•super表示父类构造方法时:
–必须放在子类构造方法的第一行。
–默认情况下,子类的构造函数调用是父类的空的构造函数(super())。
–如果父类没有指定空的构造函数,此时,子类构造函数中,必须显式的指定调用父类哪个构造函数。
•super可以点取父类中被子类隐藏的属性。
•super可以点取父类中被子类覆盖(重写)的方法。
–this和super关键字?
–this表示当前类的对象;super表示继承关系中父类的对象。
–this可表示当前类的构造方法,super表示子类中调用父类的构造方法。这两个语句必须放在第一行。
–this. 表示调用本类的属性和方法;super表示在子类中调用父类的属性和方法,super可以解决子类属性和方法与父类属性和方法重名问题。
访问修饰符
–访问修饰符:private, default, protected, public
–设置Java类中属性,方法,构造函数等访问权限。
–使用访问修饰符的原则:不扩大其使用范围。
–继承的特点
–1- Java中类与类之间,只能单继承。
一个类只能有一个父类,而一个父类可以有多个子类。
–2- 类可以有多重继承。
a extends b
b extends c
–3- 构造方法不能被继承。
–4- Object是所有类的直接父类或间接父类。
–继承复用和组合复用
–B is a A :继承复用
–B has a A:组合复用。在实际开发中,使用组合复用比较多。
–方法的重写(覆盖)override
–定义:在继承中,如果子类的某个或多个方法,它的方法名称,返回值类型,以及参数列表与父类中某个或多个方法完全一样,此时,我们就说子类重写(覆盖)了父类的方法。
–方法重写的规则:(必须在继承的结构中)
•1-子类中重写方法,返回值,方法名,参数列表必须与父类中被重写的方法相同。
–参数列表相同含义:与父类中被重写方法的参数的类型,个数,顺序要完全一样。不包含参数的名称
•2-子类中重写的方法不能比父类中被重写的方法的访问权限小。
–也就是说重写方法的访问修饰符要大于等于父类中被重写的方法的访问修饰符。
–private -> default -> protected ->public
•3-子类中重写的方法不能抛出比父类中被重写方法更多的编译时异常。
–overload和override
–overload表示重载;重载可以在一个类中,也可以在继承关系中;重载的规则:方法名相同,参数列表不同(个数,类型,顺序)。
–override表示重写;重写必须在继承中;重写的规则:1, 2, 3
–final修饰符
–表示最终的。可以修饰类,方法,变量。
–final修饰类
•表示该类无法被继承。也就是说,一个被final修饰的类,不能有子类。
–final修饰方法
•表示该方法无法被重写。
–final修饰的变量:表示该变量为常量,只能赋值一次。
•final修饰实例变量
–表示该实例变量为常量,该实例变量必须在声明的同时赋值,如果在声明的时候不赋值,则只能在构造方法中显式的为其赋值。
–注意:凡是在类中定义常量,必须使用public static final XXX_XXX=value;
–演示final修饰引用类型时,常量表示的含义以及修改堆内存中属性值。
•final修饰局部变量
–可以在声明的同时为其赋值,也可以先声明,再进行一次赋值。
–演示final修饰参数时,表示的意思。
l多态
–所谓多态,就是同一行为,有多种表现形式。
–多态的分类:
•编译时多态-重载
•运行时多态
实现多态的条件:
1- 在继承关系;
2- 子类重写父类方法
3- 父类引用子类对象。Father f = new Son();
4- 父类引用名.重写方法真正执行是子类重写后的方法,而不是父类的方法。
–多态的特点:
•1-父类的引用可以指向子类对象。 Father f = new Son();
–int i = ‘a’;
–Father f = new Son();//子类对象自动转换成了父类对象
•2-遵循1的情况下,f对象只能调用Father类中的方法,Father类中如果没有被子类重写,则调用的是Father的方法;如果被子类重写,则调用的是子类重写后的方法。
•3-遵循1的情况下,f不能访问子类对象的特有方法。
•4-遵循1的情况下, 先有Father f = new Son(); ->Son s = (Son)f;将父类强制转换为子类。此时s只能调用子类自己的方法。
–注意:
•多态,方法的多态。对于属性来说,子类属性可以覆盖父类同名属性,但没有多态概念。 Father f = new Son(); f.age 调用的是Father自己的属性。
–实际应用中,多态经常会出现在方法的参数和返回值。
–多态总结
•1- 父类出现的地方,子类就可以出现。(子类自动转换成父类)。
•2-声明什么类型,就只能调用什么类型;
–Father f = new Father(); 此时f只能调用Father类中的方法
–Son s = new Son();此时s只能调用Son类中的方法
–Father f = new Son();此时f只能调用Father类中的方法。
–Son ss = (Son)f;此时ss只能调用Son类中的方法。
•3-创建(new)什么类型,真正执行什么类型内的方法(存在子类重写父类的方法)
–Father f = new Son();此时f如果有被Son重写的方法,则f.test()调用重写的方法,此时,真正执行的是Son中重写的方法。
•4-只有子类自动转换成父类,父类对象才能强制转换成子类。
子类向上转型(upcasting);父类对象向下转型(downcasting).
–instanceof运算符------关系运算符
–对象 instanceof 类型
•判断对象是否属于该类型。如果属于返回true,否则false
–一般用于在强制类型转换前,判断对象是否能强制转换成指定的类型
lObject类
•Object类
–位于java.lang包中。
–类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
–因为Object是所有类的直接或间接父类,所以,Object中的所有方法,其子类都拥有。
•toString()—当直接打印对象时,默认输出的是该对象的toString方法的返回值。
•equals()—通过类比String的比较形式,重写自定义类的equals方法。
–注意:关于Object与数组的关系:
•对于数组元素类型为引用类型的数组来说
–Object obj = strs;//子类转换成父类。将数组整个对象转换成Object对象
–Object[] objs = strs;//将数组中的每个元素转换成对应的Object数组
•对于数组元素类型为基本数据类型的数组来说
–Object obj2 = arrs;//子类转换成父类对象。将数组整个对象转换成Object对象
–Object[] objs2 = arrs;因为int类型没有父类。
lstatic关键字
–static关键字表示静态。能与属性,方法,代码块,内部类等一起使用。
–static修饰属性和方法时,可以直接通过类名.属性或类名.方法来访问。
–静态变量:
•一个类中,静态的变量只分配一块内存空间。多个实例对象共享该内存空间。
•静态的变量在类加载的时候,被初始化。也就是说,只要类被加载,不管是否使用该静态变量,则都会自动的为其开辟空间,并初始化。
–静态方法
•在类加载时,加载到JVM。直接使用类名.方法名调用。
–静态代码块
•是类的组成部分,在类第一次被加载的时候,执行一次。也就说,静态代码块在程序运行时,只能被执行一次。
•用于初始化静态的属性。
static { school = "aaa"; //System.out.println(school); 编译错误。在定义前无法引用school } public static String school = "清华"; 第一种情况: 相当于以下代码: public static String school; static{ school = “aaa”; //syso(school) } school = “清华”; 1-类加载时,为静态属性分配内存空间,且以默认值填充; 2-从上向下执行,先为school赋值aaa,再为school赋值清华 但此时要注意的是,声明语句在静态代码块下面,在静态代码块中的如果获得静态属性的值,则会报错。 |
public static String school = "清华"; static { school = "aaa"; System.out.println(school); System.out.println("静态代码块"); } 第二种情况: 1-类加载时,为静态属性分配内存空间,且以默认值填充; 2-将清华赋值给school 3-执行静态代码块内容。 因为声明在获得school值之前,所以,可以System.out.println(school); |
–static特点:
–1-static可以修饰属性,方法,代码块。此时属性,方法,代码块就变成了类变量,静态方法,静态代码块。注意:静态不能修饰局部变量。
–2-类变量,静态方法,静态代码块与具体某个对象无关,是属于类级别。如果访问权限允许,通过类名.方法名或类名.属性名访问。
–3-静态变量,静态代码块都是在类加载时,执行并初始化。
–4-一个类的静态方法或静态代码块,只能访问静态的属性和静态方法,不能直接访问非静态的属性和方法。对于非静态的方法或代码块,可以直接访问静态的或非静态的属性和方法。
–5-静态方法或静态代码块中,不能使用this,super关键字。因为this,super是对象,对象在静态之后创建的。
–6-静态方法可以被覆盖,但不体现多态;父类如果是静态方法,子类不能覆盖为非静态方法;父类如果是非静态方法,子类不能覆盖为静态方法。
–7-构造方法不允许声明为static。因为构造方法是在创建对象时,自动调用;而static属于类级别的。
–关于静态的用法:
–静态属性:(类变量)
•节省内存空间。但生命周期从类加载分配内存开始,到程序结束。
•实际使用中,当多个对象共享某些数据时,可以将这些设置为静态的变量;定义常量;
–静态方法:
•不需要创建对象,直接通过类名.方法。静态方法中不能使用非静态的属性和方法。
•在实际使用中,定义一些和非静态的属性和方法无关的功能时,使用。比如工具类。
–静态代码块
•在类加载的时候,只运行一次。
•实际的使用中,比较少。比如,JDBC时,数据库驱动的加载,可以放在静态代码块中,仅加载一起,后续就可以直接使用。
lJava中的变量:
•成员变量(实例变量,属性)、本地变量(局部变量)、类变量(静态属性)
成员变量:(在类中定义,访问修饰符 修饰符 type name = value)
–什么是成员变量?
成员变量就是类中的属性。当new对象的时候,每个对象都有一份属性。一个对象中的属性就是成员变量。
–作用范围?
在类内部,任何地方都可以访问成员变量。
–生命周期?(在内存中存在的时间)
出生: new对象的时候,开辟内存空间。
死亡:堆内存地址没有引用,变成垃圾,被垃圾回收器回收后。
局部变量:(修饰符 type name = value)
–什么是局部变量?
方法的形式参数以及在方法中定义的变量。
–作用范围?
形参:在方法体中任何位置都可以访问。
方法中定义变量:从定义处开始,直到所在代码块结束。
– 生命周期?(在内存中存在的时间)
出生:运行到创建变量的语句时。
死亡:超过了其作用范围。总结:
类变量:(访问修饰符 static type name = value)
–什么是类变量?
被static修饰的属性。
–作用范围?
在类变量定义之后。
–生命周期?(在内存中存在的时间)
出生:类加载时,类变量就分配内存空间。
死亡:JVM退出
l类加载的时机:了解
–第一次使用类的信息时,类才被加载到JVM。一般情况下,类加载遵循:延迟加载,能不能加载就不加载。
–类加载的几种情况:
•1-调用静态方法时,会加载静态方法所在的类。如果通过子类调用父类的静态方法时,只会加载父类,不会加载子类。如果子类重写了父类的静态的方法,子类调用该方法,则先加载父类,再加载子类。
•2-加载子类时,肯定会加载父类。
•3-调用静态属性时,会加载属性所在的类。如果属性由final修饰,则不会加载。
•4-仅声明一个引用变量时,不会加载该类;new对象时,会加载类。
l静态属性和非静态属性内存结构分析
l抽象类
•抽象类和抽象方法
–什么是抽象方法?
•如果一个类中的方法,只有方法的定义而没有具体的方法实现,则称该方法为抽象方法。也就是说抽象方法没有方法体。即:没有{}。
–什么是抽象类?
•由abstract修饰的类就是抽象类。
–抽象类的特点:
•1-由abstract修饰的类,就是抽象类。
•2-抽象类中可以有抽象方法,也可以有具体方法及构造方法等。
•3-抽象类不能实例化。只能声明抽象类引用其子类对象使用。
•4-含有抽象方法的类,一定是抽象类;而抽象类不一定包含抽象方法。
•5-抽象类中含有抽象方法,如果其子类没有全部重写抽象方法,则该子类必须被标识为抽象类。
–abstract可以和private, final, static其中一个或多个同时使用吗?
抽象方法和抽象类实现模版模式
1-在抽象类,把固定的内容,存放如一个方法中(final), 在该方法中,不确定部分,调用该抽象类中的抽象方法。
public abstract class Shopping { public final void buy() { System.out.println("我买了东西"); //付钱 pay(); System.out.println("钱已付,东西买完了"); }
public abstract void pay(); } |
2-子类重写该抽象类的抽象方法。
public class China extends Shopping { @Override public void pay() { System.out.println("人民币"); } } |
3-声明抽象类引用具体实现的子类对象;通过抽象类对象.普通方法,此时普通方法中的抽象方法真正执行该子类对象抽象后的内容。
Shopping sh = new China(); sh.buy(); |
打印输出: 我买了东西 人民币 钱已付,东西买完了 |
l接口
–就是一组规范,标准。接口是一组对类功能需求的统一描述。这些类要遵守接口中规定的功能需求。接口可以看作是特殊的抽象类。
–接口如何定义:
•public interface 接口名[与类名命名规则相同]
{
//public static final 修饰的常量----常量
//public abstract修饰的方法--------抽象方法
}
–接口使用(常量和抽象方法)
•接口无法创建实例。使用接口和使用抽象类一样。由子类实现接口,声明接口,指向创建的子类对象。
public class A implements IA
{
//重写接口所有的方法
//如果子类中没有全部实现接口中的方法,则该类必须声明为abstract类
//接口中的方法可以不带public,但子类中重写的方法必须有public
}
IA a = new A();
•在实际编程中,面向接口编程比较常见。
–接口的特性:
–1-接口使用关键字interface定义;接口不是类,但在用法及命名上,和类相似。
–2-接口中,所有的方法都是public abstract修饰的抽象方法;所有的属性都是public static final修饰的静态常量。所以,在接口中,定义常量和方法时,相同的修饰符可省略。
–3- 类通过implements实现接口。一个类要么全部实现接口中所有的抽象方法;要么该类是抽象类。在重写接口中的方法时,public不可省略。
–4-接口不可以用new来实例化,但可以声明一个接口,引用其实现类对象。
–5-一个类只能继承一个类,但可以实现多个接口,多个接口以,分隔。
public class A extends B implements IA, IB, IC….{}。也就是说Java中可以通过接口间接的实现多继承。
–6-类与类之间是单继承,使用关键字extends;接口与接口之间,也是继承,使用extends,且接口与接口可以直接实现多继承;类与接口之间,是实现,使用implements,一个类可以实现多个接口.
–注意:
–接口不是类,但在用法上和类相似。
•1-一个.java文件中,只能由一个public修饰的接口或类。且文件名与接口名或类名相同
2-类与类只有继承且只能继承一个类。类与接口实现,类可以实现多个接口。接口与接口继承,可以继承多个接口。
–简单工厂模式
–简单工厂模式也叫做静态工厂方法模式。
–简单工厂模式组成:
•工厂类角色:本模式的核心,含有一定的商业逻辑和判断逻辑,是由一个具体类实现。
•抽象产品角色:一般是具体产品继承的父类或实现的接口。常常由抽象类或接口表现。
•具体产品角色:工厂类创建的对象就是该角色的实例。一般是个具体类,继承或实现抽象产品角色。
工厂类角色:
public class Factory { public static Fly getFly(String name) { if("Bird".equals(name)) { return new Bird(); } else if("Rocket".equals(name)) { return new Rocket(); } else if("Plane".equals(name)) { return new Plane(); } else { return null; } } } |
抽象产品角色:
public interface Fly { public abstract void fly(); } |
具体产品角色:
public class Plane implements Fly { public void fly() { System.out.println("飞机飞。。"); } }
public class Rocket implements Fly { public void fly() { System.out.println("rocket fly..."); } } |
l接口和抽象类
•接口和抽象类的异同
–接口和抽象类相似,它们都具有如下特征
•接口和抽象类都不能被实例化。只能被其他类实现和继承。
•接口和抽象类都可以包含抽象方法,实现接口和抽象类的类都必须实现这些抽象方法
–接口和抽象类有如下不同
•抽象类与接口定义不同:抽象类abstract class ,接口 interface
•接口里只能包含抽象方法,不包含已经实现的方法;抽象类则完全可以包含普通的方法。
•接口里不能定义静态方法;抽象类可以定义静态方法
•接口里只能定义静态常量属性,不能定义普通属性;抽象类里既可以定义普通属性,也可以定义静态常量
•接口不包含构造函数;抽象类可以包含构造函数,抽象类里的构造函数并不是用于创建对象,而是让其子类调用这些构造函数来完成属于抽象类的初始化操作。
•接口不包含初始化块,但抽象类可以包含初始化块
•一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补java的单继承不足
l包装类
–在Java中,8中基本数据类型,并不符合面向对象的编程机制。他们不属于Object的类层次结构(8中基本数据类型没有父类)。也就是说8种基本数据类型,没有属性和方法。为了让基本数据类型也能像其他引用类型一样,具备面向对象的特性,所以,为8种基本数据类型定义了包装类。
–基本数据类型与对应的包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
–关于8种包装类:
•1-每个包装类都可以与对应的基本数据类型互相转换;且包装类提供了操作该基本类型的方法和属性。
•2-8个包装类都是final修饰的类。它和String一样,创建后,值不可改变。
–基本类型与包装类之间互相转换
–//1-基本类型->包装类int
int i = 10;
Integer ii1 = new Integer(i);//1-通过包装类的构造方法
Integer ii2 = Integer.valueOf(i);//2-valueOf方法
//2-包装类->基本数据类型
int x = ii1.intValue();
–自动装箱和拆箱
–装箱:基本数据类型->包装类
•底层就是使用Integer.valueOf将基本数据类型转换成包装类。
Integer ii = 10;
–拆箱:包装类->基本数据类型
•底层就是使用intValue方法,将Integer -> int
int i = ii;
–Object obj = 1;//int -> Integer -> Object
–享元模式FlyWeight
–String与基本数据类型或包装类之间互相转换。
–基本数据类型可以转换成String类型,以int为例
•String s1 = 10 + "";//1-基本数据类型->String
•String s2 = String.valueOf(10);//2-String.valueOf(基本数据类型对象);
•String s3 = Integer.toString(10);//3-8种包装类.toString(对应的基本数据类型)
–对应的基本数据类型的字符串格式转换成基本数据类型。以int为例
•String ss1 = "10";
•Integer xx = Integer.valueOf(ss1);//将数值型的字符串->int的包装类对象。int y = xx;
•//此时如果ss1对象不是数值型的字符串会报NumberFormatException。
•int i = Integer.parseInt(ss1);//String->int NumberFormatException。
•字符串和byte[]数组转换,char数组的转换
//1-按照默认的码表对字符进行编码或解码 String str1 = "中国人"; byte[] bs1 = str1.getBytes();//String -> byte[] 编码 String str2 = new String(bs1);//byte[] -> String 解码 System.out.println(str2); String ss1 = new String(bs1, 3, 3);//部分解码 System.out.println("============" + ss1); //3.2-按照指定的码表对字符进行编码或解码 byte[] bs2 = str1.getBytes("GBK");//字符按照GBK码表进行编码 String str3 = new String(bs2, "GBK");//字节按照GBK码表进行解码 System.out.println(str3); String ss2 = new String(bs2, 2, 2, "GBK"); System.out.println("************" + ss2);
//4- String与字符数组之间互相转换 String str = "abcdedfg"; char[] cs1 = str.toCharArray();//String -> char[] String str4 = new String(cs1);//char[] -> String String ss3 = new String(cs1, 2, 4); System.out.println(ss3); |
l单态模式
一个类只允许有一个对象。
单态设计模式:- 饿汉式单态模式。 一个类,只能创建一个对象。 分析: 1- 外部创建类的对象,必须调用构造方法。想控制外部创建对象,可以不让外部访问构造方法。 2- 私有化构造方法之后,构造方法只能在本类使用。此时,只能在本类中创建该类的对象。 3- 将本类中创建的对象,对外部提供一个公共的方法,让外部得到该对象。 4- 将该方法设置为静态的,让外部直接通过类名访问。 5- 因为静态方法中只能调用当前类中静态的属性和静态方法。所以,创建的类也必须为静态的,才能在getInstance静态方法中使用。 实现步骤: 1- 私有化构造方法。 2- 本类中创建当前类的对象。 3- 创建一个方法,返回本类中创建对象。 4- 设置上面方法为static 5- 设置对象为静态的 public class Singleton{ //2- 本类中创建当前类的对象。 //5- 设置对象为静态的 private static Singleton instance = new Singleton(); //1- 私有化构造方法 private Singleton(){} //3- 创建一个方法,返回本类中创建对象。 //4- 设置上面方法为static public static Singleton getInstance() { return instance; } } |
public class Singleton2{ private static Singleton2 instance = null; private Singleton2(){} public static Singleton2 getInstance() { if(instance == null) { instance = new Singleton2(); } return instance; } } |
单态模式扩展
创建工具类:
工具类特征:
1- 所有方法都是静态方法 static修饰方法。
2- 工具类外部不能创建对象 私有化构造函数。
3- 工具类不能有子类。 final修饰工具类。
lJDK1.5新特性
–自动装箱和拆箱
•Object obj = 1;
–增强for循环
–静态导入
import static java.util.Arrays.sort;可以直接使用静态方法。
–可变参数
定义形式: type. . . 可变参数的名字
在定义的时候,可变参数就是数组。但在使用的时候,比数组灵活。
可变参数可以表示0个或多个该type类型的参数。
注意:
当方法参数列表为多个参数的时候,可变参数必须位于最后。
public static int add(int... arrs) { int sum = 0; for(int x : arrs) { sum += x; } return sum; } //方法二 public static int add(int x, int y) { System.out.println("========="); return x + y; } |
在调用可变参数的方法时: int[] arrs = {4, 1, 9, 2, 6, 3, 8}; int sum1 = add(arrs); int sum2 = add();//new int[]{} int sum3 = add(1);//new int[]{1} int sum4 = add(1, 2);//new int[]{1, 2} int sum5 = add(1, 2, 3, 4, 5);//new int[]{1,2,3,4,5} 此时,如果有方法二这样的函数,调用int sum4 = add(1, 2);优先考虑与之最匹配的方法。 |
–枚举
•当一个类只有固定个数的对象时,可以使用枚举类型。枚举就是一个类
[访问修饰符] enum 枚举名字
{
该类型的对象,可以有多个对象,且以逗号分隔,最后以分号 结束
枚举的每个元素,都是该类的静态常量。
}
ex
public enum Weekday
{
MON, TUS, WEN, THI, FRI, SAT, SUN;
}
注意:
1-枚举其实就是一个类,且该类构造方法私有。
2-枚举的值,必须是当前类的对象,且该对象是静态常量。
3- 枚举在switch语句中使用。
enum MySeason { SPRING, SUMMER, AUTUMN, WINTER; } |
MySeason summer = MySeason.SUMMER; switch(summer) { case SPRING: System.out.println("aaaaaaaaa"); break; case SUMMER: System.out.println("bbbbbb"); break; case AUTUMN: System.out.println("cccccc"); break; case WINTER: System.out.println("ddddddd"); break; } |
l日期类
–Date
•从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和解析日期字符串。Date 中的相应方法已废弃。
–DateFormat(抽象类)->子类SimpleDateFormat
•它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。
•Date->String, String->Date
–Calendar
•Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法 .
•Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象
•作业:
–1-打印输出2012年3月11日是星期几?
步骤:
1-String -> Date(使用SimpleDateFormat的parse方法)
2-Date -> String (使用SimpleDateFormat的format方法 E)
–2-计算当前日期一年前的日期,按照2010-11-12 12时12分12秒120毫秒样式显示。
1.得到当前日期:Calendar.getIntstance();
2.通过Calendar.add(year, -1)
3.Calendar -> Date
4.SimpleDateFormat -> String 显示
–3-计算2013年11月1号11:9:20 123到2008年7月3号12:19:22 777,中间隔了多少年多少月多少天多少小时多少分钟多少秒多少毫秒
lMath、Random、System类
–Math 类包含用于执行基本数学运算的方法:round, max, min, random等方法。
–Random类:此类的实例用于生成伪随机数流。
–System类:
•exit(int i)表示JVM退出,如果非0,表示异常退出。
•arraycopy();表示数组的复制。
lArrays工具类
–此类包含用来操作数组(比如排序和搜索)的各种方法。
–sort()对数组进行排序
–binarySearch();二分法查找,在对数组排序之后,才能二分法查找。
–toString(数组对象):打印输出的元素。
–练习:
–对Student对象按照学生对象的年龄排序。