一,基础部分
DAY01---14
# 常识
## 常见操作
- 文件的显示隐藏
- 隐藏文件:右键 -> 勾选隐藏
- 显示隐藏文件:
工具-> 文件夹选项->查看->显示隐藏的文件
- 文件后缀的显示隐藏
工具-> 文件夹选项->查看->隐藏已知文件的扩展名 取消勾选。
- 文件后缀的用途
- 文件后缀是给系统看的。
- 文件后缀决定系统默认使用哪个软件打开这个文件。
- 设置默认打开软件
- 右键-> 属性-> 打开方式->选择对应的软件 或者 通过浏览按钮找到对应软件的可执行文件。
## 常见快捷键
### 基本操作
- ctrl+c 复制
- ctrl+v 粘贴
- ctrl+x 剪切
- ctrl+A 全选
- 多选操作:
- 单个:ctrl + 鼠标左键
- 分段: shift+ 鼠标左键
- ctrl+w 关闭当前标签页
- alt+f4 关闭软件。
- ctrl+n 创建新的标签页。
### windows快捷键
- win+D 切换到桌面
- alt + table
### 在文本编辑里的快捷键
- ctrl+Z 回撤
- ctrl+y 重做
## sublime的使用
- ctrl+ d 选中重复的字符
- shift + 鼠标右键 多光标操作。
# 命令行
- 打开命令行
windows+r -> cmd
- 常见命令
- cd
- \ 根目录
- . 代表当前路径
- .. 上级目录
- 注意: 如果盘符不同,需要先切换盘符。
- 盘符切换方式: 盘符名: + 回车
- 小技巧:
- 上下键翻命令的历史记录。
- 可以把文件拖入命令行,命令行里会有文件夹的路径
- 在资源管理器里的地址栏里直接输cmd,会打开新的命令行在当前路径下。
- cd 后使用table键补充文件名字
- 路径
- 相对路径: 相对当前路径
- 绝对路径: 特点是由盘符。
-------------------------------------------------------
# java语言概述
- sun 。 被 Oracle 收购了
- java之父高斯林
## java 三种技术架构
- JAVAEE 企业版。
- JAVASE 标准版 java基础班学习内容
- JAVAME 小型版。
- Android java
## java语言的特点
- 面向对象
- 跨平台性
- java跨平台性主要是因为有不同版本的虚拟机(JAVA VIRTUAL MACHINE - JVM)
- 正式因为有jvm,所以java的运行效率相对较低。
- windows 虚拟机
- linux 虚拟机
- macosx 虚拟机
## 几个概念
- jre(java runtime enviroment) java运行环境。
- JVM
- 类库
- jdk(java development kits) java 开发工具包。
- jre
- 开发工具。
## HelloWorld
- java 文件。 是让程序员看的。
```
class HelloWorld
{
public static void main(String[] args)
{
System.out.println("HelloWorld");
}
}
```
- 要把java文件编译成 .class文件: javac命令
- 使用jvm执行.class 文件: java命令执行.class 文件不需要后缀。
## 环境变量
- Path
- 相当于就是给一个命令创建一个快捷方式。
- 命令寻找流程
- 首先会在当前目录下寻找命令。
- 如果找不到,去Path环境变量下配置的目录下寻找。
- 细节:如果有多个路径要配置,中间用 ';' 分割
- 功能: 用来寻找命令的。
- classpath
- 功能: 用来寻找.class文件的。
- .class文件的寻找流程
- 如果没有配置 classpath环境变量,则只会在当前目录下寻找.class文件
- 如果配置过 classpath环境变量,只会在classpath配置的路径下寻找.class文件。
- 细节:如果配置过classpath不会在当前目录下寻找。所以配置classpath的时候,需要添加 '.;'
## set命令
- 功能:查找或者临时设置环境变量的。
- 查找:
- set 环境变量名
- 如: set path
- 设置
- set 环境变量名=xxx
- 清空: set 环境变量名=
- 设置: set
## 常见错误
- 编码GBK的不可映射字符
编译的时候加 -encoding参数
```
javac -encoding "utf-8" xx.java
```
- 非法字符: \65307
一般是因为有中文符号。
- 找不到或无法加载主类 Test
- classpath设置错误。 比如设置classpath的时候没有添加当前路径
- 类名写错。
# java基本语法
## 注释
- 单行注释
- 格式: // 要注释的代码
- 特点:从单行注释开始,改行后续内容全部被注释。
- 多行注释
- 格式: /* 要注释的代码 */
- 注意:不能嵌套
- 文本注释
- 格式: /** 要添加的代码说明 */
## 标识符
- 定义:凡是可以起名的地方都使用标识符。
- 标识符:(必须准守)
- 英文字母 数字 _ $ 组成。
- 可以用中文的。
- 数字不能开头。
- 类名命名规则(可以不遵守,但是建议使用改规则)
- 首字母大写
- 多个单词,其他单词首字母也大写。
## 变量
使用变量前必须先声明。
- 变量声明: 数据类型 变量名 = 值;
- 常见错误
- 已在方法 xx 中定义了变量 xx : 因为变量的重复定义。
- 找不到符号: 一般是因为变量没有定义。 拼写错误: 或者变量定义了,定义的变量名与使用的变量名不一致。
- 变量的命名规则:
- 首字母小写。
- 多个单词,其他字母的首字母大写。
- 变量的作用域
- 在一个大括号之内生效。
## 浮点数类型
- float: 4个字节
- double: 8个字节。
- 浮点数常量默认是double类型
- 如果想表示float常量,需要在浮点数常量后添加 f. 如:1.5f
- 常见错误
- 可能会损失精度。
丢失数据。
1024 Byte(字节) -> 1KB -> 1000B
1024KB -> 1MB
1024MB -> 1GB
1024GB -> 1TB
1024TB -> 1PB
-------------------------------------------------------------
# 进制
满几进位
## 十进制
- 满十进一
- 每一位最大的数是 9
123456
1*10^5 + 2*10^4 + 3*10^3 + 4*10^2 + 5*10^1 + 6*10^0 = 123456
## 二进制
- 满2进1
- 每一位的最大值 1
## 十六进制
- 满16进1
- 每一位的最大值15 -> F
- 超过9的数字用字母表示。 10-> A
- 四位二进制可以表示为一位十六进制。
- java里的十六进制: 0x开头表示16进制
- 8F67‘
## 整数类型
- byte 1BYTE = 8 位。 0- 11111111
- short 2字节 16位
- int 4个字节 32位二进制 8位十六进制
- long 8个字节 64位
- 整数常量默认类型是 int。
- 细节:
- 用整型常量给byte,short赋值的时候,是否有超出范围,如果没有则不报错。
- 用int,long变量给另外一个byte,short赋值,不会检查范围。直接报错
## 二进制表示整数
- 二进制里最高位是符号位。 如果是1,代表负数。 如果是0,代表正数。
- 原码
127 -> 1111111
- 补码
- 负数求补码
- 获取数值部分的原码 -1 -> 0000 0001
- 取反 : 1111 1110
- +1 : 1111 1111
-5 求补码
- 整数转二进制
- 如果是正数,直接求原码。
- 如果是负数,求补码。
- 二进制转整数
- 细节:判定最高位必须知道当前数值是什么类型。
- 如果是正数(最高位是0),则直接二进制转十进制。
- 如果是负数(最高位是1)
- -1
- 取反
- 补负号
- 练习
- byte 1111 1111 -> 1111 1110 -> 0000 0001 -> -1
- short 1111 1111 -> ff -> 255
- -7 求补码
0000 0000 0000 0000 0000 0000 0000 0111
29个1 000
29个1 001
- 1111 1101
- byte
1111 1101
------------------------------------------------------------
# 类型转换
## 自动类型转换
- 定义:一种类型的变量可以直接转成另外一种类型的变量。
- 丢失数据。
- 类型匹配。
- 比如: boolean无法给数值类型赋值。
```
byte->short-> int(4)-> long(8) ->float(4) -> double(8)
char -> int
```
## 强制类型转换
- 格式
类型1 变量=(类型1) 类型2的变量;
- 范例:
```
int i = 3;
byte a = (byte)i;
```
# 运算符
## 数学运算符
- +
- -
- *
- /
- 如果是两个整数运算,结果还是一个整数。 5/2 -> 2
- %
- 名称:取模
- 功能:求余数. 如果可以整除,结果为0;
- 细节: 结果与%左侧是数字有关。
- 练习:
a = 456
1
2
3
- ++ 自增
- 右自增:a++
先取值,后运算。
- 左自增:++a
先运算,后取值。
## 字符串连接符: +
+ 两边任意一个表达式是字符串,则该符号是字符串连接符。
## 赋值运算符
- =
- +=, -= ,*=, /=, %= .
- a += b -> a = a + b;(把b添加到a里)
- 特殊情况
```
byte a = 3;
a = a + 2;//报错
a += 2;//编译通过
```
## 比较运算符
- 运算结果是 boolean
- == (等于)
- > , <
- >= , <=
- != (不等于)
## 逻辑运算符
- 特点:用来运算boolean值
- & :与运算符。(且)
- 两边条件都为true结果才为true
- 只要有一个false,结果就是false
- |: 或运算符。
- 两边条件都为false结果才为false
- 只要有一个true,结果就是true
- ^: 异或
- 不一样就对了。
- ! 非
- &&(短路与)
- & 无论左侧表达式是什么结果,右侧表达式总要执行
- && 如果左侧是false,则右侧不执行
- ||(短路或 )
- | 无论左侧结果,右侧表达式总要执行
- || 如果左侧是true,右侧不执行。
## 三元表达式
- 格式: 条件表达式(运算结果为boolean)? 表达式1: 表达式2
- 逻辑: 如果 条件表达式 运算结果为true,则执行表达式1,否则则执行表达式2
-------------------------------------------------------------------------------------------
# 运算符
## 位运算符
是用来运算整数的二进制的。
- << 左移运算符。
- >> 右移运算符。
- 如果是正数,空处的位置补0
- 如果是负数,空出的位置补1
- >>> 无符号右移
- 右移过程无论是正数还是负数全部补0。
- &
- |
- ^
- 不一样就对了。
- 123456 6 55566
# 流程控制语句
只能控制一条语句。
## if语句
- 格式1
if(条件表达式) 要控制的语句。
- 如果条件满足,执行控制的语句。如果条件不满足,不执行控制的语句。
- 练习
- 定义一个变量,判断是否是5的倍数
- 是否是2的倍数
- age , 判断是否年龄是否大于2
## if else 语句
- 格式
if(条件表达式) 语句1 else 语句2
- 流程: 如果满足条件表达式,执行语句1. 否则,执行语句2.
- 练习
- 求最大值 a b
## if else if
- 格式
```
if(条件表达式1)
语句1
else if(条件表达式2)
语句2
else if(条件表达式3)
语句3
...
else
语句4
```
- 练习:
打印星期几
## switch 选择语句
- 格式
```
switch(变量)
{
case 常量1:
语句1
break;
case 常量2:
语句2
break;
....
default:
break;
}
```
- 细节
- switch语句是一个开关。遇到case里的常量与switch里的变量匹配的时候,开关打开。
- 开关打开的时候,不会在与其他case做比较。
- 遇到break的时候开关关闭
- 支持的类型
- 可以自动类型转换为int的类型。byte short char int
- String
- 枚举。
- 练习
- 练习: 输入月份打印季节
- 三个变量。 char + - * /
## 循环结构
### while 循环
- 格式:
while(条件表达式) 循环语句
- 流程
- 如果条件表达式满足条件,则执行循环语句。
- 执行完循环语句之后,继续判断条件表达式是否满足条件,如果满足,则执行循环语句。
### do while
- 格式
do 循环语句 while( );
- 与while循环的区别
- while循环线判断条件再执行循环体。
- dowhile循环线执行一次循环体,再判断条件。即,最少执行一次循环体。
## 死循环的问题
- 注意 ; 空语句。
- 循环条件
- 如果是 --, 找一个下限, 使用 >
- 如果是 ++, 找一个上限, 使用 <
-
## 练习
- 打印 0-100之间的所有的偶数
- 打印0-100之间 3与5的公倍数。
- 计算 0-100之间所有数之和
-----------------------------------------------------------------
# for循环
- 格式
```
for(初始化表达式; 条件表达式; 循环后表达式)
{
循环体
}
```
- 流程
1. 执行初始化表达式
2. 判断条件表达式是否满足条件。
3. 如果满足条件,执行循环体。如果不满足,退出循环。
4. 循环体执行完之后,执行循环后表达式
5. 跳回第二步。
- 细节
- 在初始化表达式里声明的变量只在循环内有效。
- 初始化表达式可以为空。 循环后表达式可以为空。 条件表达式可以为空,如果为空,相当于true。
- 练习
- 打印1~100之间7的倍数
- 获取1-100之间7的倍数个数
- 获取1-100之间7的倍数之和。
## break
- 功能: 结束本层循环。
- 细节:只能在switch 以及循环里的使用 break
## continue
- 功能:结束本次循环体。
- 细节:也只能存在循环里。
## 练习
- 打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身。
for(100 -> 999)
{
个
十
百
}
- 鸡兔同笼,头 30个, 脚 88只,求有多少只鸡,多少只兔子
x 0 30 鸡
y 0 22 兔
x+y == 30 && 2*x + 4*y == 88
for(x 0-> 30)
{
for(y 0-> 22)
{
x 与y是否满足条件。
}
}
- 有两个变量 a = , b ,求这两个数的最大公约数和最小公倍数
- 最大公约数
- 12与6: 6 3 2 1
- a与b: min(a,b)->1
- 最小公倍数
- 2与3:6 12 18
- a与 b: max(a,b)->a*b
---------------------------------------------------------------------------
# 方法
是拥有一个独立功能的代码片段。
## 方法的声明
修饰符 返回值类型 方法名(参数列表)
{
//函数体
}
- 修饰符:修饰方法。 public static
- 返回值类型:
- 来声明方法的运算结果的类型的。
- 如果不需要返回值,则使用 void
- 方法名
- 标识符
- 命名规则: 首字母小写。 其他单词字母首字母大写。
- 参数列表
- 用来接收外部调用方法时候传入的数据的。
- 函数体:函数的功能代码
- 返回:
- return 要返回的值;
- 如果返回值类型是void,返回的时候使用 return ;
## 方法调用
方法名(实际参数);
## 方法声明流程
- 明确方法的功能
- 确定是否有未知内容参与运算 参数列表
- 是否需要运行结果 返回值。
## 案例
- 打印 0-n之间的所有数
- 求两个数的最大值
- 求m-n之间值之和
- 画出n个*
- 求一个数是否是一个素数
- 在刚才方法的基础上,把一个偶数转成两个素数打印
- 一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
## 方法的细节
- 方法如果不调用,则不会执行。
- 方法声明的位置
- 只能声明在类里边。
- 代码执行是有序的,从上到下,有调则调
- 调用流程
- 内存
- 栈(糖葫芦)-局部变量
- 内存连续
- 先进后出--(先进先出的是队列结构,排队买票)
- 栈内存较小
- 堆(一堆糖葫芦)
- 内存不连续
- 没有顺序。
- 堆内存较大。
## 方法的标识符
方法的标识是由 方法名 以及 参数列表 组成 。
## 重载
- 在一个类里,有多个方法的方法名相同,但是参数列表不同的方法,被称为重载
- 方法重载与返回值无关。
## 递归
函数直接在方法中调用了函数本身 被称为递归
- 警惕: 栈溢出问题。
### 明确
- 明确递归方法的功能
- 明确退出条件。
- 案例
求前n项的阶乘之和 1+2!+3!+...19! + 20!
------------------------------------------------------------------------------------
# 数组
## 介绍
- 数组是一个容器。
- 用来存放多个某种类型的数据。
## 创建数组
- 格式1
```
类型[] 变量名 = new 类型[容量];
```
- 格式2
```
类型[] 变量名 = new 类型[]{数据1,数据2, 数据3 ...};
```
- 格式3: 静态初始化
```
类型[] 变量名 = {数据1,数据2, ...};
```
- 细节
- new : 所有new出来的对象都在堆上。
- 区别
- 如果创建数组的时候,已经知道存储内容了,使用第二种。 如果创建数组时,存储内容还不确定,使用格式1
- 格式2创建出来的索引在堆上。 格式3的栈上。
- 格式3创建数组只用能用初始化数组变量。不能当做参数传递。
## 索引
- 为了方便管理数组上的每一个 元素,对每个元素进行了编号,该编号被称为 索引 -- index
- 索引的编号从0。 假设,数组长度为20, 最大索引值为 19.
## length属性
- 功能: 获取数组的长度
- 格式: 数组名.length
## 数组元素的访问
- 访问格式
数组名[索引]
- 赋值
数组名[索引] = 值;
- 取值
数组名[索引]
## 默认值
- 基本数据类型, 默认值是 0
- 如果是引用型数据类型,默认值是 null
## 常见异常
- ArrayIndexOutOfBoundsException : 数组索引越界。 一般因为给的索引超出了数组索引的范围。
- NullPointerException: 空指针异常
- 如果是数组,找 []前的变量是否为空
- 如果不是数组,找.前的变量
## 数组的常见操作
- 求数组的最大值
- 求最小值
- 两个索引的值交换
- //把最大值索引上的元素与i上的元素交换
Object temp = arr[i];//取出i上的值放入临时容器temp,此时索引i上的值为空
arr[i] = arr[maxValueIndex];//取出索引maxValueIndex上的值放入i索引位置,此时maxValueIndex索引值为空
arr[maxValueIndex] = temp;//取出临时容器temp中的值,放入数组中maxValueIndex索引上.完成数组索引i到索引maxValueIndex上值的交换.
- 求最大值的索引
- 求m-n上最大值的索引
- 选择排序
- 冒泡排序
## 二维数组
int 山楂
int [] 糖葫芦
int[][] 糖葫芦车
- 练习
求对角线之和
```
int[][] arrArr2 = {
{1,2,3,4},//0-0 0-3
{2,3,4,5},//1-1 1-2
{3,4,5,6},//2-2 2-1
{4,5,6,7}//3-3 3-0
};
```
## 作业
- 把由10个元素组成的一维数组逆序存放再输出。
---------------------------------------------------------------------------------
## 概念
- 面向对象
- c++ java c# oc
- 面向过程
- c
## 类 与 对象
类:是对某种事物的一个描述
比如:狗,恐龙
对象:某个事物的具体实例。
比如:你家的狗。 没见过恐龙实例。
- 现实生活中的对象
某个人是一个对象。
人的方法可能是 eat(), sleep(), work(), play() 等等。
所有人都有这些方法,但会在不同时间执行它们。
一个人的属性包括姓名、身高、体重、年龄、性别等等。
所有人都有这些属性,但它们的值因人而异。
- 描述事物
- 有什么
- 会干什么
- java里的类
- 有什么 -> 属性 -> 变量
- 会干什么 -> 功能 -> 方法
## 类
在类里声明的方法和变量统称为成员。
- 变量
- 声明在类里的变量,成员变量。
- 声明在方法里的变量,局部变量
- 声明
- 如果类用public修饰,那么当前类名必须与文件名相同。
- 初始化
- 成员变量可以不显示初始化。
- 如果成员变量没有显式初始化,在创建对象的时候会进行默认初始化
- 基本数据类型是:默认初始化值 0
- 引用型数据类型是:默认初始化值 null
## 局部变量和成员变量区别
- 声明的位置不同
- 成员变量:类里.(与对象共存)
- 局部变量:声明在方法里。(临时变量)
- 作用域:成员变量随着对象而存在。 局部变量在当前大括号内生效。
- 存在内存位置不同
- 成员变量随着对象的创建,存在于堆上。
- 局部变量在栈上
- 初始化
- 成员变量可以不显式初始化,可以进行默认初始化。
- 局部变量必须初始化。
## 匿名对象
{ }
# 封装
- 把对象封装为一个类,定义其属性,提供获取与修改其属性的方法.
- 把要封装的属性使用private修饰
- 提供public的get和set方法,方便外部访问。- 如果获取的属性是boolean类型,使用的 isXXX. 如果其他类型使用 getXXX
- 格式:
- public void set (参数){}
- public 返回值 get(){}
# 构造函数
在创建的对象的时候,申请完内存之后会自动调用该类的构造函数。
- 格式: public 类名(){需要初始化的成员变量 }
## 构造函数
- 方法名与类名完全相同
- 没有返回值,连void都没有
- 如果添加返回值声明,则该方法不再是构造函数。
- 构造函数是在创建对象的时候被调用。
## 隐式构造函数(缺省构造函数)
如果一个类里,没有显式的声明过构造函数,则会有一个默认的隐式的空参数的构造函数。
(注)如果设置了带参数的构造函数,则不再存在隐式的空参构造函数.
## 构造函数的作用
用来初始化成员变量。
## 构造函数与普通函数的区别
- 格式不同。
- 构造函数: 没有返回值。 方法名必须与类名相同
- 普通函数:需要声明返回值类型,如果没有,声明为void. 方法名没有限制。
- 调用时机不同
- 普通函数可以随便、多次的调用。
- *构造函数只有在创建对象的时候才会被调用一次.
String[] 表示一个'字符'类型的'数组'
## this
- 是一个关键字,相当于一个变量,指向了当前对象。
- 当前对象: 哪个对象调用的该方法,this就是该对象。
- 用途
- 用来区分成员变量与局部变量。
- 在构造函数里调用重载的构造函数
- 格式: this(参数)
- 细节: 调用重载构造函数必须放在第一条语句里。
- 调用规则:参数少的调用参数多的。
## static关键字(修饰符)
静态的,在当前类中共享
### 可修饰成员变量
- 静态变量存储于 方法区的常量区。
- 被当前类的所有对象所共享。
- 可以直接通过类名访问。
- 与非静态成员变量区别:
1、从保存位置:
a) 静态成员变量: 方法区的静态区域
b) 非静态成员变量: 堆内存中的对象空间里面
2、从书写格式上看:
a) 静态成员变量: 在数据类型前面多了一个static修饰
b) 非静态成员变量: 没有static修饰
3、从生命周期上看:
a) 静态成员变量: 在类加载的时候,类加载完成,就分配完空间;直到类被卸载时空间被回收
b) 非静态成员变量: 创建对象的时候分配空间; 对象变为垃圾空间被回收的时候被销毁
4、从使用方法上看:
a) 静态成员变量: 直接通过类名使用
b) 非静态成员变量: 必须通过对象使用
5、从修改后的影响范围上看:
a) 静态成员变量: 对该类的所有对象都有影响;
b) 非静态成员变量: 只对一个对象有影响
### 修饰成员方法
- 方法成为了静态方法。 -- 与对象无关。
- 静态方法可以通过类名直接访问。
- 静态方法无法访问非静态成员变量
- 静态方法无法访问非静态成员方法。
### 总结
静态方法中只能使用静态成员变量,非静态方法既能使用 静态变量,也可以使用非静态成员变量。
class MyClass {
static void StaticFun() { //静态方法
nsMember += nsMember; //出错!因为nsMember是非静态成员
sMember += sMember; //ok,因为sMember是静态成员
}
void UStaticFun() { //非静态方法
sMember += nsMember; //ok
sMember += sMember; //ok
}
}
//关于静态构造函数的执行顺序
//静态构造函数的执行发生在类的静态成员初始化之后和类的第一个实例创建之前.
一个类只能定义一个静态构造函数,并且不能带有参数
## 构造代码块
- 格式
```
class 类名
{
{
初始化语句。//构造代码块
}
}
```
- 特点: 在构造函数调用之前,会默认调用构造代码块。
- 使用场景:如果创建对象的时候,不管使用的是哪个构造函数,必须执行的代码就可以放入构造代码块里。
- 细节:一个类里可以有多个构造代码块。 执行顺序与代码放置顺序有关。
## 构造函数、构造代码块和静态代码块区别
构造函数
格式:类名(参数1,参数2,…){构造函数执行语句};
关于构造函数,以下几点要注意:
1.对象一建立,就会调用与之相应的构造函数,也就是说,不建立对象,构造函数时不会运行的。
2.构造函数的作用是用于给对象进行初始化。
3.构造函数笼统来说也是函数,它具备函数的一些特性,也不具备一些特性,可以把它看成是特殊的函数。它可以重载(重载时参数类型与参数个数有一项不同即可,但仅仅函数返回值类型不同是不行的),可以被权限修饰符修饰,但是它没有返回值(注意:这与平常所说的函数返回值类型是void不同)。
4.当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造方法。但是当在类中自定义构造函数后,默认的构造函数就没有了,即使是自定义的构造函数也是空参数的也是这样,因为那毕竟是你“自定义”的!
5.构造函数和一般函数不仅在写法上有不同,在运行上也有不同。构造函数是在对象一建立就运行,给对象初始化,而一般函数是对象调用时才执行,给对象添加对象具备的功能。
一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次。
6.定义构造函数的需求性:当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。
构造代码块
格式:{构造代码块执行语句};
关于构造代码块,以下几点要注意:
1.构造代码块的作用是给对象进行初始化。
2.对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。
3.构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
静态代码块
格式:static{静态代码块执行语句};
关于静态代码块,要注意的是:
1.它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的,当然,建立对象的时候,它也会执行,但是建立多个对象,它也是只会执行一次,并不是说每次建立对象它都要执行,因为它是由类调用的,且只执行一次!就它优先于主函数而执行这点来说,因为主函数也是由类调用的,所以类可以控制着执行的顺序,而实际上,类调用时,先执行静态代码块,然后才执行主函数的。
2.静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。区分着理解比较容易记牢。
下面结合一个小例子来具体分析三者的用法。
classStaticCode{
int num=9;
StaticCode(){
System.out.println("b");
}
static{
System.out.println("a");
}
{
System.out.println("c");
}
StaticCode(int x){
System.out.println("d");
}
}
public classStaticCodeDemo {
public static voidmain(String[] args){
newStaticCode(1);
}
}
运行结果是
a
c
d
这是因为,主函数中的执行语句是new StaticCode(1);因为这个语句调用了StaticCode类并调用StaticCode的一个构造函数建立对象,那么在StaticCode类中,先执行的是静态代码块
static{
System.out.println("a");
}
它是在调用类时立即执行,但此时还没有建立对象。然后执行的是构造代码块,
{
System.out.println("c");
}
这是在建立对象时执行,但它的执行是优先于构造函数的。接着执行的是对应的构造函数
StaticCode(int x){
System.out.println("d");
}
,这个构造函数与new StaticCode(1);有着相同的参数个数和对应的参数类型,执行语句自动匹配寻找对应的构造函数。
另外,StaticCode类中有个成员变量num,如果将静态代码块改为
static{
System.out.println("a"+this.num);
}
则编译不通过,因为静态代码块只能调用静态变量,非静态成员变量在对象没有建立前是不存在的,这也帮助理解了静态代码块是在对象建立前执行的。
如果将构造代码块改为
{
System.out.println("c,num="+this.num);
}
那么将编译无误,运行正确,因为构造代码块是在对象建立后才运行的,是由对象调用的,对象建立后,成员变量num已经存在了,所以不会出错。
运行结果如下
a c,num=9 d
## 静态代码块
- 构造代码块
- 创建对象的时候,会被执行一次。
- 格式: {}
- 功能:用来初始化成员变量
- 静态代码块
- 格式: static {}
- 执行时机: 当类被加载的时候会被执行一次。指挥执行一次(一般情况,类只会被加载一次。)
- 功能:初始化静态变量。
## 单例模式(Singleton Pattern)(面试笔试高发区)
- 设计模式
设计模式是为了解决某种类型的问题,总结出来的某种固定的写法。
- 解决的问题:
一个类只能创建一个对象
- 代码流程
- 构造函数私有化: 防止外部随便创建该类的对象。
- 创建一个静态的当前类引用类型的变量
- 提供一个 公共的静态的方法,用来获取当前类的对象。
- 代码
```
class P
{
private static P instance = null;
private P() { }
public static p getInstance()
{
synchronized(P.class){
if(instance == null)
{
instance = new P();
}
}
return instance;
}
}
```
## 组合练习
- 定义一个人
- 人里有一个电脑,房间
- 电脑里有硬盘,安装的有游戏
- 人
- 电脑
- 姓名 年龄
- 房子
- 电脑
- 品牌,价格
- 硬盘
- 游戏
- 功能
- 玩游戏
- 安装游戏
- 卸载游戏
## super
- 可以在子类构造函数里调用父类的构造函数。
- super 调用父类的构造函数必须在第一条语句里。
- 如果子类的构造函数里没有显示调用过父类的构造函数,则会隐式调用父类空参数的构造函数: super();
- 可以用来区分在父类里声明的成员变量。
- 可以指向父类内存。
- 可以用来调用父类的方法实现
```
public void walk()
{
//子类特性代码
super.walk(); //在子类方法中调用父类的方法
}
```
## 初始化原则
哪个类里声明的变量,就在哪个类里进行初始化。
## 继承 [规则]
### 可以多重继承.
- A继承B,B继承C 则 A可以继承B与C中所有公共方法
### 不可以多个继承。
- 即 A 不能同时继承了B以及C.(B与C是相互无关的两个类)
## 继承 [子类中方法的重写]
如果子类从父类里继承的功能无法满足子类的特性,则可以重新声明该方法, 这个过程被称为方法的重写
- 规则
- 子类覆盖父类的方法必须坚持三相同: 返回值,方法名,参数列表 都相同。
- 子类覆盖父类的方法时,权限不能低于父类。
- 方法重载与子类重写的区别
- 重载: 在同一个类里方法名相同,但是参数列表不同,被称为重载。
- 方法名相同,参数列表不同,与返回值无关。
- 重写(覆盖):子类里重新声明的一个与父类形同的方法,把父类方法覆盖了。被称为重写。
- 方法名相同,参数列表相同,返回值相同.
- 重写分为
- 子全覆盖并替换父中的方法
- 子增加本身特有的功能方法?
## 向上转型
- 定义:子类对象可以转为父类类型的应用,这个过程被称为向上转型
- 细节
- 父类类型的引用无法直接访问子类里特有属性。
## 向下转型
- 格式: A extends B
```
A a = new A();
B b = a;//向上转型
A a2 = (A)b;//向下转型(强制)
```
- 注意
- 向下转型的时候,必须明确父类类型的引用就是某个指定类型的子类的对象,才能向下转型。否则的话,会 ClassCastException 异常。
-
- instanceof 关键字
- a instanceof B : 判断a是否是一个B类型的对象。
## 多态
不同子类类型的对象转成父类类型的引用,调用相同方法,表现出来的效果不同, 这种现象被称为多态。
动态绑定: 一个对象执行方法的时候,会确定的检查该对象是一个什么类型的对象,再调用对应的方法。