(后续还会更新完善)
目录
java基础编程
一、基础语法
1、标识符
1.1 定义
- 对变量、方法和类等要素命名时使用的 字符序列,(自己可以起名字的地方放就叫标识符)
1.2 规则
- 构成:26个英文字母大小写 、0 - 9数字、_ 或 $
- 禁止使用:数字开头、含有空格、使用关键字或保留字
- 区分大小写,长度无限制
1.3 规范
- 包名:字母全部小写,一般格式为 【前缀.发起者名.项目名.模块名】
- 类名、接口名:大驼峰命名形式;一个单词 首字母必须大写;多个单词 每个单词的首字母必须大写
- 变量名、方法名:小驼峰命名形式;一个单词全部小写;多个单词 第一个单词全部小写,其他单词的首字母大写
- 常量名:所有字母大写;多个单词用 下划线 _ 隔开
- 注意点:为提高阅读性,命名时尽量做到“见名起意”
1.4 标识符举例
- 包名
//包名
package org.springframework.boot.util
- 类名
//类名(一个单词)
class Student{}
//类名(多个单词)
class SmartStudentTest{}
- 接口名
//接口名(一个单词)
interface Study{}
//接口名(多个单词)
interface GoodStudyTest{}
- 变量名
//变量名(一个单词)
int id;
//变量名(多个单词)
int orderId;
- 方法名
//方法名(一个单词)
void insert(){}
//方法名(多个单词)
void clearAllName(){}
- 常量名
//常量名(一个单词)
public static final int NUMBER = 120;
//常量名(多个单词)
public static final String LOGIN_USER_SESSION_KEY = "current_login_user";
2、关键字
1.1 定义
- java中用以特殊用途而预先占用的单词或标识符称之为关键字
1.2 特点
- 全部为小写
1.3 常用关键字及其分类
- 定义数据类型的关键字
- 定义流程控制的关键字
- 定义访问权限修饰符的关键字
- 定义类、方法、变量修饰符的关键字
- 定义异常处理的关键字
- 定义类与类、类与接口之间关系的
- 定义建立实例、引用实、判断实例的关键字
- 用于包的关键字
- 其他修饰符关键字
- 定义数据类型值的字面值
1.4 保留字
- goto、const,注意(自己命名时要避开使用保留字),不常用
3、变量、常量和作用域
3.1 变量
- 定义
变量是程序中最基本的存储单元,由作用域、变量类型、变量名组成,每个变量在使用前必须提前声明。
- 声明格式
//声明格式【1】 数据类型 变量名称;
int abs;//无初始化
//声明格式【2】 数据类型 变量名称 = 值;
int ats = 5; //显示初始化
- 分类
变量分为局部变量、成员变量,成员变量又以是否被static关键字修饰分为实例变量(属性)和类变量(静态属性)
局部变量
【声明格式】:变量类型 变量名称 = 变量值;
【声明位置】: 1.方法或构造器的形参中
2.方法内部
3.代码块内部
【作用范围】:1.方法或构造器的形参中:在方法体和构造器内部任何位置都可以使用
2.方法内部、代码块内部:从定义的地方开始到方法体或代码块结束
【生命周期】 :出生——运行到创建变量语句时
死亡——超过其作用范围
实例变量 (属性)
【声明格式】:访问修饰符 变量类型 变量名称 = 变量值;
【声明位置】: 方法体外、类体内
【作用范围】:在类内部,任何地方都可以访问成员变量
【生命周期】 :出生——new对象的时候,开辟内存空间
死亡——堆内存地址没有引用,变成垃圾,被垃圾回收器回收后
【特点】: 1. new的时候占据内存,实例化后才能调用。
2. 非静态变量赋值不发生冲突。【调用格式】: 先实例化对象,再使用对象名访问
范例: Student stu1=new Student(); //实例化对象
stu1.school="北大"; //对象.属性
类变量(静态属性)
【声明格式】:访问修饰符 static 变量类型 变量名称 = 变量值;
【声明位置】: 方法体外、类体内
【作用范围】:在类变量定义之后
【生命周期】 :出生——类加载时,类变量就分配内存空间
死亡——JVM退出。
【特点】: 1. 一声明就被存储在栈中,直接占据内存,可以快速稳定的调用。
2. 全局唯一,在一个运行环境中,静态变量只有一个值,任何一次修改都是全局性的影响。
3. 占据内存,程序中应该包含尽量少的static【调用格式】:1: 使用类名访问(推荐)
范例: Student.school="清华";
2: 使用对象名访问(不推荐)
范例: Student stu1=new Student();
stu1.school="北大";
3.2常量
- 定义
常量也可称为字面值,即字面显示的值,其本身不会发生变化。 一般用final关键字修饰,分为静态常量、成员常量、局部常量
- 声明
public class HelloWorld {
// 静态常量
public static final double PI = 3.14;
// 声明成员常量
final int y = 10;
public static void main(String[] args) {
// 声明局部常量
final double x = 3.3;
}
}
3.3变量与常量的区别
- 命名规范不一样。默认常量为全大写,而变量为驼峰;
- 修饰符不同。一般常量都会用final修饰,变量不会。而且常量会同时使用static修饰,这是为了要节省内存;
- 常量是指值不会改变(也不能改变)的变量。
4、数据类型及类型转换
4.1 数据类型
八种基本数据类型中,布尔类型(boolen)不参与数据类型转换。
4.2 自动类型转换
- 定义
将数据范围小的数据类型可以直接转换为数据范围大的数据类型的方式叫做自动类型转换
七种基本数据类型(除boolean类型)范围从小到大排序:
byte / short / char ——> int ——> long ——> float ——> double
(byte、short、char这三种类型平级,不能自动类型互转,一般转为int类型计算)
- 举例
//byte转为int byte a = 15; int b = a; System.out.println(b);//15 //short转为int short c = 16; int d = c; System.out.println(d);//16 //char转为int char e = 'a'; int f = e; System.out.println(f);//97 //int转为long int g = 133; long h = g; System.out.println(g);//133 //long转为float long i = 4555L; float j = i; System.out.println(j);//4555.0 //float转为double float k = 4.553f; double l =k; System.out.println(l);//4.552999973297119
4.3 强制类型转换
- 定义
将数据范围大的数据类型强行转换为数据范围小的数据类型的方式叫做强制类型转换,但这样可能会导致数据丢失。
- 例如
//float强转为int float aa = 15.369f; int bb = (int)aa; System.out.println(bb);//15
5、运算符和表达式
运算符包含算术运算符、赋值运算符、比较运算符、逻辑运算符、条件(三目)运算符、位运算符
算数运算符 | +(加),-(减),*(乘),/(除),%(求余),++(自增),--(自减) |
赋值运算符 | =(等于),+=(自加一次等于),-=(自减一次等于),*=(自乘一次等于),/=(自除一次等于),+(字符串连接符) |
比较运算符 | >(大于),<(小于),>=(大于等于),<=(小于等于),==(比较等于),!=(不等于) |
逻辑运算符 | &(按位与),&&(短路与),|(按位或),||(短路或),!(非,即取反) |
三目运算符 | ?:(三目、条件、三元) |
位运算符 | &(按位与),|(按位或),^(异或运算),<<(左移运算符),>>(右移运算符),>>>(无符号运算符),~(非、取反运算符) |
5.1 算数运算符
- ++和-- 运算符
// ++(--)在变量前,先给自己+1或-1,再赋值
int a = 1;
int b = ++a ;
System.out.println(a); //2
System.out.println(b); //2
// ++(--)在变量后,先赋值,再给自己+1或-1
int a = 1;
int b = a++ ;
System.out.println(a);//2
System.out.println(b);//1
- %(求余运算符)
int a = 16;
int b = 3;
System.out.println(a % b);//1(16除以3等于5余1)
5.2 赋值运算符
- 示例
//自加(+=)
int a = 1;
a += 2; //a = a + 2
System.out.println(a);//3
//自减(-=)
int a = 3;
a -= 2; //a = a - 2
System.out.println(a);//1
//自乘(*=)
int a = 3;
a *= 2; //a = a * 2
System.out.println(a);//6
//自除(/=)
int a = 4;
a /= 2; //a = a / 2
System.out.println(a);//2
//字符串连接(+)
System.out.println("abc" + "pwd");//abcpwd
5.3 比较运算符
int a = 1;
int b = 3;
System.out.println(a > b);//false
System.out.println(a < b);//true
System.out.println(a >= b);//false
System.out.println(a <= b);//true
System.out.println(a == b);//false
System.out.println(a != b);//true
5.4 逻辑运算符
- &(按位与),&&(短路与)
int a = 10;
int b = 4;
//短路与 一个成立,后面的不运行了
if (a > 100 && (b++) <5){
}
System.out.println("a < 100 && (b++) <5后b的值为:");
System.out.println(b); //b = 4 //用来判断后面的b++是否被执行
//逻辑与 所有的都运行
if (a > 100 & (b++) <5){
}
System.out.println("a < 100 & (b++) <5后b的值为:");
System.out.println(b); //b = 5 //用来判断后面的b++是否被执行
- |(按位或,逻辑或),||(短路或)
int a = 10;
int b = 4;
//短路或 一个成立,后面的不运行了
if (a > 0 || (b++) > 4){
System.out.println("a > 0 | (b++) > 4");
System.out.println(b); //用来判断后面的b++是否被执行
}
//逻辑或 所有的都运行
if (a > 0 | (b++) > 4){
System.out.println("a > 0 | (b++) > 4后b的值为:");
System.out.println(b); //用来判断后面的b++是否被执行
}
//运行结果
/*
a > 0 | (b++) > 4
4
a > 0 | (b++) > 4后b的值为:
5
*/
5.5 三目运算符
- 格式:(关系表达式)?表达式1:表达式2;
- 运算结果:若关系表达式结果为true,执行表达式1,若为false,执行表达式2
int a1 = 20;
double b1 = 30.0;
double c1 = (a1>b1)?a1:b1;
System.out.println(c1);//30.0
5.6 位运算符
& :全为1,结果为1,否则都为0
|:有一个为1,结果就为1,否则都为0
^ :两者相等为0,不等为1
~:是1为0,是0为1
>>:低位溢出,符号位不变,并用符号位补溢出的高位
<<:符号位不变,低位补0
>>>:低位溢出,高位补 0
5.7 表达式
1、变量、字面值(string、char、number),运算符 构成有效的序列,任何表达式都必须有结果,方法调用是一个结果,结果就是一个值,这个值可以存放在变量中。变量必须有其类型。
2、最简单的表达式: a=a+b (表达式+;等于语句)
3、表达式不是语句,
4、局部变量=临时变量
6、流程控制语句
6.1 分类
- 顺序结构
- 分支结构(if、switch)
- 循环结构(for、while、do…while)
6.2 顺序结构
- JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
- 顺序结构是最简单的算法结构。
- 顺序结构就是从上到下,依次执行
- 示例
public static void main(String[] args) {
System.out.println("Hello1");
System.out.println("Hello2");
System.out.println("Hello3");
System.out.println("Hello4");
System.out.println("Hello5");
}
//运行结果
//Hello1
//Hello2
//Hello3
//Hello4
//Hello5
6.3 分支结构
- if
格式
if(关系表达式) { 语句体; }
执行流程
1、首先计算关系表达式的值
2、如果关系表达式的值为true就执行语句体
3、如果关系表达式的值为false就不执行语句体
4、继续执行后面的语句内容
- if else
格式
if(关系表达式) { 语句体1; }else { 语句体2; }
执行流程
1、首先计算关系表达式的值
2、如果关系表达式的值为true就执行语句体1
3、如果关系表达式的值为false就执行语句体2
4、继续执行后面的语句内容
- if else if else
格式
if(关系表达式1) { 语句体1; }else if(关系表达式2){ 语句体2; } ... else { 语句体n+1; }
执行流程
1、首先计算关系表达式1的值
2、如果值为true就执行语句体1;如果值为false就计算关系表达式2的值
3、如果值为true就执行语句体2;如果值为false就计算关系表达式3的值
…
4、如果没有任何关系表达式值为true就执行语句体n+1
- switch
格式
switch(表达式) { case 值1: 语句体1; break; case 值2: 语句体2; break; ... default: 语句体n+1; break; //最后一个可以省略
格式说明
1、表达式:取值为byte、short、int、char,JDK5以后可以是枚举,JDK7以后可以是String
2、case:后面跟的是要跟表达式比较的值
3、break:表示中断结束的意思,用来结束switch语句
4、default:表示所有情况都不匹配的时候,就执行该处内容,和if语句中的else相似
执行流程:
1、首先计算表达式的值
2、以此和case后面的值进行比较,如果有对应值,就会执行相应语句,在执行过程中,遇到break就会结束
3、如果所有的case的值和表达式的值都不匹配,就会执行default里面的语句体,然后程序结束
6.4 循环结构
- for
格式
for(初始化语句;条件判断语句;条件控制语句){ 循环体语句; }
执行流程
1、执行初始化语句
2、执行条件判断语句,且看结果是true还是false
如果是false,循环结束;如果是true,继续执行
3、执行循环体语句
4、执行条件控制语句
5、返回到2继续
- while
格式
初始化语句; while(条件判断语句) { 循环体语句;//比如:输出内容 条件控制语句; }
执行流程
1、执行初始化语句;
2、执行条件判断语句,看其结果为true还是false
如果是false,循环结束;如果是true,继续执行
3、执行循环体语句
4、执行条件控制语句
5、回到2继续
- do while
格式
初始化语句; do{ 循环体语句;//比如:输出内容 条件控制语句; }while(条件判断语句);
执行流程
1、执行初始化语句
2、执行循环体语句
3、执行条件控制语句
4、执行条件判断语句,看其结果为true还是false
如果是false,循环结束;如果是true,继续执行
5、回到2继续
- 三者区别
1、do…while:先输出一次再进行判断(最少输出一次)
2、for、while:先判断再输出
3、for循环结束后变量不能使用
4、while循环结束后还可以使用(打印变量次数)
二、数组
- 释义
多个相同类型数据按照一定顺序排列的集合,并使用一个名字命名、通过编号的方式对这些数据进行统一管理。
- 分类
按照维度:一维数组、二维数组、三维数组、…多维数组
按照元素的数据类型:基本数据类型元素的数组、引用数据类型元素的数组
1、一维数组
1.1 声明
声明方式一:元素类型[ ] 变量名称;
声明方式二:元素类型 变量名称[ ];
- 示例:
//声明方式一:
int[] arr;
//声明方式二:
int arr[];
1.2 初始化
- 方式一
动态初始化(指定长度):
1、数组存储的数据类型[ ] 数组名字 = new 数组存储的数据类型[数组长度];
2、数组存储的数据类型 数组名字[ ] = new 数组存储的数据类型[数组长度];示例:
//动态初始化 float[] arr1 = new float[10]; double arr2[] = new double[5]; //可以分开写 float[] arr1; arr1 = new float[10]; double arr2[]; arr2 = new double[5];
- 方式二
静态初始化(指定内容):
数据类型[ ] 数组名 = new 数据类型[ ]{元素1,元素2,元素3…};
示例:
//静态初始化 int[] arr = new int[]{0,2,47,8};
1.3 访问
- 使用 .length方法访问数组长度
// 创建数组并初始化
int[] arr = new int[]{0,2,47,8};
//得到数组长度
int length = arr.length;
- 使用下标访问数组元素
// 创建数组并初始化
int[] arr = new int[]{0,2,47,8};
// 访问下标为1的数据
System.out.println(arr[1]); //2
- 利用下标循环遍历数组
int[] arr = new int[5];
for(int i=0;i<arr.length;i++){
循环体
}
- 增强for循环遍历数组
int[] arr = {2,5,8,12,51};
for(int i : arr){
循环体
}
2、二维数组
2.1 声明
声明方式一:元素类型[ ][ ] 变量名称;
声明方式二:元素类型 变量名称[ ][ ];
- 示例
//声明方式一:
int[][] arr;
//声明方式二:
int arr[][];
2.2 初始化
- 方式一
动态初始化(指定长度):
1、数组存储的数据类型[ ][ ] 数组名字 = new 数组存储的数据类型[一维数组的个数][一维数组中元素的个数];
2、数组存储的数据类型 数组名字[ ][ ] = new 数组存储的数据类型[一维数组的个数][一维数组中元素的个数];示例:
//动态初始化 float[][] arr1 = new float[10][5];//合法,代表有10个一维数组,每个一维数组中的元素为5个 double arr2[][] = new double[5][10];//合法,代表有5个一维数组,每个一维数组中的元素为10个 long[][] arr3 = new long[4][];//合法,代表有4个一维数组 int arr4[][] = new int[][4];//非法
- 方式二
静态初始化(指定内容):
数据类型[ ][ ] 数组名 = new 数据类型[ ][ ] { {元素1,元素2,元素3…} , {元素1,元素2,元素3…} , ...... };
示例:
//静态初始化 int[][] arr = new int[][]{{0,2,47,8},{100,12,111,15},{17,-7,99,789}};
2.3 访问
- 使用for循环遍历二维数组
String[][] arr = {{"我", "爱", "你"}, {"中", "国"}, {"亲", "爱", "的", "母", "亲"}};
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();
}
- 使用Array工具类
int[][] arr = {{50, 20, 30}, {80, 90, 60}, {10, 80, 70, 30, 60}};
for (int[] a : arr) {
System.out.println(Arrays.toString(a));
}
3、数组元素查找
3.1 顺序查找
遍历整个数组,与每一个元素逐个比较,直到找到所查找的元素。
- 例子
public void search(){
//创建一个一维数组
int[] arr= {1,5,7,411,46,89,13,96,66};
//从键盘获取一个待查找的数
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个你要查找的整数:");
int res = sc.nextInt();
//利用顺序查找法查找该数并返回其下标
int index = -1;//初始化下标索引
for(int i = 0; i < arr.length;i++){
//判断每个元素是否与待查找的数相等
if(arr[i] == res){
index = i; //若相等,将下标的值付给index
}
}
// 输出查询结果
if (index == -1){
System.out.println("该元素不存在");
}else {
System.out.println("你要查找的元素存在,在数组中的第"+index +"个元素");
}
}
- 结果
3.2 二分查找
对于一个有序的升序列表,将目标值与数组中间的值进行对比:
- 如果目标值与数组中间的值相等,则直接返回表中间的值即可
- 如果目标值与表中间的值不相等,则将两者进行大小比较,从而将数组分成两个:
- 如果目标值小于中间值,说明目标值在中间值往左的数组中,故舍弃中间值往右的数据,重新二分查找中间值往左的数组
- 如果目标值大于中间值,说明目标值在中间值往右的数组中,故舍弃中间值往左的数据,重新二分查找中间值往右的数组
- 最后,重复以上过程,直到找到目标值为止;或直到子数组不存在为止,此时为查找不成功
- 例子
public void search1() {
//创建一个升序的一维数组
int[] arr= {1,5,7,13,46,89,133,196,266};
//从键盘获取一个待查找的数
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个你要查找的整数:");
int res = sc.nextInt();
//利用二分查找找寻目标值
int left = 0; //指向第一个元素
int right = arr.length - 1; //指向最后一个元素
int mid = -1; //初始化一个中间值
//如果左标大于右标则结束
if (left > right ){
System.out.println("无目标值");
}
//如果左标小于右标,开始寻找目标值
while (left < right){
mid = (right + left)/2; //确定中间值的下标
if(arr[mid] == res){ //判断中间值是否和目标值相等,若相等则输入下标并结束查找
System.out.println("目标值的下标为"+mid);
break;
}else if(arr[mid] > res){ //比较中间值和目标值得到大小,若比目标值大,则右标移到中间,放弃对右侧数据的查找
right = mid - 1;
}else if(arr[mid] < res){ //若比目标值小,则左标移到中间,放弃对左侧侧数据的查找
left = mid + 1;
} //一直循环到找到目标值或者左标比右标大为止
}
System.out.println("无目标值"); //若没找到则结束
}
}
4、数组元素排序
4.1 冒泡排序
参考这边文章:个人感觉很详细http://t.csdn.cn/HfX9khttp://t.csdn.cn/HfX9k
- 思想:(假设为升序)将数组中相邻的两个元素大小依次进行比较,将大的数字放后面,小的放前面,最后经过多次循环达到排序的效果。
- 例子 (不是最优程序)
public void bubbleSort(){
//创建一个一维数组
int[] arr= {100,57,7,411,46,89,133,96,66,89,2,12,123,2,121,434423,324242,5353,42,53433,23423,1313};
//冒泡排序
for(int i=0; i < arr.length; i++){
for(int j=0; j < arr.length - 1;j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
//打印结果
System.out.println(Arrays.toString(arr));
}
}
//输出结果:[2, 2, 7, 12, 42, 46, 57, 66, 89, 89, 96, 100, 121, 123, 133, 411, 1313, 5353, 23423, 53433, 324242, 434423]
以上代码只是基本实现了其思路,但还有可以优化的方面(有三处),分别是两层的循环次数和排序完成的标志,具体细节可参考上面的链接。一些给出优化后的代码
public void bubbleSort(){
//创建一个一维数组
int[] arr= {100,57,7,411,46,89,133,96,66,89,2,12,123,2,121,434423,324242,5353,42,53433,23423,1313};
//冒泡排序
for(int i=0; i < arr.length - 1; i++){
boolean flag = false;
for(int j=0; j < arr.length - 1 - i;j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
flag = true;
}
}
if(flag == false){
break;
}
}
//打印结果
System.out.println(Arrays.toString(arr));
}
}
4.2 插入排序
主要思想:
1.从第一个元素开始,该元素可以认为已经排好序。
2。取出下一个新元素,然后把这个新元素在已经排好序的元素序列中从后往前扫描进行比较。
3.如果该元素(已排序) 大于新元素,则将这个已排序的元素移到下一个索引位置。
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置。
5.将新元素插入到该已排序的元素的索引位置后面。
6.重复步骤2~5
- 例子
public void insertSort(){
//创建一个一维数组
int[] arr= {100,57,7,411,46,89,133,96,66,89,2,12,123,2,121,434423,324242,5353,42,53433,23423,1313};
//
int j; //已排序的下标
int t; //待排序的元素
for(int i = 1; i < arr.length; i++){ //从第二个元素开始
if(arr[i] < arr[i - 1]){ //判断后一个元素是否比前一个元素小,如果是
t = arr[i]; //将该元素赋给待排序的元素
for(j = i-1 ; j >= 0 && arr[j] > t; j--){ //从该元素的前一个元素往前找,如果如果比他大,就把元素往后移。
arr[j + 1] = arr[j];
}
arr[j + 1] = t; //然后插入该元素
}
}
System.out.println(Arrays.toString(arr));
}
4.3 选择排序
主要思想:
- 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
- 再从剩余未排序元素中继续寻找最小(大)元素,然后放到未排序序列的起始位置。
- 重复第二步,直到所有元素均排序完毕。
- 例子
public void selsctSort(){
//创建一个一维数组
int[] arr= {100,57,7,411,46,89,133,96,66,89,2,12,123,2,121,434423,324242,5353,42,53433,23423,1313};
for(int i = 0;i <= arr.length ;i++){
int minIndex = i;
boolean flag = false;
for(int j = i + 1;j <= arr.length-1;j++){
if (arr[j] < arr[minIndex]) {
int temp = arr[j];
arr[j] = arr[minIndex];
arr[minIndex] = temp;
flag = true;
}
}
if(flag == false){
break;
}
System.out.println(Arrays.toString(arr));
}
System.out.println(Arrays.toString(arr));
}
三、面向对象
1、Java类及类的成员
1.1 类
类是对一类事物的描述,是抽象和概念上的定义。
- 类的声明
[标识符] [修饰符] class 类名 {
//类的属性
//类的方法
}
标识符有public、private、protected、default
1.2 对象
对象是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同对象。
1.3 类与对象
类是对象的模板,对象是类的实例。
- 使用
类名称 对象名称 = new 类名称 () ;
1.4 类的成员
这里引用的是这篇文章
http://t.csdn.cn/nb6UNhttp://t.csdn.cn/nb6UN
- 属性
在类中声明的成员变量。
class People{
int height;// 身高
int weight;// 体重
}
- 方法
描述类具有的功能,分为
- 无参数无返回值
- 在本类中调用:同一级别,直接调用,方法名();
- 在其他类中调用:对象名.方法名
- 无参数有返回值
- 在本类中调用:变量 = 方法名();(这个变量用于接收返回值)
- 在其他类中调用:变量 = 对象.方法名();(这个变量用于接收返回值)
- 在其他类中调用:System.out.println(对象名.方法名());
- 有参数无返回值
- 在本类中调用:方法名(实参列表);
- 在其他类中调用:对象.方法名(实参列表);
- 有参数有返回值
- 在本类中调用:变量 = 方法名(实参列表);
- 在其他类中调用:变量 = 对象.方法名(实参列表);
- 在其他类中调用:在其他类中调用:System.out.println(对象名.方法名(实参列表));
public class Method {
public void aMethod() {
System.out.println("无参数无返回值的方法");
}
public int bMethod() {
System.out.println("无参数有返回值的方法");
return 10; //return后面填与返回值类型相同的值或者对象
}
public void cMethod(int c) {
System.out.println("有参数无返回值的方法");
}
public int dMethod(int d) {
System.out.println("有参数有返回值的方法");
return d; //return后面填与返回值类型相同的值或者对象
}
public static void main(String[] args) {
//定义变量ret
int ret;
//将Method类进行实例化
Method method = new Method();
//通过实例化对象调用aMethod()
method.aMethod();
//通过实例化对象调用aMethod()
ret = method.bMethod();
//通过实例化对象调用cMethod(),并传入具体的实参
method.cMethod(11);
ret = method.dMethod(12);
//打印输出ret为12,即最后一次赋值
System.out.println(ret);
}
}
- 构造器
构造器通常也叫构造方法、构造函数,构造器在每个项目中几乎无处不在。当你new一个对象时,就会调用构造器。
- 函数名必须和类名相同
- 作用是构造出来一个类的实例,确保对象得到初始化
- 没有返回值,连void都没有
- 根据有无参数,可分为有参构造和无参构造
- 使用new关键字,本质是在调用构造器
- 一旦出现了有参构造,无参构造就必须定义
- 构造器格式: [修饰符] 类名 (有参/无参){ }
public class Demo {
String name;
//无参构造一般情况可以省略,但是如果出现了有参构造,无参构造就必须要定义
public Demo() {
}
public Demo(String name) {
this.name = name; //通过this来调用类中的属性String name中的name, = name中的name则是(String name)中的name
}
}
- 代码块
使用 { } 括起来的代码被称为代码块(Code block)
根据其位置和声明的不同,可以分为:
- 局部代码块:用于限定变量生命周期,及早释放,提高内存利用率。
- 静态代码块:主要用于对静态属性进行初始化。
- 实例(构造)代码块:调用构造方法都会执行,并且在构造方法前执行。
- 同步代码块:一种多线程保护机制。
详细的讲解部分参考这两篇文章
http://t.csdn.cn/7CVcjhttp://t.csdn.cn/7CVcj http://t.csdn.cn/cd0Dehttp://t.csdn.cn/cd0De
- 内部类
参考这篇文章http://t.csdn.cn/aGduDhttp://t.csdn.cn/aGduD
- Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类。
- 内部类的分类:
1.成员内部类
/** * 成员内部类(非静态) */ public class OuterClass { //定义外部类的成员变量 private int a; public String b; //定义外部类的无参构造器 public OuterClass(){ this.a = 15; this.b = "tom"; } //定义外部类方法 public void fun(){ System.out.println("外部类方法"); } //定义一个非静态的成员内部类 public class InnerClass{ //定义内部类的成员变量 private int c; public float d; //定义内部类的无参构造方法 private InnerClass(){ this.c = 9; this.d = 14.33f; } //定义内部类方法 public void fun(){ System.out.println("内部类方法"); } } public static void main(String[] args) { //创建外部类的对象 OuterClass oc = new OuterClass(); //创建内部类的对象 OuterClass.InnerClass oic = oc.new InnerClass(); //调用外部类的方法 oc.fun(); //打印外部类的属性 System.out.println(oc.a); System.out.println(oc.b); //调用内部类的方法 oic.fun(); System.out.println(oic.c); System.out.println(oic.d); } }
2. 局部内部类(编写在方法内、代码块内、构造器内)
/** * 局部内部类(非静态) */ public class OuterClass1 { //定义外部类的成员变量 private int a; public String b; //定义外部类的无参构造器 public OuterClass1(){ this.a = 15; this.b = "tom"; } //定义外部类方法 public void fun(){ System.out.println("外部类方法"); //定义局部内部类 class InnerClass{ //定义内部类的成员变量 private int c; public float d; //定义内部类的无参构造方法 private InnerClass(){ this.c = 9; this.d = 14.33f; } //定义内部类方法 public void fun(){ System.out.println("内部类方法"); } } //在方法内创建内部类对象 InnerClass inner = new InnerClass(); //调用内部类方法 inner.fun(); //打印内部类属性 System.out.println(inner.c); System.out.println(inner.d); } public static void main(String[] args) { //创建外部类对象 OuterClass1 oc = new OuterClass1(); //调用外部类方法(里面包含局部内部类) oc.fun(); } }
3.匿名内部类
匿名内部类看这篇文章就够了
http://t.csdn.cn/Yo4og
http://t.csdn.cn/Yo4og
4.静态内部类(用static关键字修饰的)
- 内部类优点:
1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整;
2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏;
3.方便编写事件驱动程序;
4.方便编写线程代码。
2、三大特征
2.1封装
2.2继承
2.3多态