javaSE学习
一、java基础
1.Java语言特点
简单性 | ==面向对象== | 分布式 |
---|---|---|
==可移植性(跨平台)== | 多线程 | 动态性 |
健壮性/鲁邦性 | 安全性 | ==开源== |
2.Java语言平台版本:
-
JavaSE: Java平台标准版
-
JavaME:Java平台小型版
-
JavaEE:Java平台企业版
3.JDK、JRE、JVM
-
==JDK(Java Development Kit Java开发工具包)==
JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。所以安装了JDK,就不用在单独安装JRE了。 其中的开发工具:编译工具(javac.exe) 执行工具(java.exe) 打包工具(jar.exe)等
-
==JRE(Java Runtime Environment Java运行环境)==
包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。
-
==JVM(Java Virtual Machine Java虚拟机)==
整个java实现跨平台的最核心的部分,保证程序的跨平台性,以及编译执行写好的java程序!
4.Java语言的特点:
简单 面向对象 跨平台性 多线程 安全性 健壮性 动态性 开源 分布式
5.环境变量配置和JDK下载和安装:
5.1下载和安装
通过官方网站获取JDK http://www.oracle.com
==注意:针对不同的操作系统,需要下载对应版本的JDK==
安装:下一步
5.2.环境变量配置
首先右键==【此电脑】==---> 选择==【属性】==---> 点击左侧的==【高级系统设置】== ---> 点击==【环境变量】==---> 在下方的==【系统变量】==中点击==【新建】==
1.新建 JAVA_HOME jdk安装路径 2.!!!找到 path !!!!! 在里面新建 条目 %JAVA_HOME%\bin 等价于: bin目录下路径 3.检测 win+R cmd 回车 java -version 4.为什么配置环境变量 在任意目录下执行,如果没有配置只能在bin目录下
6.DOS命令
6.1快捷键
全选 ctrl + A | 复制 ctrl + c | 粘贴 ctrl + v |
---|---|---|
剪切 ctrl + x | 撤销 ctrl + z | 保存ctrl + s |
打开所有磁盘 window + e | 最小化当前所有窗口 window +d | 切换程序 alt + tab / window + tab |
打开运行窗口 window + r |
6.2如何打开DOS命令窗口
-
win + r 打开运行窗口,输入cmd,回车。
-
点击win窗口图标,输入cmd,选择命令提示符
6.3常用的DOS命令
D: | 盘符切换 |
---|---|
dir | 查当当前目录 |
md | 创建目录(计算机中只有目录(文件夹)和文件) |
rd | 删除目录 |
echo > a.txt | 创建文件 |
del | 删除文件 |
cd | 指定进行目录 |
cd.. | 退回上一级目录 |
cd\ | 退回当前盘符的根目录 |
cls | 清屏 |
calc | 打开计算器 |
notepad | 打开记事本 |
control | 打开控制面版 |
services.msc | 打开服务 |
exit | 退出dos |
7.HelloWorld案例
7.1新建文本文档文件,修改名称为HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("HelloWorld");
}
}
二、Java基础语法
1.注释
1.1单行注释
// 这是单行注释文字
1.2多行注释
/* 这是多行注释文字 这是多行注释文字 这是多行注释文字 */ // 注意:多行注释不能嵌套使用。
1.3文档注释
/** 这是文档注释的内容 */
2.关键字
关键字是指被java语言赋予了特殊含义的单词
关键字的字母全部小写。
常用的代码编辑器对关键字都有高亮显示,比如现在我们能看到的public、class、static等。
3.常量
在程序运行过程中,其值不可以发生改变的量。
-
字符串常量
用双引号括起来的多个字符(可以包含0个、一个或多个),例如"a"、"abc"、"中国"等
-
整数常量
整数,例如:-10、0、88等
-
小数常量
小数,例如:-5.5、1.0、88.88等
-
字符常量
用单引号括起来的一个字符,例如:'a'、'5'、'B'、'中'等
-
布尔常量
布尔值,表示真假,只有两个值true和false
-
空常量
一个特殊的值,空值,值为null4.数据类型
4.数据类型
Java是一个强类型语言,对每一种数据都规定了范围
数据类型决定了容器的类型
1.基本数据类型:
整数类型:
byte 字节 1B
short 短整型 2B
int 整型 4B 默认
long 长整型 8B L/l
浮点类型
float 单精度 4B F/f
double 双精度 8B 默认
字符类型:
char 字符 ''单个字符
布尔类型
boolean 值:true/false
2.引用数据类型:
类、枚举、注解
接口
数组
5.变量
5.1变量定义的格式
1.数据类型 变量名 = 初始化值; // 声明变量并赋值
2.先声明,后赋值(使用前赋值即可)
3.在同一行定义多个同一种数据类型的变量,中间使用逗号隔开
数据类型 变量名 = 值,变量名 = 值, ....;
5.2变量注意事项
-
在同一对花括号中,变量名不能重复。
-
变量在使用之前,必须初始化(赋值)。
-
定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大写)。因为整数默认是int类型,整数太大可能超出int范围。
-
定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大写)。因为浮点数的默认类型是double, double的取值范围是大于float的,类型不兼容。
6.标识符
6.1命名规范:
由字母、数字、下划线_、美元符号$组成,第一个字符不能是数字。 不能使用java中的关键字。 大小写敏感(区分大小写)。
6.2江湖规则:
类名:大驼峰 HelloWorld DataType 每一个单词的首字母都要大写 HelloWorld (大驼峰) 方法、变量:小驼峰 从第二个单词开始,首字母都要大写 包名 :全小写: 倒置域名 . 常量:全部大写 MAX_VALUE
7.类型转换
7.1自动类型转换
把一个数据范围小的数值或者变量赋值给另一个数据范围大的变量; 这种转换是自动的,直接书写即可。
a:小数据到大容器:byte short int long
b:整数到小数
c:char类型到int A-65 a-97
数据范围从小到大:byte-->short,char --> int --> long --> float --> double
7.2强制类型转换:
把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量 目标数据类型 变量名 = (目标数据类型)值或者变量;
整数默认是int类型,byte、short和char类型数据参与运算均会自动转换为int类型。
特殊: byte+byte=int short+short=int byte+short=int
boolean类型不能与其他基本数据类型相互转换。
8.运算符
8.1算术运算符
+-*/ % /: 商 %: 余数 +: 加 、字符串连接符
运算结果: 整数运算的结果还是整数,小数运算的结果是小数 表达式运算的最终结果类型:是表达式中最大的数据类型 表达式中有字符串:字符串之前的正常运算,字符串之后的都是字符串串连接(注意顺序和优先级)
8.11字符串的"+"操作
当“+”操作中出现字符串时,这个”+”是字符串连接符,而不是算术运算。
表达式中有字符串,字符串之前的正常运算,字符串之后的字符串连接
System.out.println(1+5+"adc"+5*6+(6/3)+(6%3));
//输出结果为6adc3020
8.2赋值运算符
符号 | 作用 | 说明 |
---|---|---|
= | 赋值 | a=10,将10赋值给变量a |
+= | 加后赋值 | a+=b,将a+b的值给a |
-= | 减后赋值 | a-=b,将a-b的值给a |
*= | 乘后赋值 | a*=b,将a×b的值给a |
/= | 除后赋值 | a/=b,将a÷b的商给a |
%= | 取余后赋值 | a%=b,将a÷b的余数给a |
==注意:==
扩展的赋值运算符隐含了强制类型转换。
面试题:
short s=1; s = s+1; //错误
short s=1; s+=1;//正确
s += 1;
不是等价于 s = s + 1;
而是等价于 s = (s的数据类型)(s + 1);
8.3自增自减运算符
自增:++ 自减:--
a++ 与 ++a 区别:
1.单独使用的时候,结果是一样的。
2.参与操作的时候:(很少用!)
a++: 先拿变量参与操作,后拿变量++
++a:先++,后拿变量参与操作。
a-- 与 --a :规则相同
最常见的用法:单独使用。
int m = 9;
int n = ++m; // 赋值运算,++在前边,所以是使用m自增后的值赋值给n,m本身自增1
System.out.println("m=" + m ); // m=10
System.out.println("n=" + n );//n=10
int c=9,f;
c=10;
f=(++c)+(c--)+(c++);
System.out.println("f="+f);// c=11
System.out.println("c="+c);//f=11+11+10
8.4关系运算符
符号 | 说明 |
---|---|
== | a==b,判断a和b的值是否相等,成立为true,不成立为false |
!= | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
> | a>b,判断a是否大于b,成立为true,不成立为false |
>= | a>=b,判断a是否大于等于b,成立为true,不成立为false |
< | a<b,判断a是否小于b,成立为true,不成立为false |
<= | a<=b,判断a是否小于等于b,成立为true,不成立为false |
注意事项:
关系运算符的结果都是boolean类型,要么是true,要么是false。 不要把==误写成=,==是判断是否相等的关系,=是赋值。
8.5逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
& | 逻辑与(和) | a&b,a和b都是true,结果为true,否则为false |
| | 逻辑或 | a|b,a和b都是false,结果为false,否则为true |
^ | 逻辑异或 | a^b,a和b结果不同为true,相同为false |
! | 逻辑非 | !a,结果和a的结果正好相反 |
8.6短路逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
&& | 短路与 | 作用和&相同,但是有短路效果 |
|| | 短路或 | 作用和|相同,但是有短路效果 |
&& 短路与:只要有一个为假,结果就是假 ;后面的表达式不再执行 || 短路或:只要有一个为真,结果就是真 ;后面的表达式不再执行
int x = 4;
int y = 5;
System.out.println((x > y) && ( x < y));//false && true = false
//短路与, 左边false, 右边不执行
System.out.println((x < y) || ( x > y));//true || false = true
//短路或 ,左边为true, 右边不执行
8.7三元(目)运算符
表达式 ? true执行 : false执行的表达式
int a = 1;
int b = 2;
int c = a > b ? a : b;
// 如果表式返回的是true ,把结果1返回 ,如果表达式返回的false, 把结果2返回
9.键盘录入
9.1导包
Scanner 类在java.util包下,所以需要将该类导入。导包的语句需要定义在类的上面。
import java.util.Scanner;
9.2创建Scanner对象
Scanner sc = new Scanner(System.in); // 创建Scanner对象,sc表示变量名,其他均不可变
9.3接收数据
int i = sc.nextInt(); // 表示将键盘录入的值作为int数返回。
import java.util.Scanner;
public class New{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
System.out.println("请输入三个int数据");
int i=sc.nextInt();
int a=sc.nextInt();
int b=sc.nextInt();
int n=i>a?i:a;
int m=n>b?n:b;
System.out.println("最大数为:"+m);
}
}
10.流程控制语句
10.1流程控制语句分类
顺序结构
分支结构(if, switch)
循环结构(for, while, do…while)
10.2分支结构之if语句
if (关系表达式1) {
语句体1;
} else if (关系表达式2) {
语句体2;
}
…
else {
语句体n+1;
}
import java.util.Scanner;
public class IfDemo02{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
System.out.println("请输入int型数据:");
int s=sc.nextInt();
//取值0~100
if (s>=0 && s<=100){
if (s>=90){
System.out.println("你真优秀--奖励你一辆自行车!");
}else if(s>=70){
System.out.println("成绩良好,奖励一个变形金刚!");
}else if(s>=60){
System.out.println("及格了,奖励一瓶娃哈哈AD钙奶!");
}else{
System.out.println("父母混合双打!");
}
}
else{
System.out.println("输入错误");
}
}
}
三.switch循环
1.switch语句
switch (表达式|变量) { //整型(byte ,short ,int) 字符型(char)
case 值1:
语句体1;
break; //跳出,当前匹配项;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
例子:
import java.util.Scanner;
public class SwitchDemo{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
switch a:{
//如果没有加break,程序穿透case运行,直到break才会结束switch
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
default:
System.out.println("星期日");
break;
}
}
}
2.for循环
for (初始化语句;条件判断语句;条件控制语句) {
循环体语句; //重复执行的代码
}
案例:
public class QiuHe{
public static void main(String[]args){
int sum=0;
for(int i=0;i<=100;i++){
if(i%2==0){
sum+=i;
}
}
System.out.println("100以内偶数和为:"+sum);
}
}
3.while循环
3.1while结构
while (条件判断语句) {
循环体语句;
条件控制语句(循环变量更新);
}
3.2案例
public class WhileDemo{
public static void main(String[]args){
/* 输出0~100的和
int i=0;
int sum=0;
while(i<=100){
sum+=i;
i++;
}
System.out.println(sum);
*/
//输出0~100偶数
int i=0;
while(i<=100){
if(i%2==0){
System.out.println(i);
}
i++;
}
}
}
4.do...while循环
4.1结构
初始化语句;
do {
循环体语句;
条件控制语句;
}while(条件判断语句);
4.2案例
5.三种循环的区别
5.1for、while和do...while
for和 while :先进行条件判断,条件成立再执行循环体;可能一次都不执行 do-while :先执行一次循环,再判断条件,条件成立接着执行循环体:至少会执行一次
5.2for循环和while的区别
for循环中的初始变量,归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了 while的初始变量,不归属其语法结构中,在while循环结束后,该变量还可以继续使用 for循环一般用在确定一个范围的场景, while循环一种不确定的范围的场景
5.3作用域
变量的有效范围 从声明开始,到所在的{}结束; 共同的区域中不能重复定义变量
5.4死循环:
java里面的三种死循环的效率是一样的。 注意事项: 合理使用 1. for(;;){} 2. while(true){} 3. do {} while(true)
5.5跳转语句:
break : 作用在 switch 和 循环 中 --都表示结束 continue :只能用在循环中 :结束本次循环,进入下一次循环 return :在方法中,表示结束方法 break和continue只能在循环中进行使用,单独使用无任何意义!!
案例://ATM 存取款系统
import java.util.Scanner;
public class Atm{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
System.out.println("欢迎使用中国银行ATM自助服务系统");
double m=0;
while(true){
System.out.println("请选择你需要的服务:1.查询 2.存款 3.取款 4.退卡");
int i=sc.nextInt();
switch(i){
case 1:
System.out.println("查询界面");
System.out.println("您当前余额为:"+m+"元");
break;
case 2:
System.out.println("存款界面");
System.out.println("请输入你要存的金额:");
int cun=sc.nextInt();
m+=cun;
System.out.println("您存入:"+cun+"元,"+"当前余额为:"+m+"元");
break;
case 3:
System.out.println("取款界面");
System.out.println("请输入你要取的金额:");
int qu=sc.nextInt();
m-=qu;
System.out.println("您取出:"+qu+"元,"+"当前余额为:"+m+"元");
break;
default:
System.out.println("退出界面");
System.out.println("谢谢使用");
return;
}
}
}
}
6.循环嵌套
只有当内层循环执行完毕,才可以执行外层循环。
public class Jiu{
public static void main(String[]args){
for(int i=1;i<10;i++){
for(int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="+(j*i)+"\t");
}
System.out.println();
}
}
}
7.Math类随机数
7.1方法
方式一:Math中的方法:
double d=Math.random(); [0,1)之间的一个小数
(int)(Math.random()*100)+1 [1-100]之间的整数
方式二:Random类
import java.util.Random; //导包
Random r=new Random(); //创建对象
int x=r.nextInt(); //int区间的一个随机整数
r.nextInt(100) //[0-100)
r.nextInt(100)+1 //[1-100]
案例://猜数字
import java.util.Scanner;
import java.util.Random;
public class CaiShu{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
Random r=new Random();
int d=r.nextInt(100)+1;
while(true){
System.out.println("请输入1~100之间的一个数");
int s=sc.nextInt();
if(s==d){
System.out.println("恭喜你猜对了");
break;
}else if(s>d){
System.out.println("你猜的数据大了");
}else{
System.out.println("你猜的数据小了");
}
}
}
}
四 .数组
1.一维数组
1.1数组
定义:数据类型[] 数组名; 数据类型 数组名[];
用来存储一组数据类型相同的多个数据的容器 数组中可以存任意类型 数组中的元素的类型是相同的
数组一旦声明,长度不可变 a.length
1.2数组的初始化:
1 静态初始化 在创建数组时,直接将元素确定,由系统计算出数组的长度 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
int z[]={11,22,33};
int q[]=new int[]{11,22,33};
2 动态初始化 数组动态初始化就是只给定数组的长度,由系统给出默认初始化值 数据类型[] 数组名 = new 数据类型[数组长度];
int[]a=new int[5];
//byte[]a=new byte[5];//整数类型的默认值0
//double[]a=new double[5];//浮点类型默认值:0.0
//boolean[] a=new boolean[5];//boolean类型默认值false
1.3访问数组元素(下标/索引)
每一个存储到数组的元素,都会自动的拥有一个编号,从0开始。
这个自动编号称为数组下标(索引)(index),可以通过数组的索引访问到数组中的元素。
1.4数组的变量
//a.length=7; 数组长度不可变 //用length表示数组长度 //索引的有效范围: 0 a.length-1 (i<a.length) //a=null;// NullPointerException 空指针异常 //a[5] ://ArrayIndexOutOfBoundsException: 5 数组越界异常
1.5数组的遍历
int [] a = {1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
2.二维数组
2.1二维数组格式
二维数组其实就是这个二维数组中有多少个一维数组,是一维数组的 一维数组。
格式一:
数据类型 变量名 = new 数据类型m
m表示这个二维数组有多少个一维数组
n表示每一个一维数组的元素个数
格式二:
数据类型 变量名 = new 数据类型m;
格式三:
标准版: 数据类型 变量名 = new 数据类型{{元素…},{元素…},{元素…}};
简化版: 数据类型 变量名 = {{元素…},{元素…},{元素…}};
2.2二维数组遍历
int a[]={1,2,3};
int b[][]=new int[3][];
b[0]=new int[3];
b[1]=new int[]{1,2,3};
b[2]=a;
b[0][0]=11;
b[0][1]=12;
b[0][2]=13;
for(int i=0;i<b.length;i++){//i获得一维数组
for(int j=0;j<b[i].length;j++){//j获得一维数组里面的元素
System.out.println(b[i][j]);
}
}
3数组的排序
3.1冒泡排序:
冒泡排序:相邻的两个元素进行比较,满足条件 交换位置 每次都是从a[0]和 a[0+1] 开始比较: 所以 j=0 , 第一遍结束 j+1<a.length 已经选出来的数据放到后面,选出来的数据不再参与比较 所以 j <a.length- 1- i , i:已经选出的最大值个数
案例:
int b[]={5,2,6,8,4,1,9};
for(int i=0;i<b.length-1;i++){ //i表示遍数
for(int j=0;j<b.length-1-i;j++){
if(b[j]>b[j+1]){
int t=b[j];
b[j]=b[j+1];
b[j+1]=t;
}
}
}
for(int i=0;i<b.length;i++){
System.out.println(b[i]);
}
3.2选择排序:
选择排序:选定一个位置,拿这个位置的元素和后面的每一个元素比较;满足条件,交换位置
案例:
int c[]={77,22,15,45,90,12};
for(int i=0;i<c.length;i++){
for(int j=i+1;j<c.length;j++){
if(c[i]<c[j]){
int p=c[i];
c[i]=c[j];
c[j]=p;
}
}
}
for(int i=0;i<c.length;i++){
System.out.println(c[i]);
}
五.方法
1.方法的概述
1.1什么是方法:
方法(method)完成某一个特定功能的代码块。
1.2==注意==:
方法必须先创建才可以使用,该过程成为方法定义
方法创建后并不是直接可以运行的,需要手动使用后,才执行,该过程成为 方法调用
1.3方法的语法:
修饰符 返回值类型 方法名(参数列表){ //代码省略... return 结果; } //现阶段 固定写法: public static 返回值类型 方法名(参数列表){ //代码省略... return 结果; }
2、参数:
作用:灵活的传递数据
分为形参和实参 形式参数:形参:定义方法时声明的参数 有参的方法 实际参数 实参:调用时传递的具体的数据(类似于为变量赋值) public static 返回值类型 方法名(数据类型 参数名,数据类型5 参数名,..数据类型 参数名){ //代码省略... return 结果; }
public static void main(String[] args) {
//接收返回值并打印
int x=sum(11,22);
int y=sum(35,66);
System.out.println(x);
System.out.println(y);
}
public static int sum(int a,int b){
int sum=a+b;
return sum; //不写void有返回值 ,写void无返回值
}
3、方法类型
1.无参无返回值 2.无参有返回值 3.有参无返回值 4.有参有返回值
4.返回值:
方法的功能完成之后向调用者返回的数据 有返回,使用return 将结果返回给调用者。 没有返回值:void 不需要return 数据 注:除了void以外的都要有return 返回的数据必须和返回值类型一致 只能返回一条数据 return 数据 必须是方法中的最后一条语句 有返回值的方法,可以用容器接收,也可以打印输出;没有返回值则不可以!
5、参数传递:
1.基本数据类型的参数,形式参数的改变,不影响实际参数 每个方法在栈内存中,都会有独立的栈空间,方法运行结束后就会弹栈消失 2.引用类型的参数,形式参数的改变,影响实际参数的值 引用数据类型的传参,传入的是地址值,内存中会造成两个引用指向同一个内存的效果,所以即使方法弹栈,堆内存中的数据也已经是改变后的结果
案例: 1.定义打印数组的方法 2.定义一个方法,传递数组,返回数组中的最大值
public static void main(String[] args) {
int [] a={10,9,30,15};
printShu(a);
bbb(a);
sheng(a);
xuan(a);
}
public static void printShu(int[]arr){
System.out.print("[");
int max=arr[0];
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+", ");
if(max<arr[i]){
max=arr[i];
}
}
System.out.print("]"+"\n");
System.out.println("最大值为:"+max);
}
6.重载overload
6.1方法重载概述
在同一个类中,具有相同的方法名, 参数列表不同(参数的个数、类型、顺序不同),与返回值无关
参数列表:个数不同,数据类型不同,顺序不同。
案例:
public static void main(String[] args) {
sum(11,22);
//sum(1,2,3);
double x=sum(1.1,2);
System.out.println(x);
System.out.println(sum(1.1, 2.0));
sum(12, "xxxx");
sum("yyy", 22);
}
public static void sum(int a,int b){
System.out.println("111");
System.out.println(a+b);
}
public static double sum(double a,double b){
System.out.println("22");
return a+b;
}
public static int sum(int a,int b,int c){
System.out.println("333");
return a + b + c;
}
public static void sum(int a,String c){
System.out.println("4444");
}
public static void sum(String x,int y){
System.out.println("5555");
}
/*
public static void sum(int y,String x){
System.out.println("5555");
}*/
}
六.类和对象
OOP 面向对象编程思想 Oriented Object programming
扩展: C 语言是一种纯面向过程的编程语言,侧重点是过程 java 语言是一种纯面向对象的编程语言,侧重点是对象
1.面向对象的概念
(1)对象
客观存在具有唯一性的个体。
特征:属性 和 行为
属性:就是该事物的状态信息。 行为:就是该事物能够做什么。
(2)类 具有相同特征的对象的集合。
特征:属性 和 行为
(3)联系 对象是类的具体化; 类是对象的抽象(概括)。 类是创建对象的模板
2.类的定义
[修饰符] class 类名{
//成员变量--属性
public String name;
数据类型 变量名;
//成员方法--行为
[修饰符] 返回值类型 方法名([参数列表]){
}
//主方法(成员方法)--程序执行的入口
public static void main(String[] args){
//实例化:创建对象的过程
//同义词:对象==实例
类类型 对象名=new 类();
对象名.属性名=数据值;
对象名.方法名();
}
}
案例:
package com.yz.oop;
/**
* @Author: yz
* @Date: 2024/3/27 15:21
*/
public class Student {
//属性
int num;
String name;
byte age;
char gender;
boolean isAdult;
//方法
//不写static调用要加对象名
public void teach(){
System.out.println("学习");
}
public void eat(){
System.out.println("好好吃饭");
}
public void sing(){
System.out.println("唱歌");
}
public static void main(String[] args) {
// com.yz.oop.Student@7f31245a 首地址
//类名 对象名=new 类名();
Student s=new Student(); //创建对象=实例化
System.out.println(s);
s.num=20240327;
s.name="小明";
s.age=18;
s.gender='男';
s.isAdult=true;
/* 对象名.成员变量;
对象名.成员方法();*/
System.out.println(s.num); //没赋值,默认值
System.out.println(s.name);
System.out.println(s.age);
System.out.println(s.gender);
System.out.println(s.isAdult);
s.teach();
s.eat();
s.sing();
}
}
3.注意事项:
(1)类中定义的属性和行为,是所有对象都有属性和行为 (2)属性和行为应该表现在某个具体的对象身上 (3)对象之间的属性和行为,是相互独立的,没有任何联系。 (4)对象在创建时,根据类的定义,来获取属性的内容和行为。
案例:
String brand;
double price;
public void call(){
System.out.println("正在使用价格为"+price+"元的手机打电话....");
}
public void sendMessage(){
System.out.println("正在使用"+brand+"品牌的手机发短信....");
}
public void playGame(){
System.out.println("正在使用价格为"+price+"元的"+brand+"品牌的手机玩 XXX 游戏....");
}
public static void main(String[] args) {
ZuoYePhone p=new ZuoYePhone();
p.price=998;
p.brand="小米";
p.call();
p.playGame();
p.sendMessage();
}
4.成员变量和局部变量的区别
(1)定义位置的比较 成员变量:定义在类中,表示类的属性 局部变量:定义在方法中或者方法声明上(形式参数),用来描述方法 的功能 (2)作用域 成员变量:作用于整个类,可以在类的内部任何地方访问(包括方法内部) 局部变量:作用于当前方法内,只能在当前方法中访问,其他方法访问不到 (3)缺省值:当没有赋值时,系统根据数据类型提供的默认值 成员变量:有 局部变量:没有,必须手动赋值 注意:所有变量都必须先赋值,再使用 缺省值 数据类型 缺省值: —————————————————————————————————————— 整型:byte short int long 0 浮点类型:float double 0.0 字符类型:char \u0000 逻辑类型:boolean false 字符串类型:String null (4)在内存中的位置不同 成员变量:堆内存 局部变量:栈内存 (5) 生命周期不同 成员变量:随着对象的创建而存在,随着对象的消失而消失 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失 (6)修饰符的使用 private 成员变量:可以加修饰符 局部变量:不可以 重名问题: 局部变量和成员变量重名:就近原则(局部变量会屏蔽成员变量) this.成员变量 局部变量之间不能重名,成员变量之间不能重名
案例:
int num;/*成员变量 作用于整个类当没有赋值时,
系统根据数据类型提供的默认值
重名问题:
局部变量和成员变量重名:就近原则(局部变量会屏蔽成员变量) this.成员变量
局部变量之间不能重名,成员变量之间不能重名
*/
public void text01(){
int num=2;
int a=3;//局部变量 作用于当前方法
System.out.println("num:"+num);
System.out.println("num:"+this.num);//成员变量
}
public void text02(String num){
System.out.println(num);
System.out.println(this.num);
}
public static void main(String[] args) {
VarDemo v = new VarDemo();
v.text01();
v.text02("局部变量");
}
5.封装
5.1封装:将数据私有化
将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。
5.2封装格式:
使用 private 关键字来修饰成员变量。
对需要访问的成员变量,提供公共对应的一对 getXxx 方法 、setXxx 方法。
private:私有的。可以修饰成员变量和成员方法。
注意:被private修饰的成员只能在本类中访问。
private 数据类型 变量名 ;
private String name;
private char sex;
private String num;
private boolean adult;
5.3this 关键字
表示这个对象: 语法: this.成员变量 :用来区分(和局部变量重名的)成员变量 方法中只有一个变量名时,默认也是使用 this 修饰,可以省略不写
6.构造方法
(1)构造器的作用:创建类的对象(实例化)
(2)构造器的语法: [修饰符] 类名([参数列表]){ //初始化语句 }
构造器=构造函数=构造方法 名字跟类名必须完全一致 构造器不是成员方法:没有返回值 void 作用:创建对象 任何类都有构造器:如果没有定义,系统会提供一个默认的构造器,如果有定义,系统不再提供 构造器的重载:在一个类中,定义多个构造器。都可以创建对象,具体调用哪个,由参数决定
(3)构造器的重载: 在同一个类中,定义了多个构造器。 注意:我们可以任意的选择任何一个构造器来创建对象。
构造器重载的原则:参数列表必须不同。 参数列表不同的判断: a.参数个数不同。 b.参数个数相同,但对应顺序的参数数据类型不全相同。
(4)缺省: 如果你没有定义构造器,系统会提供一个默认的无参的构造器; 但是,如果定义了,系统就不提供了。
七继承和抽象
1.继承
1)概念:从现有的类中派生一个新类的过程。 (2)目的:子类从父类继承某些属性和行为,在子类中不需再进行定义,这样可以减少子类的代码量。 (3)语法: [修饰符] class 子类类名 extends 父类类名{ //子类主体 } (4)继承的原则: a.同包下,子类可以继承父类非私有的属性和方法。 b.不同包下,子类可以继承父类公有的和受保护的属性和方法。 (5)子类的定义 允许子类定义自己的新的属性和方法。 (6)注意事项: a.类是单继承:子类只能继承一个父类 b.子类不能继承父类的构造器
2.方法的重写(override)--覆写--覆盖
方法重写:子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写 或者复写。声明不变,重新实现。
前提:继承 重写原则:a.修饰符>=父类的修饰符 b.方法名相同,返回值类型相同,参数列表相同前提 比较:方法的重载(overload): 前提:类的内部 原则:方法名相同,参数列表不同, 与返回值和修饰符无关
3.super
a.继承的理解 前面说的 子类继承父类 ,真正的意义是:子类中的每一个对象在父类中有且仅有一个父类对象与之对应,或者说一个子类对象继承一个父类对象。 b.使用super访问父类对象的属性和方法 super.属性名 super.方法名() super代表:当前对象的父类对象 c.使用super访问父类构造器 super([参数列表]); //这句话必须作为子类构造器的第一条语句。 super代表:父类构造器
案例:
//父类
public class Employee {
String name;
double salary;
public double getMoney(double salary){
System.out.println("张三的基本工资是:"+salary+"元。");
return salary;
}
public void work(){
System.out.println("做大做强!再创辉煌!");
}
}
//子类
public class HourEmployee extends Employee{ //继承父类
double hSalary;
int hours;
public HourEmployee() {
}
public HourEmployee(double hSalary, int hours) {
this.hSalary = hSalary;
this.hours = hours;
}
@Override//重写:子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同)
public double getMoney(double salary) {
super.getMoney(salary);
System.out.println("时薪"+hSalary+"元,时长"+hours+"小时,小时工资:"+(hSalary*hours)+";");
System.out.println("本月总工资"+(salary+(hSalary*hours)));
return salary;
}
public void eat(){
System.out.println("我喜欢吃红烧肉");
}
3.1 super和this
this: 1.this.成员变量 :表示这个对象: 语法:this.成员变量:用来区分(和局部变量重名的)成员变量 方法中只有一个变量名时,默认也是使用 this 修饰,可以省略不写 2.this(参数列表):在一个构造方法中调用另一个构造方法(完成初始化工作) super: 1.父类对象 super.父类成员 :用来区分(和子类重名的)父类成员 2.父类构造器super():在子类构造器中调用父类构造器 注意:super() 必须是当前构造器的第一条语句。
4.抽象
4.1抽象 :
就是从具体到概念化的过程;
只有方法的声明,没有方法体{}的方法,就是抽象方法
抽象方法所在的类必定是一个抽象类
public abstract void 方法名();//抽象方法 修饰符 abstract 返回值类型 方法名 (参数列表); public abstract class 类名//抽象类
4.2抽象的使用
具体的子类继承抽象的父类必须重写父类所有的抽象方法
抽象的子类继承抽象的父类,不用再去重写父类的所有抽象方法,这种是没有意义
public abstract void eat();//父类定义抽象方法
//子类实现
public class Cat extends Animal{
//在子类中能继承并实现抽象方法
//否则子类也必须是抽象类
public Cat() {
super();
}
@Override
public void eat() {
System.out.println("猫喜欢吃鱼");
}
}
4.3抽象的注意事项
1、有抽象方法的类,这个类一定是抽象类 2、抽象类中可以有抽象方法,也可以有普通方法 3、抽象类有没有构造方法 有 4、抽象类是否可以实例化 不能 5、抽象类中的普通方法如何调用,通子类继承过来即可调用
(1)抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。 (2)抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。 (3)抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。 (4)抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类 (5)一个抽象类,可以没有抽象方法。 (6)抽象类和非抽象类的区别和联系 区别: a.抽象类中可以包含抽象方法,非抽象类不可以。 b.抽象类不可以实例化,非抽象类可以。 联系: 从类的定义角度看,抽象类 = 非抽象类+抽象方法 - 实例化。 (7)抽象类主要作用:用来被继承,在子类中重写抽象方法。 (8)抽象类的构造器在子类实例化时会被调用,创建子类对象对应的父类对象。
abstract不能和以下关键字一块使用 private 冲突 final 冲突 static 冲突
八.接口和多态
1.接口概述
(1)接口就是一种公共的规范标准;是Java语言中一种引用类型 (2)作用:实现多继承/多实现 (3)接口的定义: [修饰符] interface 接口名{ //常量-默认修饰符 publi static final int a=1; //抽象方法 默认修饰符 public abstract void test(); (4)无构造方法 因为接口主要是扩展功能的,而没有具体存在 (5)接口是用来被类实现的: [修饰符] class 类名 implements 接口1,接口2,.......接口n{ } 说明: a.一个类可以实现多个接口,简称多实现。 b.一个类实现多个接口,必须实现所有抽象方法,否则该类必须是抽象类。 (6)一个子类可以同时继承父类和实现接口 [修饰符] class 类名 [extends 父类名] [implements 接口1,接口2,.......接口n]{ } (7)多继承:一个接口可以继承多个父接口 [修饰符] interface 子接口名 extends 父接口1,接口2,.......接口n{ } (8)接口声明变量 Shape s=new Circle(); 表示该变量只能存储该接口的实现类的对象。它体现了面向对象的多态性(后面会讲到)。 (9)接口静态方法的定义和使用 静态方法:使用 static 修饰,供接口直接调用。 静态与.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用 (10) a.默认方法定义格式 public default 返回值类型 方法的名称(参数列表){ 方法体 } b. //默认接口 被子类直接调用,也可以重写(便于后期扩展) public default void eat(){ System.out.println("我要吃饭"); }
2.注意事项
(1).- 接口中,有多个抽象方法时,实现类必须重写所有抽象方法。 如果抽象方法有重名的,只需要重写一次即可!? 如果实现类继承了父类,这个父类是一个抽象类时,我们还需要再重写抽象类中的所有抽象方法。 (2).接口多继承之后,如果想使用,我们还必须定义实现类,才能使用 (3)在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。 (4)一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。
3.抽象类和接口的区别
A:成员区别 抽象类: 成员变量:可以变量,也可以常量 构造方法:有 抽象类不能实现化 成员方法:可以抽象,也可以非抽象 接口: 成员变量:只可以静态常量 可以省略 public static final 构造方法:无 接口不能实例化 成员方法:可以抽象 可以省略public abstract 有默认方法 静态方法 B:关系区别 类与类 继承,单继承, 多层继承 类与接口 实现,单实现,多实现 接口与接口 继承,单继承,多继承