Win7下如何打开DOS控制台?
- a:开始--所有程序--附件--命令提示符
- b:开始--搜索程序和文件--cmd--回车
- c:win+r--cmd--回车
常见的DOS命令
- d: 盘符切换
- dir (directory)列出当前目录下的文件以及文件夹
- cd (change directory)改变指定目录(进入指定目录)
- cd.. 退回到上一级目录
- cd\ 退回到根目录
- cls (clear screen)清屏
- exit 退出dos命令行(分割线上的需要掌握,下的了解)
Java语言跨平台原理
- a:什么是跨平台性
- 通过Java语言编写的应用程序在不同的系统平台上都可以运行
- b:Java语言跨平台原理
- 只要在需要运行java应用程序的操作系统上,先安装一个Java虚拟机(JVM Java Virtual Machine)即可。由JVM来负责Java程序在该系统中的运行。
-
c:Java语言跨平台图解
JRE和JDK的概述
- a:什么是JRE
- 包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。
- JRE:JVM+类库。
- b:什么是JDK
- JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。所以安装了JDK,就不用在单独安装JRE了。
- 其中的开发工具:编译工具(javac.exe) 打包工具(jar.exe)等
- JDK:JRE+JAVA的开发工具。
- c:为什么JDK中包含一个JRE呢?
- 开发完的程序,需要运行一下看看效果。
- d:JDK,JRE,JVM的作用和关系
Java语言的书写格式(约定俗成)
- 1.大括号要对齐,并且成对写
- 2.左大括号前面有空格
- 3.遇到左大括号要缩进,Tab
- 4.方法和程序块之间加空行让程序看起来清晰
- 5.并排语句之间加空格,例如for语句
- 6.运算符两侧加空格
关键字的概述和使用
- a:什么是关键字
- 被Java语言赋予特定含义的单词
- b:关键字的特点
- 组成关键字的字母全部小写
- c:常见关键字
- public static void class等
标识符的概述和组成规则
标识符的概述和组成规则)(掌握)
- a:什么是标识符
- 就是给类,接口,方法,变量等起名字时使用的字符序列
- b:标识符的组成规则
- 英文大小写字母
- 数字字符
- $和_
- c:标识符注意事项
- 1,不能使用关键字
- 2,不能数字开头
标识符中常见的命名规则
- 见名知意
- a:包
- 最好是域名倒过来,要求所有的字母小写
- b:类或者接口
- 如果是一个单词首字母大写
- 如果是多个单词每个单词首字母大写(驼峰标识)
- c:方法或者变量
- 如果是一个单词全部小写
- 如果是多个单词,从第二个单词首字母大写
- d:常量
- 如果是一个单词,所有字母大写
- 如果是多个单词,所有的单词大写,用下划线区分每个单词
常量的概述和使用
- A:什么是常量
- 在程序执行的过程中其值不可以发生改变
- B:Java中常量的分类
- 字面值常量
- 自定义常量(面向对象部分讲)
- C:字面值常量的分类
- 字符串常量 用双引号括起来的内容
- 整数常量 所有整数
- 小数常量 所有小数
- 字符常量 用单引号括起来的内容,里面只能放单个数字,单个字母或单个符号,如:
System.out.println('10'); 编译错误 '10'必须放单个字符,10代表的是1字符和0字符;
System.out.println(''); 编译错误 ''中什么也不放,不能代表任何字符;
System.out.println(' '); 编译成功 ' '中代表空格字符; - 布尔常量 较为特殊,只有true和false
- 空常量 null(数组部分讲解)
任意进制到十进制的转换图解
十进制到任意进制的转换图解
快速的进制转换法
原码反码补码
- 原码
- 就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
- 通过一个字节,也就是8个二进制位表示+7和-7
- 0(符号位) 0000111
- 1(符号位) 0000111
- 反码
- 正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
- 补码
-
正数的补码与其原码相同;负数的补码是在其反码的末位加1。
-
变量的概述及格式
- A:什么是变量
- 在程序执行的过程中,在某个范围内其值可以发生改变的量
- B:变量的定义格式
- 数据类型 变量名 = 变量值;
- C:为什么要定义变量
- 用来不断的存放同一类型的常量,并可以重复使用
数据类型的概述和分类
- A:为什么有数据类型
- Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间
- B:Java中数据类型的分类
- 基本数据类型
- 引用数据类型
- 面向对象部分讲解
- C:基本数据类型分类(4类8种)
- 整数型
- byte 占一个字节 -128到127
- short 占两个字 -215~215-1
- int 占四个字节 -231~231-1 (整数默认的数据类型)
- long 占八个字节 -263~263-1 (如果long类型加L进行表示最好加大写的L,因为小写的l和1太像了 long x = 888888888L;【用L标示,要不然会报错,因为整数默认为int类型,888888888超过了int范围】)
- 浮点型
- float 占四个字节 -3.403E38~3.403E38 单精度 (float f = 12.3F;小数默认的数据类型为double,直接赋值会损失精度,要加上F进行标示)
- double 占八个字节 -1.798E308~1.798E308 双精度 (小数默认的数据类型)
- 字符型
- char 占两个字节 0~65535
- 布尔型
- boolean true 和 false
- boolean理论上是占八分之一个字节,因为一个开关就可以决定是true和false了,但是java中boolean类型没有明确指定他的大小
- 整数型
使用变量的注意事项
- a:作用域问题
- 同一个区域不能使用相同的变量名
- b:初始化值问题
- 局部变量在使用之前必须赋值
- c:一条语句可以定义几个变量
- int a,b,c...;
数据类型转换之隐式转换
- Java中的默认转换规则
-
取值范围小的数据类型与取值范围大的数据类型进行运算,会先将小的数据类型提升为大的,再运算
-
数据类型转换之强制转换
- A:强制转换问题
- int a = 10;
- byte b = 20;
- b = a + b;
- B:强制转换的格式
-
b = (byte)(a + b);
- C:强制转换的注意事项
-
如果超出了被赋值的数据类型的取值范围得到的结果会与你期望的结果不同
面试题之变量相加和常量相加的区别
- 面试题:看下面的程序是否有问题,如果有问题,请指出并说明理由。
- byte b1 = 3;
- byte b2 = 4;
- byte b3 = b1 + b2;
- 从两方面去回答这个题
- b1和b2是两个变量,变量里面存储的值都是变化的,所以在程序运行中JVM是无法判断里面具体的值
- byte类型的变量在进行运算的时候,会自动类型提升为int类型
- byte b4 = 3 + 4;
- 3和4都是常量,java有常量优化机制,就是在编译的的时候直接把3和4的结果赋值给b4了
long与float的取值范围谁大谁小
-
进行混合运算的时候,byte,short,char不会相互转换,都会自动类型提升为int类型,其他类型进行混合运算的是小的数据类型提升为大的
- byte,short,char -- int -- long -- float -- double
- long: 8个字节
- float: 4个字节
- IEEE754规定
- 4个字节是32个二进制位,其中
- 1位是符号位
- 8位是指数位
- 00000000 11111111
- 0到255
- 1到254
- -126到127
- 23位是尾数位
- 每个指数位减去127
A:它们底层的存储结构不同。
-
B:float表示的数据范围比long的范围要大
- long:2^63-1
- float:3.410^38 > 210^38 > 28^38 = 22338 = 2*2^114 > 2^63-1
字符和字符串参与运算
- System.out.println('a'); ===> 输出a字符
- System.out.println('a'+1); ===> 输出98,因为a的ASCII码是97
- System.out.println(char('a'+1)); ===> 输出b,因为b的ASCII码是98
- System.out.println("hello"+'a'+1); ===> 输出helloa1,因为任何数据类型用+ 与字符串相连接都会生成新的字符串
- System.out.println('a'+1+"hello"); ===> 输出98hello
- D:+在有字符串参与中被称为字符串连接符
- System.out.println("5+5="+5+5); ===> 输出5+5=55
- System.out.println(5+5+"=5+5"); ===> 输出10=5+5
char数据类型
- Java语言中的字符char可以存储一个中文汉字吗?为什么呢?
- 可以。因为Java语言采用的是Unicode编码。Unicode编码中的每个字符占用两个字节。中文也是占的两个字节
- 所以,Java中的字符可以存储一个中文汉字
算术运算符的基本用法
- A:什么是运算符
- 就是对常量和变量进行操作的符号。
- B:运算符的分类
- 算术运算符,赋值运算符,比较(关系或条件)运算符,逻辑运算符,位运算符,三目(元)运算符
- C:算数运算符有哪些
- +,-,*,/,%,++,--
- D:注意事项:
- a: +号在java中有三种作用,代表正号,做加法运算,字符串的连接符
- b: 整数相除只能得到整数。如果想得到小数,必须把数据变化为浮点数类型
10 / 3 = 3
10 / 3.0 = 3.3333333....(把其中一个数变成小数,另一个数在运算的时候会自动类型提升) - c: /获取的是除法操作的商,%获取的是除法操作的余数
- %运算符
- 当左边的绝对值小于右边绝对值时,结果是左边
1 / 5 = 1 - 当左边的绝对值等于右边或是右边的倍数时,结果是0
5 / 5 = 0 - 当左边的绝对值大于右边绝对值时,结果是余数
7 / 5 = 2 - %运算符结果的符号只和左边有关系,与右边无关
-12 / 5 = -12 / (-5) = -2 - 任何一个正整数%2结果不是0就是1可以用来当作切换条件
1 / 2 = 1 2 / 2 = 0 3 / 2 = 1 4 / 2 = 0
算术运算符++和--的用法
- a: 单独使用:
- 放在操作数的前面和后面效果一样。(这种用法是我们比较常见的)
- b: 参与运算使用:
- 放在操作数的前面,先自增或者自减,然后再参与运算。
- 放在操作数的后面,先参与运算,再自增或者自减。
int a = 10;
int b = 10;
int c = 10;
a = b++; // a = 10; b = 11
c = --a; // c = 9; a = 9
b = ++a; // b = 10; a = 10
a = c--; //a = 9; c = 8 - 请分别计算出x,y的值?
int x = 4;
int y = (x++)+(++x)+(x10); // y = 4 + 6 + 6 10 = 70; x = 6 - 面试题
byte b = 10;
① b++;
② b = b + 1;
问哪句会报错,为什么
第二句会报错 , 因为b++底层会自动加强转换符【b=(byte)(b+1)】; 而当byte 与 int 进行混合运算的时候,会提升为int类型, 两个int相加的结果还是int, 赋值给byte会损失精度
赋值运算符的基本用法
- A:赋值运算符有哪些
-
a:基本的赋值运算符:=
- 把=右边的数据赋值给左边。
-
b:扩展的赋值运算符:+=,-=,*=,/=,%=
- += 把左边和右边做加法,然后赋值给左边。
-
关系运算符及其注意事项
- 关系运算符有哪些(比较运算符,条件运算符)
- ==,!=,>,>=,<,<=
- 注意事项:
- 无论你的操作是简单还是复杂,结果是boolean类型。
- "=="不能写成"="。
逻辑运算符的基本用法
- A:逻辑运算符有哪些
- &,|,^,!
- &&,||
- B:案例演示
-
逻辑运算符的基本用法
- 注意事项:
- a:逻辑运算符一般用于连接boolean类型的表达式或者值。
- b:表达式:就是用运算符把常量或者变量连接起来的符合java语法的式子。
- 算术表达式:a + b
- 比较表达式:a == b(条件表达式)
- C:结论:
- &逻辑与:有false则false。
- |逻辑或:有true则true。
- ^逻辑异或:相同为false,不同为true。
- !逻辑非:非false则true,非true则false。
- 特点:偶数个不改变本身。
逻辑运算符&&和&的区别(|| 与 | 同理)
- a:最终结果一样。
- b:&&具有短路效果。左边是false,右边不执行。
-
&是无论左边是false还是true,右边都会执行
位运算符的基本用法
- A:位运算符有哪些
- &,|,^,~ ,>>,>>>,<<
- B:案例演示
-
位运算符的基本用法1
- &,|,^,~ 的用法
- &:有0则0
- |:有1则1
- ^:相同则0,不同则1
- ~:按位取反
-
位运算符的基本用法2
三元运算符的格式
- (关系表达式) ? 表达式1 : 表达式2;
键盘录入的基本格式
- A:为什么要使用键盘录入数据
- a:为了让程序的数据更符合开发的数据
- b:让程序更灵活一下
- B:如何实现键盘录入呢?
- 先照格式来。
- a:导包
- 格式:
- import java.util.Scanner;
- 位置:
- 在class上面。
- b:创建键盘录入对象
- 格式:
- Scanner sc = new Scanner(System.in);
- c:通过对象获取数据
- 格式:
- int x = sc.nextInt();
选择结构if语句注意事项
- a:比较表达式无论简单还是复杂,结果必须是boolean类型
- b:if语句控制的语句体如果是一条语句,大括号可以省略;
- 如果是多条语句,就不能省略。建议永远不要省略。
- c:一般来说:有左大括号就没有分号,有分号就没有左大括号
if语句和三元的相互转换问题
- if语句和三元运算符的区别
- 三元运算符实现的,都可以采用if语句实现。反之不成立。
- 什么时候if语句实现不能用三元改进呢?
- 当if语句控制的操作是一个输出语句的时候就不能。
- 为什么呢?因为三元运算符是一个运算符,运算符操作完毕就应该有一个结果,而不是一个输出。
选择结构switch语句
switch(表达式) {
(表达式可以接收:
基本数据类型:byte、short、char、int
引用数据类型:枚举(JDK1.5)String字符串(JDK1.7)
)
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
…
default:
语句体n+1;
break;
}
选择结构switch语句的注意事项
- a:case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的
- b:default可以省略吗?
- 可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。
- 特殊情况:
- case就可以把值固定。
- A,B,C,D
- c:break可以省略吗?
- 最后一个可以省略,其他最好不要省略
- 会出现一个现象:case穿透。
- 最终我们建议不要省略
- d:default一定要在最后吗?
- 不是,可以在任意位置。但是建议在最后。
- e:switch语句的结束条件
- a:遇到break就结束了
- b:执行到switch的右大括号就结束了
选择结构switch语句练习
A:看程序写结果:---------y=4
int x = 2;
int y = 3;
switch(x){
default:
y++;
break;
case 3:
y++;
case 4:
y++;
}
System.out.println("y="+y);B:看程序写结果:--------y=6
int x = 2;
int y = 3;
switch(x){
default:
y++;
case 3:
y++;
case 4:
y++;
}
System.out.println("y="+y);
方法的概述
- 方法:就是完成特定功能的代码块。
- 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法。
- 方法重载
- 在同一个类中,方法名相同,参数列表不同。与返回值无关。
参数列表不同: 参数的个数不同; 参数的对应的数据类型不同。
- 在同一个类中,方法名相同,参数列表不同。与返回值无关。
数组概述和定义格式说明
A:为什么要有数组(容器)
为了存储同种数据类型的多个值
B:数组概念
数组是存储同一种数据类型多个元素的集合。也可以看成是一个容器。
数组既可以存储基本数据类型,也可以存储引用数据类型。
C:数组定义格式
数据类型[] 数组名 = new 数据类型[数组的长度];
数组的初始化动态初始化
A:什么是数组的初始化
就是为数组开辟连续的内存空间,并为每个数组元素赋予值
B:如何对数组进行初始化
a:动态初始化 只指定长度,由系统给出初始化值
int[] arr = new int[5];
b:静态初始化 给出初始化值,由系统决定长度
C:动态初始化的格式:
数据类型[] 数组名 = new 数据类型[数组长度];
D:案例演示
-
输出数组名称和数组元素
整数类型: byte,short,int ,long 默认初始化值都是0 浮点类型: float,double默认初始化值都是0.0 布尔类型: boolean默认初始化值是false 字符类型: char 默认初始化值是'\u0000'【char在内存中占两个字节,是16个二进制位,\u0000,,每个0都代表16进制的0,那么 四个0就代表16个二进制位】
Java中的内存分配以及栈和堆的区别
A:栈(掌握) (先进后出, 相当于抢里的子弹): 存储局部变量 【局部变量: 定义在方法声明上和方法中的变量】
B:堆(掌握) : 存储new出来的数组或对象
C:方法区: 面向对象部分讲解
D:本地方法区: 和系统相关
E:寄存器: 给CPU使用
注意:
a:局部变量 在方法定义中或者方法声明上定义的变量。
b:栈内存和堆内存的区别
栈:数据使用完毕,就消失。
堆:每一个new出来的东西都有地址
每一个变量都有默认值
byte,short,int,long 0
float,double 0.0
char '\u0000'
boolean false
引用类型 null
数据使用完毕后,在垃圾回收器空闲的时候回收。
数组的初始化静态初始化及内存图
- A:静态初始化的格式:
- 格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
- 简化格式:声明和赋值在同一行
- 数据类型[] 数组名 = {元素1,元素2,…};
- B:案例演示
- 对数组的解释
- 输出数组名称和数组元素
- C:画图演示
- 一个数组
数组越界和空指针
- a:ArrayIndexOutOfBoundsException:数组索引越界异常
- 原因:你访问了不存在的索引。
- b:NullPointerException:空指针异常
- 原因:数组已经不在指向堆内存了。而你还用数组名去访问元素。
int[] arr = {1,2,3};
arr = null;
System.out.println(arr[0]);
数组遍历
- 数组遍历:就是依次输出数组中的每一个元素。
- 数组的属性:arr.length数组的长度
- 数组的最大索引: arr.length - 1;
public static void print(int[] arr) {
for (int i = 0;i < arr.length ;i++ ) {
System.out.print(arr[i] + " ");
}
}
数组获取最值
- 数组获取最值(获取数组中的最大值最小值)
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1;i < arr.length ;i++ ) { //从数组的第二个 元素开始遍历
if (max < arr[i]) { //如果max记录的值小于的数组中的元素
max = arr[i]; //max记录住较大的
}
}
return max;
}
数组反转
- 数组元素反转(就是把元素对调)
// 1. 明确返回值类型void
// 2. 明确参数列表int[] arr
public static void reverseArray(int[] arr) {
for (int i = 0;i < arr.length / 2 ; i++) {
//arr[0]和arr[arr.length-1-0]交换
//arr[1]和arr[arr.length-1-1]交换
//arr[2]和arr[arr.lentth-1-2]
//...
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
数组查表法
- 数组查表法(根据键盘录入索引,查找对应星期)
public static char getWeek(int week) {
char[] arr = {' ','一','二','三','四','五','六','日'}; //定义了一张星期表
return arr[week]; //通过索引获取表中的元素
}
数组基本查找
- 数组元素查找(查找指定元素第一次在数组中出现的索引)
public static int getIndex(int[] arr,int value) {
for (int i = 0;i < arr.length ;i++ ) { //数组的遍历
if (arr[i] == value) { //如果数 组中的元素与查找的元素匹配
return i;
}
}
return -1;
}
二维数组概述和格式
A:二维数组格式1
数据类型[][] 数组名 = new 数据类型[m][n];
int[][] arr = new int[3][2]; 【 二维数组中有3个一维数组,每个数组中有2个元素】
B:二维数组格式1的解释
C:注意事项
a:以下格式也可以表示二维数组
1:数据类型 数组名[][] = new 数据类型[m][n];
2:数据类型[] 数组名[] = new 数据类型[m][n];
-
B:注意下面定义的区别
int x;
int y;
int x,y;int[] x; int[] y[]; int[] x,y[]; x是一维数组,y是二维数组
二维数组遍历
外循环控制的是二维数组的长度,其实就是一维数组的个数。
-
内循环控制的是一维数组的长度。
int[][] arr = {{1,2,3},{4,5},{6,7,8,9}}; for (int i = 0;i < arr.length ;i++ ) { //获取到每个二维数组中的一维数组 for (int j = 0;j < arr[i].length ;j++ ) { //获取每个一维数组中的元素 System.out.print(arr[i][j] + " "); } System.out.println(); }
Java中的参数传递问题及图解
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a:"+a+",b:"+b);
change(a,b);
System.out.println("a:"+a+",b:"+b);
int[] arr = {1,2,3,4,5};
change(arr);
System.out.println(arr[1]);
}
public static void change(int a,int b) {
System.out.println("a:"+a+",b:"+b);
a = b;
b = a + b;
System.out.println("a:"+a+",b:"+b);
}
public static void change(int[] arr) {
for(int x=0; x<arr.length; x++) {
if(arr[x]%2==0) {
arr[x]*=2;
}
}
}
基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失
引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内层数组对象还在,可以通过地址继续访问
Java中到底是传值还是传址
java中只有传值, 因为地址值也是值(支持者高司令----java)
面向对象特征
- 封装(encapsulation)
- 继承(inheritance)
- 多态(polymorphism)
面向对象与面向过程的区别
- 面向对象:
- 找回摊煎饼的老大妈(老大妈包含: 摊煎饼的技术,做煎 饼)
- 给钱
- 吃
- 面向过程:
- 学习摊煎饼的技术
- 买材料薄脆,油,面粉....
- 开始摊
- 吃
- 收拾
类和对象的概念
- a:类:是一组相关的属性和行为的集合
- b:对象:是该类事物的具体体现
- 我们如何描述现实世界事物
- 属性 就是该事物的描述信息(事物身上的名词)
- 行为 就是该事物能够做什么(事物身上的动词)
- Java中最基本的单位是类,Java中用class描述事物也是如此
- 成员变量 就是事物的属性
- 成员方法 就是事物的行为
如何使用对象?
- 创建对象并使用
- 格式:类名 对象名 = new 类名();
- 对象名: 其实就是标准的标识符,如果是一个单词所有字母小写,如果是多个单词, 从第二个的单词开始首字母大写
- 如何使用成员变量呢?
- 对象名.变量名
- 如何使用成员方法呢?
- 对象名.方法名(...)
成员变量和局部变量的区别
A:在类中的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
成员变量:在堆内存(成员变量属于对象,对象进堆内存)
局部变量:在栈内存(局部变量属于方法,方法进栈内存)
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
注意事项:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
基本数据类型变量包括哪些:byte,short,int,long,float,double,boolean,char
引用数据类型变量包括哪些:数组,类,接口,枚举
方法的形式参数是类名的时候如何调用
- A:方法的参数是类名public void print(Student s){}//print(new Student());
-
如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
匿名对象的概述和应用
- A:什么是匿名对象
- 没有名字的对象
- B:匿名对象应用场景
- a:调用方法,仅仅只调用一次的时候。
- 那么,这种匿名调用有什么好处吗?
- 节省代码
- 注意:调用多次的时候,不适合。匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
- b:匿名对象可以作为实际参数传递
-
C:匿名对象可以调用属性, 但是没有意义,因为调用后就变成了垃圾,如果需要赋值的还是使用有名字的对象
封装的概述
A:封装概述
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
B:封装好处
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性。
C:封装原则
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问。
private关键字的概述和特点
- A:private关键字特点
- a:是一个权限修饰符
- b:可以修饰成员变量和成员方法
- c:被其修饰的成员只能在本类中被访问
- B:案例演示
- 封装和private的应用:
- a:把成员变量用private修饰
- b:提供对应的getXxx()和setXxx()方法
- private仅仅是封装的一种体现形式,不能说封装就是私有
this关键字的概述和应用
- A:this关键字特点
- 代表当前对象的引用
- B:案例演示
- this的应用场景
- 用来区分成员变量和局部变量重名
构造方法Constructor概述和格式
- A:构造方法概述和作用
- 给对象的数据(属性)进行初始化
- B:构造方法格式特点
- a:方法名与类名相同(大小也要与类名一致)
- b:没有返回值类型,连void都没有
- c:没有具体的返回值return;
构造方法的重载及注意事项
- A:案例演示
- 构造方法的重载
- 重载:方法名相同,与返回值类型无关(构造方法没有返回值),只看参数列表
- B:构造方法注意事项
- a:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
- b:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
- 注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
给成员变量赋值的两种方式的区别
- A:setXxx()方法
- 修改属性值
- B:构造方法
-
给对象中属性进行初始化
- C:给成员变量赋值:
- a:setXxx()方法
- b:构造方法
- D:输出成员变量值的方式:
- a:通过getXxx()分别获取然后拼接
- b:通过调用show()方法搞定
画图说明一个对象的创建过程做了哪些事情?
-
Student s = new Student();
1,Student.class加载进内存
2,声明一个Student类型引用s
3,在堆内存创建对象,
4,给对象中属性默认初始化值
5,属性进行显示初始化
6,构造方法进栈,对对象中的属性赋值,构造方法弹栈
7,将对象的地址值赋值给s
static关键字及内存图
static关键字的特点
- a:随着类的加载而加载
- b:优先于对象存在
- c:被类的所有对象共享
- 举例:咱们班级的学生应该共用同一个班级编号。
- 其实这个特点也是在告诉我们什么时候使用静态?
- 如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
- 举例:
- 饮水机(用静态修饰)
- 水杯(不能用静态修饰)
- 共性用静态,特性用非静态
- d:可以通过类名调用
- 其实它本身也可以通过对象名调用。
- 推荐使用类名调用。
- 静态修饰的内容一般我们称其为:与类相关的,类成员
static的注意事项
- a:在静态方法中是没有this关键字的
- 如何理解呢?
- 静态是随着类的加载而加载,this是随着对象的创建而存在。
- 静态比对象先存在。
- b:静态方法只能访问静态的成员变量和静态的成员方法
- 静态方法:
- 成员变量:只能访问静态变量
- 成员方法:只能访问静态成员方法
- 非静态方法:
- 成员变量:可以是静态的,也可以是非静态的
- 成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
- 简单记:
- 静态只能访问静态。
静态变量和成员变量的区别
- 静态变量也叫类变量 成员变量也叫对象变量
- A:所属不同
- 静态变量属于类,所以也称为为类变量
- 成员变量属于对象,所以也称为实例变量(对象变量)
- B:内存中位置不同
- 静态变量存储于方法区的静态区
- 成员变量存储于堆内存
- C:内存出现时间不同
- 静态变量随着类的加载而加载,随着类的消失而消失
- 成员变量随着对象的创建而存在,随着对象的消失而消失
- D:调用不同
- 静态变量可以通过类名调用,也可以通过对象调用
- 成员变量只能通过对 象名调用
main方法的格式详细解释
- public 被jvm调用,访问权限足够大。
- static 被jvm调用,不用创建对象,直接类名访问
- void 被jvm调用,不需要给jvm返回值
- main 一个通用的名称,虽然不是关键字,但是被jvm识别
- String[] args 以前用于接收键盘录入的
工具类中使用静态
- 如果一个类中所有的方法都是静态的,需要再多做一步,私有构造方法,目的是不让其他类创建本类对象
- 直接用类名.调用即可
Math类的随机数功能
- A:Math类概述
- 类包含用于执行基本数学运算的方法
- B:Math类特点
- 由于Math类在java.lang包下,所以不需要导包。
- 因为它的成员全部是静态的,所以私有了构造方法
- C:获取随机数的方法
- public static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
- D:我要获取一个1-100之间的随机数,肿么办?
- int number = (int)(Math.random()*100)+1;
代码块的概述和分类
- A:代码块概述
- 在Java中,使用{}括起来的代码被称为代码块。
- B:代码块分类
- 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
- C:常见代码块的应用
- a:局部代码块
- 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
- b:构造代码块 (初始化块)
- 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行(每创建一次对象就会执行一次),并且在构造方法前执行(优先构造函数执行)
- c:静态代码块
- 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。(优先于主方法执行)
- 一般用于加载驱动
代码块的面试题
class Student {
static {
System.out.println("Student 静态代码块");
}
{
System.out.println("Student 构造代码块");
}
public Student() {
System.out.println("Student 构造方法");
}
}
class Demo2_Student {
static {
System.out.println("Demo2_Student静态代码块");
}
public static void main(String[] args) {
System.out.println("我是main方法");
Student s1 = new Student();
Student s2 = new Student();
}
}
输出》》》》
我是main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法
继承好处和弊端
A:继承的好处
a:提高了代码的复用性
b:提高了代码的维护性
c:让类与类之间产生了关系,是多态的前提
B:继承的弊端
类的耦合性增强了。
开发的原则:高内聚,低耦合。
耦合:类与类的关系
内聚:就是自己完成某件事情的能力
Java中类的继承特点
- A:Java中类的继承特点
- a:Java只支持单继承,不支持多继承。(一个儿子只能有一个爹)
- 有些语言是支持多继承,格式:extends 类1,类2,...
- b:Java支持多层继承(继承体系)
- B:案例演示
- Java中类的继承特点
- 如果想用这个体系的所有功能用最底层的类创建对象
- 如果想看这个体系的共性功能,看最顶层的类
继承的注意事项和什么时候使用继承
- A:继承的注意事项
- a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
- b:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。
- c:不要为了部分功能而去继承
- 项目经理 姓名 工号 工资 奖金
- 程序员 姓名 工号 工资
- B:什么时候使用继承
- 继承其实体现的是一种关系:"is a"。
Person
Student
Teacher
水果
苹果
香蕉
橘子
采用假设法。
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
this和super的区别和应用
- A:this和super都代表什么
- this:代表当前对象的引用,谁来调用我,我就代表谁
- super:代表当前对象父类的引用
- B:this和super的使用区别
- a:调用成员变量
- this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
- super.成员变量 调用父类的成员变量
- b:调用构造方法
- this(...) 调用本类的构造方法
- super(...) 调用父类的构造方法
- c:调用成员方法
- this.成员方法 调用本类的成员方法,也可以调用父类的方法
- super.成员方法 调用父类的成员方法
继承中构造方法的关系
A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
B:为什么呢?
因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
其实:
-
每一个构造方法的第一条语句默认都是:super() Object类最顶层的父类。
继承中构造方法的注意事项
- A:父类没有无参构造方法,子类怎么办?
- super解决
- this解决
- B:注意事项
- super(…)或者this(….)必须出现在构造方法的第一条语句上
方法重写
- A:什么是方法重写
- 重写:子父类出现了一模一样的方法(注意:返回值类型可以是子父类,这个我们学完面向对象讲)
- B:方法重写的应用:
- 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。
方法重写的注意事项
A:方法重写注意事项
a:父类中私有方法不能被重写
因为父类私有方法子类根本就无法继承
b:子类重写父类方法时,访问权限不能更低
最好就一致
c:父类静态方法,子类也必须通过静态方法进行重写
其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解(静态只能覆盖静态)
子类重写父类方法的时候,最好声明一模一样。
方法重写的面试题
Override和Overload的区别?Overload能改变返回值类型吗?
overload可以改变返回值类型,只看参数列表
方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值是一致(或者是子父类)的
方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。
子类对象调用方法的时候:
先找子类本身,再找父类。
final关键字修饰类,方法以及变量的特点
- A:final概述
- B:final修饰特点
- 修饰类,类不能被继承
- 修饰变量,变量就变成了常量,只能被赋值一次
- 修饰方法,方法不能被重写
final关键字修饰局部变量
- 基本类型,是值不能被改变
- 引用类型,是地址值不能被改变,对象中的属性可以改变
final修饰变量的初始化时机
- 显示初始化
- 在对象构造完毕前即可
class Demo3_Final {
public static void main(String[] args) {
Demo d = new Demo();
d.print();
}
}
class Demo {
final int num; //成员变量的默认初始化值是无效值
public Demo() {
num = 10;
}
public void print() {
System.out.println(num);
}
}
多态的概述及其代码体现
- A:多态(polymorphic)概述
- 事务存在的多种形态
- B:多态的前提
- a要有继承关系
- b:要有方法重写
- c:要有父类引用指向子类对象
多态中的成员访问特点之成员变量
多态中的成员访问特点之成员变量)
- 成员变量
-
编译看左边(父类), 运行看左边(父类
多态中的成员访问特点之成员方法
- 成员方法
- 编译看左边(父类), 运行看右边(子类)
多态中的成员访问特点之静态成员方法
- 静态方法
- 编译看左边(父类), 运行看左边(父类)
- (静态和类相关, 算不上重写, 所以, 访问访问还是看左边)
- 只有非静态的成员方法, 编译看左边 , 运行看左边
超人故事
多态中向上转型和向下转型
- Personn p = new SuperMan(); 向上转型
-
SuperMan sm = (SuperMan)p; 向下转型
多态的好处和弊端
- A:多态的好处
- a:提高了代码的维护性(继承保证)
- b:提高了代码的扩展性(由多态保证)
- B:案例演示
- 多态的好处
- 可以单子形式参数, 可以接受任意子类对象
- C:多态的弊端
- 不能使用子类的特有属性和行为
-
D:案例提示
method(Animal a)
method(Cat c)
多态的题目分析题
A:看下面程序是否有问题, 如果没有, 说出结果
class Fu {
public void show() {
System.out.println("Fu show");
}
}
class Zi extends Fu {
public void show() {
System.out.println("Zi show");
}
public void method() {
System.out.println("Zi method");
}
}
class Test1Demo {
public static void main(String[] args) {
Fu f = new Zi();
f.method(); //-----有问题,编译出问题, 父类Fu中没有method方法
f.show(); //--------没问题,输出 Zi show; 当子类Zi中没有自己的show方法时,编译仍然正确,是输出Fu show
}
}-
B:看下面程序是否有问题, 如果没有, 说出结果
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
public void show2() {
System.out.println("爱");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
class Test2DuoTai {
public static void main(String[] args) {
A a = new B();
a.show(); // ------------爱B b = new C(); b.show(); // ------------你 } }
抽象类的概述及特点
- A:抽象类的概述
- 抽象类就是看不懂的
- B:抽象类的特点
- a:抽象类和抽象方法必须用abstract关键字修饰
- abstract class 类名 {}
- b:抽象类不一定有抽象方法, 有抽象方法的类一定是抽象类或者是接口
- c:抽象类不能实例化那么, 抽象类然后实例化呢?
- 按照多态的方式, 由具体的子类实例化. 其实这也是多态的一种, 抽象类多态
- d:抽象类的子类
- 要么是抽象类
- 要么重写抽象类中的所有抽象方法
抽象类的成员特点
- A:抽象类的成员特点
- a:成员变量:既可以是变量,也可以是常量。abstractshift可以修饰成员变量?不能修饰成员变量
- b:构造方法: 有
- 用子类访问父类数据的初始化
- c:成员方法:既可以是抽象的,也可以是非抽象的
- B:案例演示
- 抽象类的成员特点
- C:抽象类的成员方法特性:
- a:抽象方法 强制要求子类做的事情
- b:非抽象方法 子类继承的事情, 提高代码复用性
abstract不能和那些关键字共存
接口的概述及其特点
A:接口的概述
从侠义的角度讲就是指java 中的interface
从广义的校对讲对外提供规则的都是接口
B:接口的特点
a:接口用关键字interface表示
b:类实现接口用implement表示
class 类名 implement 接口名 {}
c:接口不能被实例化
那么,接口如何实例化呢?
按照多态的方式来实例化
d:接口的子类
可以是抽象类,但意义不大
可以是具体类,要重写接口中的所有抽象方法
子类重写父类方法的时候,最好声明一模一样。
接口的成员特点
- 成员变量: 只能是常量,并且是静态的、公共的
- 默认修私符: public static final
- 建议 : 自己动手给出
- 构造方法:接口没有构造方法
- 成员方法:只能是抽象方法
- 默认修私符: public abstract
- 建议 : 自己动手给出
类与类、类与接口、接口与接口的关系
- a:类与类
- 继承关系: 只能单继承, 可以多层继承
- b:类与接口
- 实习关系:可以单实现、也可以多实现
- 并且还可以在继承一个类的同时实现多个接口
- c:接口与接口
- 继承关系:可以单继承,也可以对继承
抽象类与接口的区别
A:成员区别
抽象类:
成员变量: 可以是变量,也可以是常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量: 只能是常量
构造方法:无
成员方法:只可以抽象
B:关系区别
类与类:
继承,单继承
类与接口:
实现,单实习,多实现
接口与接口
继承,单继承,多继承
c:设计理念区别
抽象类 被继承体现的是:“is a”的关系,抽象类中定义的是该继承依稀的共性功能
接口 被实现体现的是:“like a”的关系, 接口中定义的是该继承体系的扩展功能
如何编译运行带包的类
- a:javac编译的时候带上-d即可
- javac -d . HelloWorld.java
- b:通过java命令执行。
- java 包名.HellWord
四种权限修饰符
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
类及其组成所使用的常见修饰符
- A:修饰符:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
- B:类:
- 权限修饰符:默认修饰符,public
- 状态修饰符:final
- 抽象修饰符:abstract
- 用的最多的就是:public
- C:成员变量:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 用的最多的就是:private
- D:构造方法:
- 权限修饰符:private,默认的,protected,public
- 用的最多的就是:public
- E:成员方法:
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
- 用的最多的就是:public
- F:除此以外的组合规则:
- 成员变量:public static final
- 成员方法:
- public static
- public abstract
- public final
内部类概述和访问特点
- a:内部类可以直接访问外部类的成员,包括私有。
- b:外部类要访问内部类的成员,必须创建对象。
- 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
class Demo1_InnerClass {
public static void main(String[] args) {
//Inner i = new Inner();
//i.method();
//外部类名.内部类名 = 外部类对象.内部类对象
Outer.Inner oi = new Outer().new Inner(); //创建内部类对象
oi.method();
}
}
class Outer {
private int num = 10;
class Inner {
public void method() {
System.out.println(num);
}
}
}
成员内部类私有使用
class Demo2_InnerClass {
public static void main(String[] args) {
//Outer.Inner oi = new Outer().new Inner();
//oi.method();
Outer o = new Outer();
o.print();
}
}
class Outer {
private int num = 10;
private class Inner {
public void method() {
System.out.println(num);
}
}
public void print() {
Inner i = new Inner();
i.method();
}
}
静态成员内部类
- 成员内部类被静态修饰后的访问方式是: 外部类名.内部类名 对象名 = 外部类名.内部类对象;
class Demo1_InnerClass {
public static void main(String[] args) {
//外部类名.内部类名 对象名 = 外部类名.内部类对象;
Outer.Inner oi = new Outer.Inner();
oi.method();
Outer.Inner2.print();
}
}
class Outer {
static class Inner {
public void method() {
System.out.println("method");
}
}
static class Inner2 {
public static void print() {
System.out.println("print");
}
}
}
使用已知的变量,在控制台输出30,20,10。
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(?); // num
System.out.println(??); // this.num
System.out.println(???); // Outer.this.num
//内部类之所以能获取到外部类的成员,是因为它能获取到外部类的引用外部类名.this
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
局部内部类访问局部变量的问题
- 局部内部类访问局部变量必须用final修饰
- 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?
因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用
但是jdk1.8取消了这个事情,所以我认为这是个bug
匿名内部类的格式
- A:匿名内部类
- 就是内部类的简化写法。
- B:前提:存在一个类或者接口
- 这里的类可以是具体类也可以是抽象类。
- C:格式:
new 类名或者接口名(){
重写方法;
}
- D:本质是什么呢?
- 是一个继承了该类或者实现了该接口的子类匿名对象。
匿名内部类重写多个方法调用
class Demo2_NoNameInnerClass {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
interface Inter {
public void show1();
public void show2();
}
//匿名内部类只针对重写一个方法时候使用
class Outer {
public void method() {
/*new Inter(){
public void show1() {
System.out.println("show1");
}
public void show2() {
System.out.println("show2");
}
}.show1();
new Inter(){
public void show1() {
System.out.println("show1");
}
public void show2() {
System.out.println("show2");
}
}.show2();*/
Inter i = new Inter(){
public void show1() {
System.out.println("show1");
}
public void show2() {
System.out.println("show2");
}
/*public void show3() {
System.out.println("show3");
}*/
};
i.show1();
i.show2();
//i.show3(); //匿名内部类是不能向下转型的,因为 没有子类类名
}
}
匿名内部类在开发中的应用
//这里写抽象类,接口都行
abstract class Person {
public abstract void show();
}
class PersonDemo {
public void method(Person p) {
p.show();
}
}
class PersonTest {
public static void main(String[] args) {
//如何调用PersonDemo中的method方法呢?
PersonDemo pd = new PersonDemo ();
}
}
修改后: ------------------------------------------
class Test1_NoNameInnerClass {
public static void main(String[] args) {
//如何调用PersonDemo中的method方法呢?
PersonDemo pd = new PersonDemo ();
//pd.method(new Student());
pd.method(new Person() {
public void show() {
System.out.println("show");
}
});
}
}
//这里写抽象类,接口都行
abstract class Person {
public abstract void show();
}
class PersonDemo {
//public void method(Person p) { //Person p = new Student();
/*
Person p = new Person(){ //父类引用指向子类对象
public void show() {
System.out.println("show");
}
};
*/
public void method(Person p) {
p.show();
}
}
class Student extends Person {
public void show() {
System.out.println("show");
}
}
匿名内部类的面试题
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
操作结果为--------------------------------------------------------------
class Test2_NoNameInnerClass {
public static void main(String[] args) {
//Outer.method().show(); //链式编程,每次调用方法后还能继续调用方法,证明调用方法返回的是对象
Inter i = Outer.method();
i.show();
}
}
//按照要求,补齐代码
interface Inter {
void show();
}
class Outer {
//补齐代码
public static Inter method() {
return new Inter() {
public void show() {
System.out.println("show");
}
};
}
}