第一章:HelloWorld
1.java语言介绍
public class MainTest {
public static void main(String[] args) {
//软件分为系统软件和应用软件
//人机交互方式: 图形化界面 命令行方式
/*
常用的DOS命令:
1.切换盘符:
盘符 :
2.创建文件夹
md 文件名
3.查看目录
dir
4.进入文件夹
cd 文件夹名
5.删除文件
rd 文件名
语言=语法+逻辑
第一代:计算机语言
第二代:汇编语言
第三代:高级语言
java语言概述:
java
javase java标准版
javaee java企业版
javame java小型版本
什么是jdk:
是java程序开发工具包 包含jre和开发人员使用的工具
jre是java运行时 的环境 包含jvm和运行时 所需的核心类库
运行环境就是 jvm
jdk=jre+开发工具集
jre=jvm+Java 标准类库
jdk版本的选择:
jdk版本的选择:通过企业的使用数量来确定
Spring框架来决定:使用jdk17版本来适用spring框架版本
jdk下载和安装
java官网下载jdk18
安装 安装的过程路径不要出现中文
配置path环境变量:
右键此电脑 属性 高级系统设置 环境变量 把路径赋值粘贴到变量值里面即可
建议使用java_home的方式去配置 变量名和变量值 名值对结构的方式去配置
在java进阶部分需要使用到java_home的内容
jdk17的安装
*/
//1.书写一个HelloWorld程序
//类 +类名{}
System.out.println("Hello World!");
//乱码问题 出现乱码问题 把保存类型改为ASCII
/*
1.java程序编写:
步骤1:编写 将java代码编写在.java结尾的源文件中
步骤2:编译 针对于.java结尾的源文件进行编译 格式 javac 源文件名.java
步骤3:运行 针对于编译后生成的字节码文件 进行解释运行 格式 java 字节码文件名
2.针对于编写过程说明:
class HelloWorld{
public static void main(String[] args){
System.out.println("Hello World");
}
}
其中class是关键字 表示类 后缀跟着类名称
main()方法的格式是固定的 public static void main(String[] args){}
java程序严格区分大小写
main方法是程序的入口 如果非要有变化 只能变化String[] args结构 可以写成 String args[]
args全称为 argument 简写为args
从控制台输出数据的操作:
System.out.pringtln("Hello World");
每一条语句必须以分号结束
System.out.print(); 区别就是换行和不换行的问题
3.编译:
如果编译不通过 可以考虑的问题:
1.查看编译的文件名 文件路径是否错误
2.查看代码中是否存在语法问题
编译以后会生成一个或多个字节码文件 每一个字节码文件对应一个java类
针对于运行的说明:
我们是针对于字节码文件对应的java类进行解析运行的 要注意区分大小写
可能存在运行时 异常 在第九章中去解决
一个源文件中可以声明多个类 但是最多只能有一个类实用public进行声明 且要求声明为public的类名与源文件名相同
注释和单行注释:
// 单行注释
文档注释(java特有)
针对于单行注释和多行注释 其作用就是起到解释说明的作用
对程序进行调试
注意:
单行注释和多汗注释中的信息不参与编译
注释不能嵌套注释 不能嵌套使用
文档注释:
文档注释内容可以被jdk提供的工具 javadoc所解析 生成一套网页文件形式的体现该程序的说明文档
javaapi文档:
jdk的说明书 帮助文档 类似于字典
java核心机制:
java优点:跨平台性
面向对象性
安全性
简单性
高性能
功能说明:
jvm 是一个虚拟的计算机 是java程序的运行环境 jvm具有指令集并使用不同的存储区域
自动的内存管理 内存分配 内存回收
*/
/*
@author math
@version 1.2.2
*/
System.out.println(1+3);
System.out.println(1/0);
System.out.println("姓名:吴邪");
System.out.println("地址:吴山居");
System.out.println("职业:盗墓");
/*
复习:
java基础学习:
第一阶段 java基本语法
java概述 关键字 标识符 变量 运算符 流程控制 条件控制 选择结构 循环结构 数组
第二阶段:java面向对象
类及类的内部成员
面向对象三大特征
其他关键字的使用
第三阶段:java高级应用
异常处理 多线程 io六 集合框架 放射 网络编程 新特性 其他api
软件开发相关内容:
硬件+软件
软件 即一系列特点序列组织的计算机数据和指令的集合 有系统软件和应用软件之分
系统软件:即操作系统 window Linux Android
应用软件:即os之上的应用程序
人机交互方式:图形化界面(GUI)
命令行交互方式: dir 传递 cd.. cd/ cd\ md rd等
计算机编程语言
语言的分代:
第一代:机器语言
第二代:汇编语言
第三代:高级语言
面向对象的语言 c++ java python go JavaScript
面向过程的语言
java的一个发展史:
jdk1.0
环境的搭建:
jdk jre jvm
环境变量的配置 尽量配置java_home
hello world的编写:
class Tets{
public static void main(String[] args ){
System.out.println("你好");
}
}
面试题:
1.一个.java源文件是否可以包括多个类 ?有什么限制?
--是的
限制是有且仅有一个类实用public进行声明
且要求声明为public的类的类名与源文件名相同
2.java的优势:
跨平台性
安全性
简单性
高性能
面向对象性
健壮性
java的社区体系比较繁荣
3.java中是否存在内存溢出 内存泄漏 如何解决 ?举例说明
存在
内存泄漏
4.如何看待java是一门半编译半解释语言:
*/
}
}
第二章:变量与运算符
1.标识符
class A{
public static void main(String[] args){
/*
java关键字:
被java语言赋予了特殊的含义 用做专门用途的字符串(或单词)
例如: class public void null true等
标识符:
--测试标识符的使用:
什么是标识符:
比如类名 方法名 变量名 包名 常量名
标识符的命名规则:
--由26个英文字母组成 0-9 —— $组成
数字不可以开头
不可以使用关键字和保留字 但能包含关键字 和保留字
java中严格区分大小写 长度无限制
标识符不能包含空格
3.规范:
标识符的命名规范:
包名 多个单词组成时 所有字母都小写
类名 接口名 :多单词组成时 所有的单词的首字母大写
变量名 方法名:多单词组成时 第一个单词首字母小写 第二个单词开始就大写
常量名:驼峰命名法
*/
System.out.println("计算机科学与技术学院");
int age=90;
String name="吴邪";
System.out.println("姓名:"+name+"年龄:"+age);
/*for(int i=0;i<100;i++){
System.out.println("你好 计算机科学与技术学院");
}*/
B b=new B();
b.test();
}
}
class B{
void test(){
System.out.println("你好 我是类B中的方法! 计算机科学与技术学院");
}
}
2.变量
class A{
public static void main(String[] args ){
/*
变量:
变量是程序中不可缺少的组成单位 最基本的存储单元
内存中的一个存储单位 该区域的数据可以在同一个类型分为中不断变化
变量的构成 包含三个要素:数据类型 变量名 存储的值
java中变量的声明的个数:数据类型 变量名=变量值
int age=19;
变量的作用:用于在内存中保存数据
使用变量注意:
java中的变量按照实际类型来分类:
基本数据类型(8种):
整型:byte short int long
浮点型:float double
字符型:char
布尔型:boolean
引用类型:
类(class)
数组(array)
接口(interface)
枚举(enim)
注解(annotation)
记录(record)
定义变量时 变量名要遵循标识符命名的规范和规则
说明:
变量都有其作用域 变量在作用域里面是有效的 出了作用域就失效了
在同一个作用域内 不能声明两个同名的变量
变量在赋值时 必须满足变量的数据类型 并且在数据类型有效的范围内变化
*/
int age=90;//这个就是变量的初始化
char gender='男';//变量的声明
//综合来看 变量的初始化和声明可以合并起来
//因此可以使用以下方法:
int boy=1289;//这个就是同时声明和初始化变量
System.out.println("年龄为:"+age);
B b=new B();
b.test();
//num=10;//这个由于在声明类型 即当前num变量没有提前定义 所以编译不通过
}
}
class B{
void test(){
System.out.println("我是 test方法");
int a=0;
int b=0;
System.out.println(a+b);
}
}
3.整型数据类型的使用
class A{
public static void main(String[] args ){
/*
整型数据类型的使用:
整型和浮点类型的使用:
byte(1字节=8bit) short(2字节) int(4字节) long(8字节)
*/
byte b1=12;
byte b2=127;
//byte b3=128;//编译不通过 超过了byte的存储范围
System.out.println("你好 计算机科学与技术");
short s1=122393;
int i=123393;
//1.声明long类型变量 时 需要提供后缀 后缀为小写l
long n=122338L;
//在开发中 定义整型变量 没有特殊情况 通常定义为int类型0、
}
}
4.浮点类型使用
class A{
public static void main(String[] args){
/*
foloat/double
*/
double i=12.3;
//声明long类型变量时 需要提供后缀 后缀为‘f’ 或‘F’
float j=212.2f;
System.out.println(i+j);
//在开发中 大家定义浮点型变量时 没有特殊情况的话 通常都声明double类型 因为精度更高
//float类型表示数的范围要大于long类型的表示范围 当时精度不高
//浮点数的精度不高 如果在开发中需要使用精度较高的精度 需要使用BigDecimal类替换浮点型变量
}
}
class A{
public static void main(String[] args)
{
//案例一:
//定义圆周率并赋值为3.14 现在有3个圆的半径为1.2 2.5 7 则他们的面积
//定义圆周率变量:
double pi=3.14;
//定义三个圆的半径
double radius1=1.2;
double radius2=2.5;
double radius3=7;
//计算面积:
double area1=pi*radius1*radius1;
double area2=pi*radius2*radius2;
double area3=pi*radius3*radius3;
System.out.println("圆面积1为:"+area1+"圆面积2为:"+area2+"圆面积3为:"+area3);
//案例二:将华式温度转换为摄氏度 c=(F-32)/1.8
double F=80.0;
double c=(F-32)/1.8;
System.out.println("华温度:"+c);
}
}
5.字符类型的使用
class A{
public static void main(String[] args){
//测试字符类型和布尔类型的使用
//1.字符类型 char(2字节)
//表示形式1:
//使用一对''表示 内部有且只能有一个字符串
char c1='a';
char c2='中';
System.out.println(c1+c2);
//表示形式2:直接使用Unicode值表示字符型字符型常量 '\uXXXX'
char c8='\u0036';
System.out.println("+"+c8);
//表示形式3:使用转义字符
char c9='\n';
char c10='\t';
System.out.println(c9+c10);
//表现形式4:使用具体的字符对应的数值(比如ASCII码)
char a=1;
}
}
6.布尔类型的使用
class A{
public static void main(String[] args){
/*
布尔值类型 Boolean
只有两个值 true false
*/
boolean b1=true;
boolean b2=false;
//1.常使用在流程控制语句中 比如 条件判断 循环结构
if(b1)
{
System.out.println("计算机");
} else{
System.out.println("你好");
}
//我们不谈Boolean类型占用空间的大小 但是在内存中分配的话 使用的是4个字节
}
}
7.基本数据类型变量间的自动类型提升规则
class A{
public static void main(String[] args){
/*
基本数据类型变量的运算规则
1.这里提到可以做运算的基本数据类型有7种 不包含Boolean类型
2.运算规则:
自动类型提升
强制类型转换
3.规则:
当容量小的变量与容量大的变量做运算时 结果自动转换为容量大的数据类型
说明:
此时的容量小或大 并非指内存空间的大小 而是指表示数据的大小
long(8字节) float(4字节)
byte-->short--->int--->long-->float1-->double
特殊情况:
byte,short--->int--->long-->float1-->double
*/
int i1=10;
long i2=i1;
byte b1=12;
int i3=b1;
//特殊的情况下:
byte b3=12;
short s1=10;
short s2=b3+s1;//这个编译不通过 最小要使用int来接收
//特别的:byte short类型的变量之间做运算 结果为int类型
//特殊情况2:char
char c1='a';
char c2=c1+b3;//这个也是编译不通过 最小用int
}
}
8.基本数据类型转换规则
class A{
public static void main(String[] args){
/*
强制类型转换:
规则:将取值范围小(或容量小)的类型自动提升为取值范围大(或容量大)的类型
1.强制类型转换需要使用强转符 () 在()内指明要转换为的数据类型
2.强制类型转换过程中可能导致精度损失
*/
double d1=19;
int i1=(int)d1;
long i2=120;
short s2=(short)i2;
System.out.println(s2);
double n=28829.21212;
int y=(int)n;
System.out.println(y);//这个就是导致了精度损失
}
}
9.String类的基本使用
class StringTest{
public static void main(String[] args){
/*
1.String类 属于引用类型 俗称字符串
2.String类型的变量 可以使用一对""方式进行赋值
3.String声明的字符串可以包含0个多个字符
String与基本数据类型的运算
包括布尔在内的有8种
String与基本数据类型运算只能做连接运算 使用+来表示
运算的结果是String类型
*/
String str1="hello World";
String str2="hello World";
System.out.println(str1==str2);//true
String str=str1+str2;//做连接运算
System.out.println(str);
//引用数据类型不不能转换为基本数据类型
//需要实现的话 可以使用Integer
int num3=Integer.parseInt(str);
System.out.println(num3+1);
}
}
10.String课后练习
class StringExer{
public static void main(String[] args){
String name="吴邪";
int age=24;
String gender="男";
double weight=120.89;
boolean isMarried=false;
String phonNumber="121212";
System.out.println("姓名\t"+name+"\t性别\t"+gender+"\t体重\t"+weight+"\t单身?\t"+isMarried+"\t电话号码\t"+phonNumber);
}
}
11.常见的进制及换算
class BinaryTest{
public static void main(String[] args){
/*
1.二进制;
*/
int num1=103;//十进制
int num2=0b011;//二进制
int num3=023;//八进制
int num4=0x2a;//十六进制
System.out.println(num1);
System.out.println(num2);
System.out.println(num3);
}
}
12.算数运算符
class Arithmetic{
public static void main(String[] args){
/*
1. + - * /
2.
*/
int m1=12;
int n1=5;
int a=m1/n1;
System.out.println(a);//因为变量是整型 所以强制转换 等于2
System.out.println(a*10);
//取模运算:%
int i=18;
int j=5;
System.out.println(i%j);//取余数 在开发中 经常用来判断是否能整除 一个数
//前++ 表示自增1
//先加加 先自增一 在赋值
int a1=10;
int b1=++a1;
System.out.println("\ta1\t"+a1+"\tb1\t"+b1);
//后++ 表示自增1
//先赋值 后自增一
int a2=100;
int b2=a2++;
System.out.println("\ta2\t"+a2+"\tb2\t"+b2);
//前-- 先自减一 在运算
//后-- 先运算 在自减一
System.out.println("********************************");
//提取一个三位数的个位 十位 百位
int num=153;
int ge=num%10;//个位
int shi=num/10/10;//十位
int bai=num/100;
System.out.println("\t个位\t"+ge+"\t百位\t"+bai+"\t十位\t"+shi);
}
}
13.赋值运算符
class SetValue{
public static void main(String[] args){
/*
/*赋值运算符:
1.= -= += /= %=
2.当两侧数据类型不一致 可以使用自动类型转换或使用强制类型转换原则进行处理
3.支持连续赋值
*/
int i=7;
long l=10;//自动类型提升
//1. +=
int m1=10;
m1+=5;//m1=m1+5
System.out.println(m1);
//这些操作不会改变变量本身的类型
byte by1=10;
by1+=5;//编译=编译+5操作会报错
System.out.println(by1);
int m2=1;
m2*=0.1;//m2=m2*0.2
System.out.println(m2);
}
}
14.比较运算符
class Compare{
public static void main(String[] args){
/*
1.== != < > >= <= 适用于除Boolean类型之外的其他7种基本数据类型
instanceof 在面向对象多态性
运算的结果为布尔型
补充:== != 适用于引用数据类型
2.区分 ==与= 一个是等于号 一个是赋值号
*/
int m1=10;
int m2=20;
System.out.println(m1 );
System.out.println(m2);
m1=m2;
boolean i= m1>m2;
System.out.println(i);
System.out.println(m1);
System.out.println(m2);
}
}
15.位运算符
class BigTest{
/*
位运算符:
*/
public static void main(String[] args){
//1.<< >> & |^ `
// 1针对数值类型的变量或常量进行运算 运算的结果也是数值
// 2.每向左移动因为 结构就是在原有的基础上*2(对于正数和负数都适用)
//对于右移运算:
//在一定范围内 每向右移动一位 结构就在原有的基础上/2 (对于正数负数都适用)
int num=7;
System.out.println("左移2位"+(num<<2));
System.out.println("右移2位"+(num>>2));
int num2=-7;
System.out.println("负数左移动1位"+(num2<<1));
System.out.println("负数右移动2位"+(num2>>2));
//无符号右移 >>>
//逻辑&
System.out.println(0&1);
//按位取反 0-1 1-0
System.out.println(~1101);
}
}
16.条件运算符
class ConditionTest{
public static void main(String[] args){
/*
条件运算符
-1.(条件表达式)?表达式1:表达式2
2.说明条件表达式结果是布尔
条件表达式结果为true 执行表达式1 否则表达式2
表达式1和表达式2需要的是相同的类型或兼容的类型
*/
String info= (2>1)?"你好":"你不好";//返回的结果类型取决于表达式的类型
System.out.println(info);
//获取两个整数的较大值
int m=20;
int n=10;
int max= (m>n)?m:n;
System.out.println("最大值是:"+max);
//获取三个数的最大值
int i=20;
int j=30;
int k=40;
//先找到两个数中最大值
int tempMax=(i>j)?i:j;
int finalMax= (tempMax>k)?tempMax:k;
System.out.println("最终最大值为:"+finalMax);
//字符集:
}
}
17.第二章:复习
/*
关键字,保留字
关键字:被java赋予特殊含义的字符串
官方规范有50个关键字
true false null虽然表示关键字 但是可以当做关键字来看待
保留字 goto const
标识符:
反是直接可以命名的地方都是标识符
比如类名 变量名 方法名 包名 常量名
记住 标识符命名的规则必须要遵守 否则编译不通过
记住:标识符的命名规范
见名知意
1.变量基本使用
三个要素 数据类型 变量名= 变量值
2.基本数据类型变量的使用
基本数据类型 整型 浮点型 字符型 布尔型
3.基本数据类型变量间的运算规则
4.基本类型提升
5.强制类型转换
6.String类的使用 与基本数据类型变量间的运算
7.关于进制间的认识
正数:原码 反码 补码三码相同
负数:原码 反码 补码不相同
8.运算符 算数运算符 赋值运算符 比较运算符 逻辑运算符 位运算符 条件运算符
面试题:
1.高效的计算2*8
使用位运算<<
2.&和&&区别
3.java中的基本数据类型 String是最基本的数据类型吗?
8种基本数据类型 String表示基本数据类型 是引用类型
4.java开发中计算金额使用什么数据类型
不能使用float或double 因为精度不够
使用BigDecimal替换 可以实现任意精度的数据运算
5.char类型变量中能不能存储一个文字 为什么
可以存储一个汉字 因为char使用Unicode字符集 包含了世界范围的所有的字符
6.代码分析:
short s1=1;
s1=s1+1 因为等号的右边是int类型 需要强转
short s1=1;
s+=1;//这个没有错
7.布尔占几个字节:
我们不谈几个字节 但是jvm在给布尔类型分配空间 布尔类型的变量占据四个字节
*/
第三章:流程控制语句
1.else-if语句
class ifElseTest{
/*
1分支结构:if-else条件判断语句
语法:
if(条件表达式){
代码块1;
}else{
代码块2;
}
if(条件表达式1){
}
else if(条件表达式2){代码块}
else if(条件表达式3){代码块}
else if(条件表达式4){代码块}
else{代码块}
*/
public static void main(String[] args){
int hearBeats=89;
if(hearBeats>=60&&hearBeats<100){
System.out.println("你需要检查!");
}else{
System.out.println("你不需要检查!");
}
//定义一个整数 判断是偶数还是奇数
int num=13;
if(num%2==0){
System.out.println("是偶数");
}else{
System.out.println("不是偶数");
}
//成绩100分 奖励车
//成绩90-99 奖励自行车
//成绩60-80 奖励旅游
int score=62;
if(score>60&&score<80){
System.out.println("旅游");
}else if(score>90&&score<99){
System.out.println("奖励自行车");
}else if(score==100){
System.out.println("奖励跑车");
}else{
System.out.println("继续努力!");
}
/*
多个表达式之间没有交集 则那个表达式那个在上面,那个在声明
下面都可以
如果多个表达式之间是包含关系 则需要将范围小的表达式声明在分为大的表达式上面
否则范围小的条件表达式不会被执行
*/
}
}
2.if-else嵌套使用
class ifElse{
public static void main(String[] args){
/*
从键盘输入三个整数 num1 num2 num3 对他们进行排序 并从小到大输出
*/
int num1=2,num2=2,num3=7;
int temp;
if(num1>num2){
if(num3>=num1){
System.out.println(num2+"**"+"**"+num1+"**"+num3);
}else if(num3<num2){
System.out.println(num3+"**"+""+num3+"***"+num1);
}else{
System.out.println(num1+"***"+num3+"***"+num2);
}
}else{
if(num3>=num2){
System.out.println(num1+""+num2+""+num3);
}else if(num3<num2){
System.out.println(num3+""+num1+""+num2);
}else{
System.out.println(num1+""+num3+""+num2);
}
}
}
}
3.输入类Scanner的使用
import java.util.Scanner;
class ScannerTest{
/*使用Scanner获取不同数据类型的步骤*/
public static void main(String[] args){
//1.使用Scanner获取不同数据类型的步骤
/* --导包 import java.util.Scanner
--提供或创建一个scanner;类的实例
--调用scanner类中的方法 获取指定类型的变量
--关闭资源
*/
//输入数字 来判断是否成年 壮年 老年
Scanner i=new Scanner(System.in);//创建类的实例
System.out.println("请输入!");
int age= i.nextInt();//调用类里面的方法
/*
输入方法 nextXXX();
*/
if(age<18){
System.out.println("你还未成年!");
System.out.println("你的年龄"+age);
}
System.out.println("请输入体重!");
double height=i.nextDouble();
if(height>90){
System.out.println("你要减肥了!");
}
/*
Scanner类中提供了获取 byte short int longfloat double Boolean String
注意:没有提供获取char的方法 如果需要的话 就是使用next().charAt(0);
*/
//关闭资源
i.close();
}
}
4.随机数
/*
如何获取一个随机数
*/
class RandomTest{
public static void main(String[] args){
//1.可以使用java提供java提供的api方法 Math类的Random方法
//random()调用以后会返回一个0.0到1.0范围的随机数
double di=Math.random();
System.out.println(di);
//获取一个0到100的随机数
System.out.println("0到100内的随机数:"+(int)(di*100));
//获取[a,b]之间的随机数 (int) (Math.random())*(b-a+1)*a
}
}
5.switch-case的基本使用
class SwitchTest{
public static void main(String[] args){
/*
选择结构的使用:
1.语法格式
switch(表达式){
case 常量1:
//执行语句1;
break;
case 常量2:
//执行语句2;
break;
case 常量3:
//执行语句3;
break;
....
case 常量n:
//执行语句n
break;
default:
//语句
}
执行过程:
根据表达式中的值依次匹配case语句 一旦与某个case中的常量相等
就执行此case中的语句 执行完成之后
情况一:
遇到break 则执行break后 跳出当前的switch结构
情况二:没有遇到break 则继续执行其后的case语句
.....直到遇到break 或者执行完成所有的case及default中的语句 退出当前的switch-case语句
3.
*/
int num1=1;
switch(num1){
case 1:
System.out.println("你好啊");
break;
case 2:
System.out.println("你不好!");
break;
case 3:
System.out.println("计算机科学与技术");
default:
System.out.println("计算机软件工程");
}
}
}
6.for循环语句
class ForTest{
public static void main(String[] args){
/*
1.java中规范了三种循环结构: for while do-while
2.凡是循环结构一定湖有四要素:
1.初始化条件
2.循环条件--->重要 一定是要布尔类型的变量或者表达式
3.循环体
4.迭代条件
3.for循环的格式
for(初始化条件部分;循环条件;迭代条件){
循环体;
}
执行过程 初始化条件 循环条件 循环体 迭代条件 --初始化条件 循环条件 循环体 迭代条件 以此类推继续走
直到不满足循环条件
*/
//案例:输出100行的HeLloWorld
for(int i=0;i<100;i++){
System.out.println("HelloWorld!");
}
System.out.println("********************");
for(int j=0;j<100;j=j+1){
System.out.println("HelloWorld!");
}
System.out.println("******************");
/* int num=1;
for(System.out.println("a");num<3;System.out.println("c");num++){
System.out.println("b");//输出结果为abcbc
}*/
//需求3:遍历0-100以内的偶数 获取偶数的个数
int count=0;//记录偶数的个数
int sum=0;
for(int i=0;i<=100;i++){
if(i%2==0){
System.out.println("偶数为:"+i);
count++;
}
sum+=i;//sum=sum+i 统计偶数的和
}
//输出偶数的个数
System.out.println("偶数个数为:"+count);
System.out.println("偶数的和为:"+sum);
}
}
/*
循环语句:
for
while
do-while
*/
7.for循环练习
class ForTest2{
public static void main(String[] args){
/*
输出所有的水仙花数 所谓水仙花数是指三位数 其各位上数字的立方和等于其本身
*/
//先遍历三位数
for(int i=100;i<999;i++){
//针对于每一个三位数 获取其个位上数值
int num1=i%10;
int num2=i/10%10;//取出10位
int num3=i/100;
//判断是否满足水仙花数的规则
if(i==num1*num1*num1+num2*num2*num2+num3*num3*num3){
System.out.println("水仙花数为:"+i);
}
}
}
}
8.练习2:
class ForTest3{
public static void main(String[] args){
/*
输入两个正整数 m和n 求最大公约数和最小公倍数
*/
int m=12;
int n=20;
for(int i=1;i<12;i++){
//最大约数
if(m%i==0&&n%i==0){
System.out.println(i);
}
// System.out.println(i);
}
}
}
9.while循环的使用及练习
class WhileTest{
public static void main(String[] args){
/*
while 循环:
初始化条件
循环条件
循环体
迭代部分
while(循环条件)的格式:
{
循环体
迭代部分;
}
*/
//打印100遍HelloWorld
int i=0;
while( i<100){
System.out.println("HelloWorld");
i++;//这个一定要书写 不然就是死循环
}
}
}
import java.util.Scanner;
class WhileTest{
public static void main(String[] args){
/*
随机生成一个随机数 猜这个随机数多少
从键盘输入数 提示大了 如果小了 就提示小了 如果对了 就不要在猜了
并统计一共猜了多少次
提示:生成一个[a,b] 范围的随机数的方式 (int)(Math.random)*(b-a+1)+a)
*/
//1.生成一个1-100内的随机整数
int target=(int)(Math.random()*100)+1;
//2.使用Scanner 从键盘输入数
Scanner sc=new Scanner(System.in);
//3.使用循环结构 进行多次循环的对比和获取数据
System.out.println("请输入0-100内的数!");
int guss=sc.nextInt();
int guessCount=0;
while(target!=guss){
if(guss>target){
System.out.println("你输入的数据大了!");
}else if(guss<target){
System.out.println("你输入的数据小了!");
}
System.out.println("请输入0-100内的数!");
guss=sc.nextInt();
guessCount++;
}
//能结束循环 就意味着random和guess相等了
System.out.println("猜对了");
System.out.println("你共猜了"+guessCount+"次");
//关闭资源
sc.close();
}
}
class WhileTest2{
public static void main(String[] args){
/*
世界最高的山是珠穆朗玛峰 它的高度是8848米 假如我有一张足够大的纸
它的厚度是0.1毫米 请问 我折叠多少次 它可以折成珠穆朗玛峰的高度
*/
//1.声明珠穆朗玛峰的高度 纸的默认厚度
double paper=0.1;//单位毫米
double height=8848860;//单位毫米
int count=0;
//2.通过循环结构 不断调整纸的厚度 当纸的高度超过珠穆朗玛峰高度时停止循环
while(paper<=height){
paper*=2;
count++;
}
//3.定义变量来记录折纸的次数
System.out.println("纸的高度为:"+(paper/1000)+"超过了珠穆朗玛峰的盖度");
//4.删除折了多少次:
System.out.println("折了多少次:"+count);
}
}
10.do…while循环
class DoWhileTest{
public static void main(String[] args){
/*
do...while()循环:
格式:
do{
循环体;
}while(循环条件);
执行过程:
先判断后执行 初始化条件 循环体 迭代部分...
说明:
do..while()循环 至少执行一次循环体
*/
//遍历100以内的偶数 并且输出偶数的个数和总和
int i=1;
int sum=0;
int count=0;
do{
if(i%2==0){
System.out.println("偶数是:"+i);
sum+=i;//偶数和
}
i++;
count++;
}while(i<=100);
System.out.println("偶数和为:"+sum);
System.out.println("次数为:"+count);
}
}
import java.util.Scanner;
class doWhileTest{
public static void main(String[] args){
/*
do..while()循环在开发中使用的比较少
声明变量balance 并且初始化为0 用来表示银行账户余额 下面通过atm取款机来实现
===ATM===
1.存款
2.取款
3.显示余额
4、退出
请 选择 1-4
*/
//3.使用Scanner获取用户的选择
Scanner sc=new Scanner(System.in);
//1.定义变量
double balance=0;
boolean flag=true;//控制循环的结束
do{ //2.声明atm收款的界面
//就是四条输出语句
System.out.println("=======ATM取款机=======");
System.out.println("1.存款");
System.out.println("2.取款");
System.out.println("3.显示余额");
System.out.println("4 退出");
System.out.println("=======================");
//4.根据用户的选择 决定执行存款 取款 显示余额 退出等操作
int slection=sc.nextInt();
switch(slection){
case 1:
System.out.println("请输入存款金额!");
double money1= sc.nextDouble();
if(money1>0){
balance+=money1;
}
System.out.println("存钱成功!");
break;
case 2:
System.out.println("请输入取款金额!");
double money2=sc.nextDouble();
if(money2>0&&money2<=balance){
balance-=money2;
}
else{
System.out.println("输入的余额有误 或不足 请重新输入!");
}
System.out.println("存钱失败!");
break;
case 3:
System.out.println("账户余额为:"+balance);
break;
case 4:
flag=false;
System.out.println("正在退出!欢迎使用~~");
break;
default:
System.out.println("输入有误!");
}
}while(flag);
//关闭资源
sc.close();
}
}
11.死循环使用
import java.util.Scanner;
class dieTest{
public static void main(String[] args){
/*
无限循环结构的使用:
1.格式 while(true){代码块..}
for(;;){代码块...}
*/
/*while(true){
System.out.println("你好 计算机科学与技术!");
}
for(;;){
System.out.println("你好!");
}
}
*/
//案例:从键盘输入个数不确定的整数 并判断读入的正数和负数的个数 输入为0结束
Scanner sc=new Scanner(System.in);
int postCount=0;//记录正数的个数
int negatCount=0;//记录负数的个数
while(true){
System.out.println("请输入一个整数");
int num=sc.nextInt();//获取用户输入的整数
if(num>0){
//整数
postCount++;
}else if(num<0){
negatCount--;
}else{
System.out.println("程序结束!");
break;
}
}
System.out.println("正数的个数为:"+postCount);
//sc.colse();//关闭资源
}}
12.循环嵌套的使用
class ForForTEst{
public static void main(String[] args){
/*
嵌套循环的使用:
1.嵌套循环 是指一个循环结构A的循环体内是另一个循环结构B
--外层循环 :循环结构A
--内层循环:循环结构B
内层循环充当了外层循环的循环体
对于两层循环来说 外层循环控制行数 内层循环控制列数
举例:外层循环执行m次 内层循环执行循环体执行m*n次
实际开发中 我们不会出现三层以上的嵌套循环
*/
for(int i=0;i<100;i++){
for(int j=0;j<i*j-1;j++){
System.out.println("**");
}
System.out.println();
}
}
}
class ForForTest{
public static void main(String[] args){
/*
使用循环嵌套打印一个菱形
*/
for(int i=1;i<=5;i++){
for(int j=1;j<=10-2*i;j++){
System.out.println("-");
}
for(int k=1;k<=2*i-1;k++){
System.out.println("* ");
}
System.out.println("");
}
}
}
class ForForTest{
public static void main(String[] args){
/*
使用循环嵌套打印一个菱形
*/
/*for(int i=1;i<=5;i++){
for(int j=1;j<=10-2*i;j++){
System.out.println("-");
}
for(int k=1;k<=2*i-1;k++){
System.out.println("* ");
}
System.out.println("");
}
*/
for(int i=1;i<=9;i++){
for(int j=0;j<=i;j++){
System.out.print(i+"*"+j+"="+i*j+"\t");
}
System.out.println();
}
}
}
13.关键字break和continue的使用
class BreakContiuneTest{
public static void main(String[] arg){
/*
break和continue关键字的使用:
break: 在循环结构中是结束当前循环结构 在此关键字的后面不能书写输出语句
switch-case
循环结构
continue: 结束当次循环
循环结构中
*/
for(int i=1;i<10;i++){
if(i%4==0){
continue;
}
else{
break;//直接结束循环
}
//System.out.println(i);
}
leable:for(int j=0;j<10;j++){
if(j%4==0){
System.out.println("第一个数是"+j);
break leable;//这个就是显式的结束for循环 用于循环层数过多选择结束
}else{
System.out.println("其他数"+j);
}
}
}
}
14.经典案例
class PrimeNumber{
/*
题目:找出100以内所有的质数 (素数) 10000以内?
*/
public static void main(String[] args){
//质数:只能被0和1本身整除的自然数
for(int i=2;i<=100;i++){
int number=0;
//判定i是否是质数
for(int j=2;j<i;j++)
{
//遍历100以内的自然数
if(i%j==0){
number++;
System.out.println(i);
}
if(number==0){
System.out.println(i);
}
}
}
}
}
class PrimeNUmber{
public static void main(String[] args){
/*
遍历10000以内的质数 体验性能的差距
*/
//获取代码执行的时间
long satrt= System.currentTimeMillis();
boolean isFlag=true;
int count=0;
for(int i=2;i<100000;i++){
for(int j=2;i<i;j++){
if(i%j==0){
isFlag=false;
}
}
if(isFlag){
//System.out.println(i);
count++;
}
//重置isFlag
isFlag=true;
}
//获取系统当前时间
long end= System.currentTimeMillis();
System.out.println("花费的时间为:"+(end-satrt));
// System.out.println("质数的个数为:"+count);
}
}
第四章:数组
1.IDEA开发工具的使用
1.下载 安装 激活 破解
开发工具:
project(工程) ---> module(模块)----> package(包)--->class(类)
一个project可以创建多个module
一个module可以创建多个package
一个pack阿哥可以创建多个class
project和module的概念
:在idea中project是最高级结构单元 然后就是module 目前 主流的大型项目结构基本都是多module的结构
这类项目一般是按照功能划分的
module与package
删除模块:
2.数组定义
数组(Array)是多个相同类型数据按照一定顺序排列的集合 并使用一个名字命名 并通过编号的方式对这些数据进行统一的管理
数组中的概念:
数组名
下标
元素
数组的长度
数组的特点:
数组本身的特点
package demo01;
/**
* className:ArrayTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/9 20:57
* @Version 1.0
**/
public class ArrayTest {
/*
* 数组:多个数据的组合
*
* java中容器:数组 集合 框架 在内存中对多个数据的存储
* 几个相关的概念:
* 数组的名
* 数组的元素 即内部存储的多个元素
* 数组的下标 角标 索引 index(即找到数组所使用的编号)
* 数组的长度 即数组容器中存储的元素的个数
*
* 数组的特点:
* 数组中元素在内存中是依次排序的 有序的
* 数组是引用数据类型的变量 数组中的元素既可以是基本本身具类型 也可以是引用类型
*
* 基本的数据类型:byte short int long float double char boolean
* 引用数据类型:类 数组 接口 枚举 注解 记录
*
* 数组的分类:
* 基本数据类型的数组 引用数据类型元素的数组
*
* 按照数组的维数来分 :一维数组 二维数组 ...
*
* 一维数组的使用:
* 一维数组的声明和初始化:
* 调用数组的指定元素:
* 数组的属性:length 表示数组的长度
* 数组元素的默认初始化值
* 一维数组的内存解析
* */
public static void main(String[] args) {
// 1.数组的声明和初始化
// 变量的定义方式 数据类型 变量名=变量值;
int num1=100;
System.out.println(num1);
// 声明数组
double[] price;
// 数组的初始化b 静态初始化 数组遍历的初始化与数组元素的赋值同时进行
price =new double[]{12,31,123,123};
System.out.println(price[0]);
//
String[] foods;
foods=new String[]{};
// 多态初始化 数组遍历的初始化与数组元素的赋值分开进行
String[] food=new String[10];
//数组一旦初始化完成 其长度就确定 并且其长度不可更改
// 创建数组对象会在内存中开辟一整块连续的空间 占据的空间的大小 取决于数组的长度 取决于数组的长度和数组中元素的类型
// 其他正确的方式:
int arr[]=new int[7];
int[] arr1={1,2,3,4,5};//类型推断
// 错误的方式:int[] arr2=new int[2]{1,2,3}; 这种动静结合的就是错误的
// 数组元素的调用:
// 通过角标的方式去取出元素
System.out.printf("第一个值为", price[0]);
System.out.println(price[1]);
// 对food数组进行赋值
food[0]="吴邪";
food[1]="解雨臣";
food[2]="吴三省";
// 数组的长度用来描述容器中容量1大小 使用length属性表示
System.out.println(food.length);
// 数组的遍历
String[] name;
name =new String[]{"吴邪","张起灵","吴三省"};
for (int i = 0; i < name.length; i++) {
System.out.println(name[i]);
}
// 数组元素的默认初始化值
int[] arr4=new int[3];//初始化了数组 并且指定了数组的长度
// 整型数组元素的默认初始化值 0
System.out.println(arr4[0]);
// 浮点型数组元素的初始化默认值‘ 0.0
float[] arr5=new float[5];
System.out.println(arr5[0]);
// 字符型数组元素的默认初始化值 0
char[] ch=new char[2];
ch[0]='A';
System.out.println(ch[0]);
// 布尔值类型数组元素的默认初始值 false
boolean[] b=new boolean[2];
b[0]=true;
System.out.println(b[0]);
// 引用数据类型 null
String[] s1=new String[2];
for (int i = 0; i < s1.length; i++) {
System.out.println(s1[i]);
}
// 引用数据类型数组元素的默认初始化值
}
}
3.数组类型的内存解析
package demo01;
/**
* className:ArrayJVM
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/9 22:01
* @Version 1.0
**/
public class ArrayJVM {
public static void main(String[] args) {
/*
* 数组类型的内存解析:
* java中的内存是如何划分的 (主要是关心jvm)
* 将内存区域划分为五个区域 程序计数器 虚拟机栈 本地方法栈 堆 方法区
*
* 与目前数组相关的内存结构 比如 int[] arr1=new int[]{12,3,2,1}
* 虚拟机栈 用于存放方法中声明的变量 比如arr1
* 堆 用于存放数组的实体 即数组中的所有元素 比如1,2,3
*
* 栈(stack) 堆(heap)
*
*
* */
}
}
4.数组的练习题
package demo01;
/**
* className:Arrayexer
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/9 22:20
* @Version 1.0
**/
public class Arrayexer {
public static void main(String[] args) {
/*
号码的随机排列:
随机排列的号码:
* * */
int[] arr=new int[]{8,2,1,0,3};
int[] index=new int[]{2,0,3,2,4,0,1,3,2,3,3,1};
String tel="";
for (int i = 0; i < index.length; i++) {
int value=index[i];
tel+=arr[value];
}
System.out.println("联系方式+"+tel);
}
}
package demo01;
import java.util.Scanner;
/**
* className:Arrayexer
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/9 22:20
* @Version 1.0
**/
public class Arrayexer {
public static void main(String[] args) {
/*
号码的随机排列:
随机排列的号码:
* * */
int[] arr=new int[]{8,2,1,0,3};
int[] index=new int[]{2,0,3,2,4,0,1,3,2,3,3,1};
String tel="";
for (int i = 0; i < index.length; i++) {
int value=index[i];
tel+=arr[value];
}
System.out.println("联系方式+"+tel);
/*
* 案例:输出英文星期几
* 用一个数组 保存星期一到星期天的7个英语单词 从键盘1-7 显示对应的单词
* */
String[] week=new String[]{"Monday","Tuesday","Wednesday","Thursday","Thursday","Friday","Saturday","Sunday"};
Scanner scanner = new Scanner(System.in);
while (true){
// 从键盘获取对应的单词
System.out.println("请输入数值[1-7]");
int i = scanner.nextInt();
if (i<1||i>7){
System.out.println("你输入的数据有误");
scanner.close();
}else {
System.out.println(week[i-1]);
}
}
}
}
package demo01;
import java.util.Scanner;
/**
* className:SudentScore
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/9 22:47
* @Version 1.0
**/
public class SudentScore {
public static void main(String[] args) {
/*从键盘输入学生成绩 找出最高分 并输出学生成绩
* 成绩>最高分-10 等级为:’A‘
* 成绩>=最高分 等级为:’B‘
* 成绩>=最高分-30 等级为C
* 其余成绩 为d
* */
// 1.从键盘输入学生的人数 根据人数 创建
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生人数:");
int i = scanner.nextInt();
int[] score=new int[i];
// 2.根据提示 因此输入学生成绩 并且将元素保存到元素中
// 输入
System.out.println("请输入"+i+"个成绩");
for (int j = 0; j < score.length; j++) {
score[j] = scanner.nextInt();
}
// 3.获取学生成绩的最大值
int maxScore=score[0];
for (int j = 0; j < score.length; j++) {
if (maxScore<score[j]){
maxScore=score[j];
}
}
System.out.println("最高分为:"+maxScore);
// 4.遍历数组 根据学生成绩与最高分的差值 得到学生的等级 并输出成绩和等级
for (int j = 0; j < score.length; j++) {
if (score[j]>=maxScore-10){
System.out.println("学生"+i+"成绩"+score[j]);
}else if(score[j]>=maxScore-20){
System.out.println("学生"+i+"成绩"+score[j]);
}
else if (score[j]>maxScore-30){
System.out.println("学生"+i+"成绩"+score[j]);
}
}
}
}
5.二维数组
package demo01;
/**
* className:TowArray
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 17:35
* @Version 1.0
**/
public class TowArray {
public static void main(String[] args) {
/*二维数组:
*
*
*
* */
//1.二维数组的声明和初始化
String[] Array=new String[]{"吴邪","解雨臣","黑瞎子"};
// 二维数组的静态初始化 数组遍历的赋值和数组元素的赋值同时进行
int[][] arr1=new int[][]{{1,2,3},{2,3,4},{6,5,3},{6,8,9}};
// 二维数组动态初始化 数组变量的赋值和数组元素的赋值分开进行
String[][] arr2=new String[3][4];
// 数组的外层元素和数组的内层元素
double[][]arr3=new double[2][];//这样子初始化数组也对
// 其他正确的写法
int arr4[][]=new int[][]{{123},{221},{21,21,23}};
int arr5[][]={{12,32,12},{89,42,21}};//类型推断的写法
int[] arr6={1,23,2,1,3};
for (int i = 0; i < arr6.length ;i++) {
System.out.println(arr6[i]);
}
// 数组元素的调用
// z针对于 arr2来说 外层元素 {1,2,3} {4,5} {6,7,8,9} 内层元素 1,2,3,4,5,6,7,8,9
// 先来调用内层元素
System.out.println(arr5[0][1]);//使用平面直角坐标的形式去调用
//调用外层元素
System.out.println(arr5[0]);//打印出的是地址
// 测试arr2
arr2[0][1]="吴邪";
arr2[0][2]="解雨臣";
System.out.println(arr2[0][1]+arr2[0][2]);
// 数组的长度
//
System.out.println(arr3.length);
// 如何遍历数组
for (int i = 0; i < arr3.length; i++) {
for (int j = 0; j < i; j++) {
System.out.println(arr5[i][j]);
}
}
// 二维数组的默认初始值
// 外层元素:默认存储地址值
// 内层元素:默认与一维数组一样
int[][] a=new int[3][2];
// 外层元素默认值
System.out.println(a[0]);//是地址值
System.out.println(a[1]);//是地址值
boolean[][] i=new boolean[1][2];
System.out.println(i[0]);
// System.out.println(i[1]);
// 内层元素默认值
// 。。。。。。。。。。。。。。。。。。。
// 以多态初始化说明:
int[][] pont=new int[4][];
// 外层元素默认值
System.out.println(pont[3]);
// 内层元素默认值
System.out.println(pont[0][0]);//空指针异常
//外层元素 默认存储null
// 内层元素 不存在的 如果调用就会报错 空指针异常
// 二维数组的内存解析:
}
}
6.练习
package demo01;
/**
* className:TowArrayTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 18:13
* @Version 1.0
**/
public class TowArrayTest {
public static void main(String[] args) {
/*
* 获取数组中和
*
* */
// 静态初始化
int[][] arr=new int[][]{{3,5,8},{12,9},{7,0,6,4}};
int sum=0;//记录元素的总和
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum+=arr[i][j];
}
}
System.out.println("总和为"+sum);
/*数组和数组之间要想相互赋值 就要满足维度一样 数据类型一样
*
* */
}
}
7.常见特征值计算
1.算法一
package demo02;
/**
* className:ArrayTest1
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 18:29
* @Version 1.0
**/
public class ArrayTest1 {
public static void main(String[] args) {
/*
* 案例:定义一个int型的一维数组 包含10个元素 分别赋值一些随机数 然后求出所有元素的最大值 最小值 总和
*
* */
// 1.创建数组 动态初始化方式创建数组
int arr[]=new int[10];
// 2.通过循环来给元素赋值
for (int i = 0; i < arr.length; i++) {
arr[i]=(int)(Math.random()*(99-10+1))+10;
}
// 求最大值
int max=arr[0];
for (int i = 0; i < arr.length; i++) {
if (max<arr[i]){
max=arr[i];
}
}
System.out.println("最大值为:"+max);
// 求最小值
int min=arr[0];
for (int i = 0; i < arr.length; i++) {
if(min>arr[i]){
min=arr[i];
}
}
System.out.println("最小值:"+min);
// 求总和
int sum=0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
System.out.println("总和为:"+sum);
// 求平均值
double avg=(double) (sum/arr.length);
System.out.println("平均值为:"+avg);
}
}
package demo02;
/**
* className:ArrayTest2
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 18:39
* @Version 1.0
**/
public class ArrayTest2 {
public static void main(String[] args) {
/*
* 在比赛中 有十位评委为参赛的选手进行打分 分数分别为 5 4 6 8 9 0 1 2 7 3
* 求选手的最后得分
* 去掉一个最高分 和一个最低分其余8位评委打分的平均值
* */
// 声明三个特征值
int[] score={5,4,6,8,9,0,1,2,7,3};
int sum=0;
int max=score[0];
int min=score[0];
for (int i = 0; i < score.length; i++) {
sum+=score[i];
if (max<score[i]);{
max=score[i];//获取高分
}
if (min>score[i]){
min=score[i];//获取低分
}
}
int avg=(sum-max-min)/(score.length-2);
System.out.println("去掉最高分和最低分之后为:"+avg);
}
}
2.算法二
package demo03;
/**
* className:ArrayList
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 19:45
* @Version 1.0
**/
public class ArrayList {
public static void main(String[] args) {
/*
* 数组的反转:
* 数组对称位置相互交换
*
*
* */
// 创建一个数组对象
int[] arr=new int[]{1,2,3,1,23,3,12,4,2,3,1,3,13,2,67};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]+"\t");
}
System.out.println();
// 反转数组元素
for (int i = 0; i < arr.length/2; i++) {
int temp=arr[i];
arr[i]=arr[arr.length-1-i];
arr[arr.length-1-i]=temp;
// System.out.println();
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
3.数组的扩容和缩容
package demo03;
/**
* className:ArrayMax
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 19:55
* @Version 1.0
**/
public class ArrayMax {
public static void main(String[] args) {
/*数组的扩容:
将数组长度扩容一倍 并且加入三个元素
*
* */
int arr[]=new int[]{1,2,3,4,5};
// 把数组扩容一倍容量
int newArr[]=new int[arr.length<<1];
// 将原有的数组复制到新的数组中
for (int i = 0; i < arr.length; i++) {
newArr[i]=arr[i];
}
// 将10 30 40添加到新数组中
newArr[arr.length]=10;
newArr[arr.length+1]=30;
newArr[arr.length+2]=40;
// 遍历新数组 将新数组的地址赋值给原有的数组变量
arr=newArr;
// 开始遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]+"\t");
}
// 开始缩容 删除索引为4的元素
}
}
package demo03;
/**
* className:ArrayMin
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 20:04
* @Version 1.0
**/
public class ArrayMin {
public static void main(String[] args) {
/*数组缩容:
删除索引为4的元素
*
* */
int arr[]=new int[]{1,2,3,4,5,6,7,8,9};
/*
* 删除数组中角标为4的元素
*
* */
int deleteIndex=4;//创建索引值
// 方式一:不新建数组
for (int i = deleteIndex; i < arr.length-1; i++) {
arr[i]=arr[i+1];
}
// 修改最后一个元素 设置为默认值
arr[arr.length-1]=0;
// 遍历arr数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 方式二:新建一个数组
int newArr[]=new int[arr.length-1];
for (int i = 0; i < deleteIndex; i++) {
newArr[i]=arr[i];
}
for (int i = deleteIndex; i <arr.length-1 ; i++) {
newArr[i]=arr[i+1];
}
System.out.println("--------------------------");
arr=newArr;
// 遍历arr数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
4.查找排序
package demo04;
/**
* className:SearchTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 20:14
* @Version 1.0
**/
public class SearchTest {
public static void main(String[] args) {
/*
* 给定一个数组
* 查找数组中的元素
* */
int arr[]=new int[]{12,32,42,43,66,98,45};
boolean isFlag=true;
int target=43;
// 查找方式:线性查找
for (int i = 0; i < arr.length; i++) {
if (target==arr[i]){
System.out.println("找到了"+target+",对应的位置为:"+i);
isFlag=false;
break;
}
}
if (isFlag){
System.out.println("没有查找到该元素");
}
// 方式二:二分查找法
/*定义数组
查找元素5是否在上述数组中出现过 如果出现输出对应的索引值
*
*
* */
System.out.println("二分查找************************************");
}
}
package demo04;
/**
* className:BinarySearchTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 20:26
* @Version 1.0
**/
public class BinarySearchTest {
public static void main(String[] args) {
/*
* 二分查找法:
* */
int arr[]=new int[]{2,3,4,5,6,7,8,9,12,13,14,15,13,8,90};
boolean isFlag=false;//判断是否找到了元素
int target=5;
int head=0;//默认首索引
int end=arr.length-1;//默认尾索引
while (head<=end){
int mid= (head+end)/2;
if (target==arr[mid]){
System.out.println("找到了"+target+"对应的位置为"+mid);
isFlag=true;
break;
}else if(target>arr[mid]){
head=mid+1;
}else {
end=mid-1;
}
}
System.out.println("不好意思没有找到");
}
}
顺序查找 算法简单 缺点就是效率低 执行的复杂度为O(n)
二分查找 优点就是执行效率高 算法相较于顺序查找难一点 前提:数组 必须是有序的
5.排序算法
1.冒泡排序
排序分为:内部排序 和外部排序
冒泡排序 快速排序 堆排序
package demo05;
/**
* className:BubbleSort
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 20:49
* @Version 1.0
**/
public class BubbleSort {
public static void main(String[] args) {
/*冒泡排序
:
*
* */
int arr[]=new int[]{34,56,78,45,29,98,67,78,12};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("///");
// 冒泡排序实现从小到大排序
for (int j = 0; j<arr.length-1 ; j++) {
for (int i = 0; i < arr.length-1-j; i++) {
if(arr[i]>arr[i+1]){
// 交换两个值的位置
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
排序算法的衡量标准 时间复杂度 空间复杂度 稳定性
排序的分类:内部排序 外部排序
内部排序:10种
冒泡排序 快速排序
堆排序
2.快速排序
8.数组工具类
package demo05;
import java.util.Arrays;
/**
* className:QuickSort
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/10 20:57
* @Version 1.0
**/
public class QuickSort {
/* 1.Array所在类的位置 java.util
* 作用:java.util.Array类即为操作数组的工具类 包含了用来操作数组
*
* */
public static void main(String[] args) {
/*
* 数组方法:
* */
int[] arr1=new int[]{12,3,12,12,12,31};
int[] arr2=new int[]{12,45,21,12,42,23};
System.out.println(Arrays.equals(arr1,arr2));//比较数组是否相等
System.out.println(Arrays.toString(arr1));//输出数组元素信息
Arrays.fill(arr1,3);//元素插入到指定的位置
Arrays.sort(arr1);//排序方法
int i = Arrays.binarySearch(arr1, 4);//二分查找的方法 传递一个要查找的值 之后会返回所在的位置 返回负数就说明没有找到
System.out.println(i);
/*
* 数组下标越界的异常
* 空指针异常
*
* 一旦程序执行中出现异常 程序就会终止执行
* 针对于异常提供的信息 避免异常再次出现
*
* */
}
}
9.数组复习
1.数组的概述
数组 就可以连接为多个数据的组合
是程序中的容器
集合 框架 list set Map
数组存取数据的特点:
数组排序是依次紧密的 有序的 可以重复的
此时的数组 集合框架都是在内存中对多个数据的存储
数组特点:一旦初始化 长度就确定了
不可改变
在main方法中声明变量
虚拟机栈:main方法作为一个栈帧 压入栈空间中 在main()栈帧中 存储着arr变量 arr记录折实体的首要地址
堆:数组实体存储在堆空间中
2.一维数组的使用
3.二维数组的使用
一维数组的元素的元素 又是一个唯一数组 则构成了二维数组
4.数组的常用算法
5.Array工具类的使用
第五章:面向对象初级
1.类与对象
package demo06;
/**
* className:ClassObject
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/11 20:04
* @Version 1.0
**/
public class ClassObject {
public static void main(String[] args) {
/*
* 面向对象的三条主线:
* java及类的成员 属性 方法 构造器 代码块 内部类
* 面向对象的特征 封装 继承 多态 (抽象)
* 其他关键字:this super package import static final interface abstract
*
* 面向过程编程 面向对象编程
* 面向过程:以函数为基本单位
* 面向对象:以类为关系
*
* 类(class) 对象(Object)
* 类“具备相同特征的事物的抽象描述 是抽象的 概念上的定义
* 对象:实际存在的该类事物的每个个体 是具体的 因此也被称为实例
*
*
* 类的声明与使用:
*
* 设计类 其实就是设计类的成员
* class Person{
*
* }
*
* 成员之一:属性 成员变量 field (字段 域)
* 成员之二:成员方法 函数 methods
* 创建类 设计内部结构
* 创建类的对象
* 通过对象调用内部的属性或方法
*
* 类的实例化 <==>创建类的对象<====>创建类的实例
* 类类型 对象名=通过new创建的对象实体
*
*
*
*
* */
Phone phone = new Phone();//造对象
//通过对象 调用内部声明的属性或方法
//对象.属性 对象.方法
System.out.println(phone.name = "苹果");
System.out.println(phone.price = 1902.09);
phone.call();
// new Scanner(System.in);
}
}
package demo07;
/**
* className:Person
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/11 20:24
* @Version 1.0
**/
public class Person {
String name;
int age;
char gender;
// 方法
public void eat(){
System.out.println("吃饭");
}
public void sleep(int hour){
System.out.println("人至少保证"+hour+"小时的睡眠");
}
public void interests(String hobby){
System.out.println("我的爱好为:"+hobby);
}
public static void main(String[] args) {
Person person = new Person();
person.age=19;
person.gender='男';
person.name="吴邪";
person.sleep(10);
System.out.println();
Person person1 = new Person();//这个对象与p1不是同一个对象
person1.sleep(90);
/*
* 对象在内存中分配涉及到的内存结构
* 栈(stack):方法内定义的变量
* 堆(heap): new出来的结构 数组实体 对象实体 包括对象中的属性
* 方法区(MethodsArea) 存放类的模板
*
*
*
* */
System.out.println("地址为:"+person1);
System.out.println("地址为:"+person);
// Person p1=new Person() Person p3=p1
// 此时p1和p2两个变量指向了堆空间中的同一个对象实体 (或p1 p2保存的地址值相同) 如果通过其中某个对象改变对象的属性时
// 会影响另一个对象变量此属性的值
}
}
2.成员变量和对象变量的对比
package demo07;
/**
* className:VariableClass
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/11 20:51
* @Version 1.0
**/
public class VariableClass {
/*
* 变量的分类:
* 按照数据类型来分:基本数据类型 引用数据类型(数组 类 接口 枚举 注解 记录)
* 按照变量在类中声明的位置不同 成员变量(或属性) 局部变量(方法内)
* 属性的几个称谓:
* 成员变量 属性 字段 域
*
* 相同点:
* 变量声明的格式相同 数据类型 变量,名=变量值
* 变量都有其有效的作用域 出了作用域就失效了
* 变量必须先声明后使用
*
*
* 不同点:
* 类中声明的位置不同:
* 属性:声明在类内 方法外的变量
* 局部变量 声明方法 构造器内部的变量
*
* 在内存中分配的位置不同:
* 属性:随着对象的创建是放在堆空间
* 局部变量:存储在栈空间中
*
* 声明周期:
* 属性:随着对象的创建的创建而创建 对象的消亡而消亡
* 局部变量:随着方法对应的栈帧入栈 局部变量会在栈中分配 随着方法对应的栈帧出栈 局部变量消亡
*
* 作用域:
* 属性:在这个类内部都是有效的
* 局部变量:仅限于声明次局部变量所在的方法 (或构造器 代码块内)
* 是否有权限修饰符:public private protected 用于表明所修饰的结构的可调用的范围的大小
*
* 属性:是可以使用权限修饰符进行修饰的
* 而局部变量 不能使用任何权限修饰符进行修饰
*
* 是否有默认值:
* 属性 都有默认初始值
* 意味着如果没有给属性进行显式初始化赋值 则会有默认初始化值
* 局部变量:都没有默认初始值
* 在使用局部变量之前必须显式的赋值
*
* 注意:对于方法的形参而言 调用方法时 给此形参赋值即可
*
*
*
* */
public static void main(String[] args) {
person person = new person();
person.age=90;
System.out.println(person);
}
}
class person {
String name;
int age;
char gender;
public void eat(String sellp){
System.out.println("人"+sellp);
}
public void hour(int time){//形参
System.out.println("人不能少于"+time);
}
}
/**
* className:mainTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/11 21:10
* @Version 1.0
**/
public class mainTest {
public static void main(String[] args) {
Employee emp1 = new Employee();
emp1.id=10;
emp1.name="吴邪";
System.out.println(emp1.id);
// 创建第二个对象
Employee emp2 = new Employee();
System.out.println(emp1.equals(emp2));
}
}
class Employee{
// 属性
int id;
String name;
int age;
double salary;
}
package demo09;
/**
* className:Employee
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/11 21:18
* @Version 1.0
**/
public class Employee {
int id;
String name;
int age;
double salary;
MyDate birthday;
public static void main(String[] args) {
Employee employee = new Employee();
employee.birthday=new MyDate();
employee.birthday.year=1998;
employee.birthday.month=9;
employee.birthday.day=17;
employee.id=1;
employee.name="吴邪";
employee.age=19;
employee.salary=19923;
System.out.println(employee.birthday);
System.out.println(employee.id+ employee.salary+ employee.age+employee.birthday.year+employee.birthday.month+employee.birthday.day);
}
}
class MyDate{
int year;
int month;
int day;
}
3.方法的作用与方法的声明
package demo09;
/**
* className:MethodsTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/11 22:06
* @Version 1.0
**/
public class MethodsTest {
}
/*使用方法的好处:
方法的了解 方法就是类或对象行为的特征的描述 用来完成某个功能的描述
方法的好处 实现代码重用 减少冗余 简代码
*
方法命名的格式:
权限修饰符 返回值类型 方法名(形参列表...)[throws 异常类型{
代码块...;//方法体
return 返回值;
}
权限修饰符:static private
注:[]中内部不是必须的 以后在讲
*
权限修饰符:
四种:
private 缺省 protected public
返回值类型:
描述当调用完此方法时 是否需要返回一个结果
分类:
无具体返回值类型
有具体返回值类型 需要指明具体的返回值类型 可以是基本数据类型 也可以是基本引用数据类型
需要在方法内部配合使用 return +返回值类型的变量或常量
我们在声明方法时 要不要提供返回值类型?
根据方法具体实现的功能来决定 换句话说就是具体问题具体分析
方法名:
属于标识符
在命名的时候 需要满足标识符的命名规范
形参列表:形参,属于局部变量
格式(形参类型1,形参类型2,形参列表3...形参列表n)
分类:无形参列表 有形参列表
无形参列表:不能省略小括号
有形参列表 根据方法调用时 需要的不确定的变量的个数 确定形参的个数
经验:声明方法时 是否需要形参列表:
具体问题具体分析
方法体:当我们调用一个方法时 真正执行的代码 体现了此方法的功能
java中的方法不调用就不执行
方法内可以调用方法或者属性 这个就是递归
方法内不能定义方法了
关键字:return
作用一:结束一个方法
作用二:结束一个方法的同时 可以返回数据给方法的调用者 (方法声明中如果有返回值类型 则方法内需要搭配return使用)
* */
class Person{
// 属性:
String name;
int age;
char gender;
//方法:
public void eat(){
System.out.println("人吃饭!");
}
public void sleep(int hour){
System.out.println("人至少每条睡眠"+hour+"小时");
}
public String interests(String hobby){
System.out.println("爱好为"+hobby);
String info="爱好为"+hobby;
return info;
}
}
3.练习题
package demo10;
/**
* className:Employee
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 13:25
* @Version 1.0
**/
public class Employee {
public static void main(String[] args) {
Employee e = new Employee();
e.show();
}
// 定义员工类里面的属性
int age = 19;
String name = "吴邪";
int id = 1;
double salary = 19232;
// 对于有该方法来显示员工的基信息
public void show() {
System.out.println(name + "\t" + id + "\t" + salary + "\t" + age);
}
/*
*
* 形参:方法在声明时 一对()内声明一个或多个形式参数 简称为形参
* 实参:方法在被调用时 实际传递给形参的变量或常量 就称为实际参数 简称实参
*
*
* 过程描述:
* */
}
package demo10;
/**
* className:Person
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 13:42
* @Version 1.0
**/
/* 创建Person类的对象 设置该对象的name age 和gender属性
调用 study方法 输出字符串学习
调用showAge方法 返回age值
* 调用addAge方法 给对象值增加addAge岁
*
*
* 创建第二个对象 执行上述操作 体会同一个类的不同对象之间的关系
*
* */
public class Person {
public static void main(String[] args) {
Person p = new Person();
p.name="吴邪";
p.age=12;
p.gender='男';
p.srudy();
p.age=10;
int age= p.showAge();
p.addAge(12);
System.out.println(age);
Person p2 = new Person();
p2.addAge(18);
int i = p2.showAge();
System.out.println(i);
}
String name;
int age;
char gender;
public void srudy(){
System.out.println("学习了");
}
public int showAge(){
return age;
}
public void addAge(int addAge){
age+=age;
}
}
package demo10;
/**
* className:Exer
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 13:52
* @Version 1.0
**/
public class Exer {
public static void main(String[] args) {
Exer e = new Exer();
e.method1();
int a= e.method3(12,12);
System.out.println(a);
}
/*
* 1.编写程序 声明一个method1方法 在方法中打印一个10*8的*矩阵 在main方法中调用
* 2.编写程序 声明一个methods2方法 除打印一个10*8的*型矩阵外
* 3.再不写程序 声明一个method3方法 在methods3方法提供m和n两个参数 方法中打印一个m*n的矩形 并且计算该矩形的面积
*
* */
public void method1(){
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 8; j++) {
System.out.print("*");
}
System.out.println();
}
}
public int method2() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 8; j++) {
System.out.print("*");
}
System.out.println();
}
return 10*8;
}
public int method3(int m,int n){
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print("*");
}
System.out.println();
}
return m*n;
}
}
package demo10;
/**
* className:Area
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 14:01
* @Version 1.0
**/
public class Area {
public static void main(String[] args) {
/*使用面向对象的方式:计算圆面积
*
* */
Area area = new Area();
area.radius=19;
double arra = area.Arra();
System.out.println("面积为:"+arra);
}
double radius;//半径
//方法
public double Arra(){
return 3.14*radius*radius;
}
}
package demo10;
/**
* className:MyArrays
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 14:07
* @Version 1.0
**/
public class MyArrays {
/*
* 编写一个数组的算法
* 求最大值
* 求最小值 总和 平均值 遍历数组 复制数组 数组反转 数组排序
*
* */
public static void main(String[] args) {
MyArrays m1 = new MyArrays();
int[] arr=new int[]{12,89,93,67,34};
int max = m1.getMax(arr);
System.out.println(max);
// m1.sort(arr);
}
/**
*
* 获取int[]数组的最大值
* @param arr 要获取数组的最大值
* @return 数组的最大值
*/
public int getMax(int[] arr){
int max=arr[0];
for (int i = 0; i < arr.length; i++) {
if(max<arr[i]){
max=arr[i];
}
}
return max;
}
public int getmin(int[] arr){
int min=arr[0];
for (int i = 0; i < arr.length; i++) {
if (min>arr[i]){
min=arr[i];
}
}
return min;
}
/**
*
* @param arr
* @return
*/
public int getSum(int[] arr){
int sum=0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
/**
*
* @return
*/
public int getAvg(int[] arr){
// 方法里面调方法 调用总和的方法 除以总数
return getSum(arr)/arr.length;
}
/**
*
* @param arr
*/
public void print(int[] arr){
System.out.println("[");
for (int i = 0; i < arr.length; i++) {
if(i==0){
System.out.println(arr[i]);
}else {
System.out.println(","+arr[i]);
}
}
System.out.println("]");;
}
/**
*
* @param arr
* @return
*/
public int[] copy(int[] arr){
int[] newArr=new int[arr.length];
for (int i = 0; i < arr.length; i++) {
newArr[i]=arr[i];
}
return newArr;
}
/**
*
* @param arr
*/
public void reverse(int[] arr){
for (int i = 0,j=arr.length-1; i<j;i++, i--) {
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
/**
*
* @param arr
*/
public void sort(int[] arr){
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length-1-j; j++) {
if(arr[i]>arr[i+1]){
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
}
/**
*
* @param arr
* @return
*/
public int search(int[] arr,int target){
for (int i = 0; i < arr.length; i++) {
if (target==arr[i]){
System.out.println("找到了"+target+"对应的位置为+"+i);
return i;
}
}
System.out.println("没有找到!");
return -1;
}
}
4.对象数组
package demo10;
/**
* className:Student
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 15:41
* @Version 1.0
**/
public class Student {
/*
*
* 对象数组:数组的元素可以是基本数据类型 也可以是引用数据类型 当元素是引用数据类型中的类的时 我们称为对象数组
*
* */
int number;//学号
int state;//年级
int score;//成绩
// 创建20个学生对象
public static void main(String[] args) {
// 创建Student[]
Student[] students=new Student[20];//创建20个学生对象
// 使用循环 给数组的元素赋值
for (int i = 0; i < students.length; i++) {
students[i]=new Student();
// 给每一个学生对象的学号 状态 成绩赋值
students[i].number=i+1;
students[i].state=(int) (Math.random()*6+1);
students[i].score=(int) (Math.random()*101);
}
// 打印出三个年级的学生信息
for (int i = 0; i < students.length; i++) {
if(3==students[i].state){
Student stu=students[i];
System.out.println("学号"+stu.number+"状态+"+stu.score);
}
}
// 使用冒泡排序 按照学生的成绩去排序 并且遍历学生信息
for (int i = 0; i < students.length; i++) {
for (int j = 0; j < students.length-1-i; j++) {
if(students[j].score>students[j+1].score){
Student temp=students[j];
students[j]=students[j+1];
students[j+1]=temp;
}
}
}
}
}
5.方法的重载
package demo10;
/**
* className:overLoad
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 16:08
* @Version 1.0
**/
public class overLoad {
public static void main(String[] args) {
/*定义:在同一个类中 允许存在一个以上的同名方法 只要他们的形参列表不相同 满足这样特征的多个方法 彼此之间构成方法的重载
*
* 两同一不同 :同一个类 相同的方法名 参数列表不同(1.参数个数不同 2.参数的类型不同)
*
* 注意:方法的重载与形参名 权限修饰符 返回值类型
*
*
* 在同一个类中不允许定义两个相同的方法 因此编译器主要是以 方法名相同且形参列表相同
* 参数类型相同 与形参名没有关系
*
* 要求在一个类中 运行存在多个相同名字的方法 只要他们形参列表不同即可
* 编译器先通过方法名 然后参数列表 参数类型
*
*
* */
overLoad p = new overLoad();
p.add("1");
p.add(12,31);//方法的重载
}
public void add(int i,int j){
System.out.println(122);
}
public void add(int i ,int j ,int k){
System.out.println(21212);
}
public void add(String p){
System.out.println(89);
}
public void add(String n,int p){
System.out.println(87);
}
}
package demo10;
/**
* className:OverLoadTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 16:19
* @Version 1.0
**/
public class OverLoadTest {
/*
* 练习一:
* 编写程序 定义三个重载方法 方法名为mOl
* 三个方法分别接收一个in套餐红素 两个int参数 一个字符串参数
* 翻倍执行平方运算并输出结果 相乘输出结果 输出字符串信息
*
*
*
* 练习二;
* 定三个重载方法max()
* 第一个方法求两个int值中最大值
* 第二个方法求两个double值中最大值
* 第三个方法求三个double 值中最大值 并且分别调用三个方法
* */
public static void main(String[] args) {
OverLoadTest i = new OverLoadTest();
i.mOL(12);
i.mOL(12,12);
i.mOL("你好 计算机科学与技术");
i.max(1,2,3);
i.max(12,67);
i.max(67,90);
}
public void mOL(int num){
System.out.println(num*num);
}
public void mOL(int num1,int num2){
System.out.println(num1*num2);
}
public void mOL(String message){
System.out.println(message);
}
/**
*
* @param i 练习二:
* @param j
* @return
*/
public int max(int i,int j){
return (i>=j)?i:j;
}
public double max(double d1 ,double d2){
return (d1>d2)?d1:d2;
}
public double max(double d1,double d2,double d3){
double tempMax=max(d1,d2);
return max(tempMax,d3);
}
}
6.可变个数的形参
package demo10;
/**
* className:OverArgsTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 16:32
* @Version 1.0
**/
public class OverArgsTest {
/*在调用方法时 可能会出现方法形参的类型是确定的 但是参数的个数不确定 此时我们就使用可变个数参数的方法
*
* 格式(参数类型...参数名)
* 说明:
* 可变个数形参的方法在调用时 针对于可变的形参赋的实参的个数为 0个 1个 多个
* 可变形参的方法与同一个类中 同名的多个方法之间可以构成重载、
* 特例:可变形参的方法与同一个类中的同一个方法的参数列表为数组作为参数的时候就不能构成重载
* 可变个数的形参必须在形参列表的最后 不然就报错
*
* 可变形参的个数在方法中有且仅有一个
*
*
* 针对数据库:
*
*
* */
public static void main(String[] args) {
OverArgsTest test = new OverArgsTest();
test.print(12,12,3,4,232,432,23,42,42);//像这样子就可以传递多个参数保护报错
test.print(new int[]{12,3,12,3});
}
public void print(int...nums){
System.out.println("调用了!");
}
public void print(int i){
System.out.println("你好");
}
public void print(int i,int j){
System.out.println(i+j);
}
}
package demo10;
/**
* className:argsTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/12 16:45
* @Version 1.0
**/
public class argsTest {
/*
* n个字符串进行拼接 每一个字符串宅男使用某字符串进行分割 如果没有传入字符串 那么就返回空字符串
* */
public static void main(String[] args) {
argsTest i = new argsTest();
String heLLO = i.content("HeLLO", "world" + "你好 计算机科学与技术");
System.out.println(heLLO);
}
public String content(String operator, String ...strs){
String result="";
for (int i = 0; i < strs.length; i++) {
if(i==0){
result+=strs[i];
}else {
result+=(operator+strs[i]);
}
}
return result;
}
}
7.方法值传递机制的剖析
package demo11;
/**
* className:OverLoad
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/13 17:13
* @Version 1.0
**/
public class OverLoad {
public static void main(String[] args) {
// 局部变量:
// 基本数据类型的局部变量
int m=10;
int n=m;//传递的值
System.out.println("m:"+m+"n:"+n);
m++;
System.out.println(m);
// 2.引用数据类型的局部变量
int[] arr1=new int[]{1,2,3,4,5,6};
int[] arr2=arr1;//传递的是地址值
arr2[0]=10;
System.out.println(arr1[0]);
// 对象类型:
Order order = new Order();
order.orderId=1;
System.out.println(order.orderId);
Order order1 = new Order();
order1=order;
order1.orderId=100;
System.out.println(order1.orderId);
System.out.println("方法传递机制*******************************************");
ValueTran v = new ValueTran();
int j=10;
v.methods(j);
System.out.println(j);//10
// 2.引用类型的变量
Person p = new Person();
p.age=10;
p.method2(p);
System.out.println(p.age);//11
}
/* 对于方法内声明的局部变量来说:如果是基本数据类型的变量 则将此变量保存的数据传递出去
* 如果是引用类型的变量 则将此变量保存的地址值传递出去
* 方法的参数传递机制:就是值传递机制
*
* 2.方法中参数的传递机制
* 形参:
* 实参
* 规则:实参给形参赋值的过程
* 如果形参是基本数据类型的变量 则将实参保存的数据值传递给形参
* 如果形参是引用数据类型的变量 则将实参保存的地址值传递给形参
*
*
* 因此java中参数的真谛机制是值传递机制 不能说引用传递
*
*
*
*
*
*
*
*
* */
}
class Order{
int orderId;
}
class ValueTran{
// 1.对于基本数据类型的变量来说
public void methods(int m){
m++;
}
}
class Person{
int age;
public void method2(Person p){
p.age++;
}
}
package demo11;
/**
* className:OverLoadTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/13 17:35
* @Version 1.0
**/
public class OverLoadTest {
public static void main(String[] args) {
/*交换两个变量的值
* */
int m=10;
int n=20;
System.out.println("m="+m+"\tn="+n);
// 交换两个变量的值
Swap swap = new Swap();
swap.SwapTest(m,n);
System.out.println("m="+m+"\tn="+n);
}
}
class Swap{
public void SwapTest(int m,int n){
int temp=m;
m=n;
n=temp;
}
}
package demo11;
/**
* className:Circle
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/13 17:46
* @Version 1.0
**/
public class Circle {
double radius;//半径
public double finalArea(){
return 3.14*radius*radius;
}
public static void main(String[] args) {
Circle circle = new Circle();
circle.radius=90;
double v = circle.finalArea();
System.out.println("面积为:"+v);
}
}
package demo11;
/**
* className:PassObject
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/13 17:49
* @Version 1.0
**/
public class PassObject {
/*
* 定义一个类PassObject 在类中定义有该方法printAreas() 该方法的定义如下
* 循环给半径赋值
*
*
* */
public static void main(String[] args) {
PassObject obj = new PassObject();
Circle circle = new Circle();
obj.printAreas(circle,5);
System.out.println(circle.radius);
}
public void printAreas(Circle c,int time){
System.out.println("Radius\t\tArea");
int i = 1;
for (; i <=time; i++) {
c.radius=i;
System.out.println(c.radius+"\t\t"+c.finalArea());
}
c.radius=i;
}
}
8.递归
package demo11;
/**
* className:MethodSA
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/13 18:02
* @Version 1.0
**/
public class MethodSA {
// 递归:方法自己调用自己
// 递归方法的分类:直接和间接
public static void main(String[] args) {
MethodSA methodSA = new MethodSA();
methodSA.method1();
int i = methodSA.method2(100);
System.out.println(i);
int i1 = methodSA.methods3(10);
System.out.println(i1);
int i2 = methodSA.methods4(10);
System.out.println(i2);
}
public void method1(){
int i=100;
int sum=0;
if(i>0){
for (int j = 0; j < i; j++,i--) {
sum+=j;
}
System.out.println(sum);
}
else {
method1();
System.out.println("完成了");
}
}
public int method2(int num){
int sum=0;
for (int i = 1; i <=num; i++) {
sum+=i;
}
return sum;
}
// 使用递归来计算100以内自然数的值
public int methods3(int num){
if(num==1){
return 1;
}else {
return methods3(num-1)+num;
}
}
// 计算阶乘
public int methods4(int n){
if (n==1){
return 1;
}else {
return n*methods4(n-1);
}
}
// 斐波那契数列
public int f(int n){
if(n==1){
return 1;
}else if (n==2){
return 1;
}
else {
return f(n-1)+f(n-2);
// 递归的使用会调用大量的堆栈
}
}
}
9.关键字package和import
package demo11;
/**
* className:PacTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/14 21:24
* @Version 1.0
**/
public class PacTest {
/* 包(package) 用于指明该文件中的定义的类
* 包名属于标识符 符合标识符的命名规则
* 同一个包下可以声明多个类和接口 但是不能定义同名的结构
*
* 包的作用:
*
*
* import 导入
* import语句可以用来显示的导入指定包下的所需要的类 相对于 import语句告诉编译器去哪里找这个类
* import.类名
*
*
* */
public static void main(String[] args) {
String[] i=new String[]{"吴邪","黑瞎子","张启山","风轻云淡"};
System.out.println(i[0]);
for (String s : i) {
System.out.println(s);
}
}
}
10.面向对象的特征一-封装性
package demo11;
/**
* className:encaseTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/14 21:48
* @Version 1.0
**/
public class encaseTest {
public static void main(String[] args) {
/*
* 面向对象-封装性:
* 理论上:
* 高内聚:类的内部数据操作细节自己来完成 不允许外部干涉
* 低耦合:仅暴露少量的方法给外部使用 记录方便外部使用
*
*
* 通俗来说:把该隐藏的隐藏起来 该暴露的暴露
*
* java中使用四种权限修饰:
* 分别:private public protected 缺省
*
* 我们可以使用四种权限修饰符来修饰类及类的内部成员 当这些成员被调用的时 体现出可见性的大小
*
* 案例:
*
*
* public(公有 值为3) private(私有 值为1) protected( 值为2)
*
* 类:只能使用public 缺省去修饰
* 类的内部成员 可以使用4种权限修饰符去修饰
*
* 开发中4种权限的使用情况:
* 比较高 public private
* 比较低 缺省 protected
*
* 封装性:
* 1; 私有化类的属性 提供公共的get和set方法 对此属性进行获取或修改
* 2.将类中不需要对外暴露的方法 进行封装
*
* 3.单例模式 构造器我们设置为私有 避免在类的内部区创建实例 放到static关键字后面将
*
* */
Animal a = new Animal();
a.name="乌龟";
/* a.legs=10;
a.legs=-12;*/
a.setlegs(4);//因为声明为私有属性 出了那个作用域就不能访问了 只能通过set方法来修改属性值
a.eat();
// 当前位置还没有能获取所有数据的方法 所以也要定义
System.out.println(a.getlegs());
// 在题目我们给腿赋值 我们不能赋值为负数 但是如果直接调用legs 是不能加入判断逻辑的 因此我们将这个属性私有化
// 机制在类的外部直接调用此属性 提供给legs属性赋值的setLegs()方法 在此方法加legs的判断逻辑
// 提供给legs属性获取的getLegs()方法 此方法外 使得在类的外部还可以调用此属性的值
}
//
}
//声明一个动物类
class Animal{
String name;//名字
private int legs;//腿的个数 要设置为私有属性 不能随意赋值
// 为了解决数据安全问题
public void setlegs(int l){
if (l>=0&&l%2==0){
legs=l;
}else {
System.out.println("数据非法!");
}
}
// 定义获取数据的方法
public int getlegs(){
return legs;
}
public void eat(){
System.out.println("动物吃饭!");
}
}
package demo12;
/**
* className:Person
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/14 22:16
* @Version 1.0
**/
public class Person {
public static void main(String[] args) {
/*
* 案例:创建程序 在其中定义两个类 Person 在setAge()设置人的合法年龄为(0-130) 用getAge()返回人的年龄
*
*
* 在主方法中实例化类镀锡 调用set和get方法
*
* */
// 测试
Person p = new Person();
p.setAge(18);
int i = p.getAge();
System.out.println(i);
}
private int age;
public void setAge(int agePost){
if(agePost>=0&&agePost<=130){
age=agePost;
}else {
System.out.println("你输入的数据非法");
}
}
// 获取age的值
public int getAge(){
return age;
}
}
package demo12;
/**
* className:BookClass
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/14 22:23
* @Version 1.0
**/
public class BookClass {
public static void main(String[] args) {
BookClass p = new BookClass();
p.setBookName("盗墓笔记");
p.setAuthor("三叔");
p.setPrice(1902.290);
String b = p.getBookName();
String s = p.showInfo();
System.out.println(s);
}
// 设置图书属性:图书名称 作者 价格
private String BookName;
private String author;
private double price;
public String getBookName(){
return BookName;
}
public void setBookName(String bn){
BookName=bn;
}
public String getAuthor(){
return author;
}
public void setAuthor(String a){
author=a;
}
public double getPrice(){
return price;
}
public void setPrice(double p){
price=p;
}
// 获取图书信息
public String showInfo(){
return "bookName"+BookName+"price"+price+"author"+author;
}
}
package demo05.demo12;
/**
* className:EmployeeTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/14 22:29
* @Version 1.0
**/
public class EmployeeTest {
/*
* 声明一个员工类:
* 包含的属性 姓名 性别 年龄 电话 属性私有化
*
*
* 提供get和set方法
* */
public static void main(String[] args) {
EmployeeTest t = new EmployeeTest();
t.setName("吴邪");
t.setGender('男');
t.setAge(19);
t.setNumberPhone("1229389233");
String info = t.getInfo();
System.out.println(info);
}
private String name;
private char gender;
private int age;
private String numberPhone;
// 提供get和set方法
public void setName(String n){
name=n;
}
public String getName(){
return name;
}
public void setGender(char g){
gender=g;
}
public char getGender(){
return gender;
}
public void setAge(int a){
age=a;
}
public int getAge(){
return age;
}
public void setNumberPhone(String pn){
numberPhone=pn;
}
public String getNumberPhone(){
return numberPhone;
}
public String getInfo(){
return name+"\t"+gender+"\t"+age+"\t"+numberPhone+"\t";
}
}
package demo12;
/**
* className:Order
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/14 22:41
* @Version 1.0
**/
public class Order {//这个类的权限是public 因此可以在任意包里面调用
/* 四种权限修饰符的测试:
*
*
* */
private int orderPrivate;
int orderDefault;//缺省
public int orderPublic;
public static void main(String[] args) {
Order p = new Order();
// 调用属性
// p.orderPrivate//不能调用
p.orderPublic=10;//中可以调用
p.orderDefault=90;//这个也可以调用
// 调用方法
p.methodDefault();//这个可以调用
//p.methodsPrivate();
}
// 声明四种权限的方法
private void methodsPrivate(){
}
void methodDefault(){
}
public void methodPublic(){
}
public void test(){
orderDefault=1;
orderPublic=2;
orderPrivate=12;
}
}
11.构造器
package demo12.constor;
/**
* className:Person
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/14 22:48
* @Version 1.0
**/
public class Person {
public static void main(String[] args) {
Person p = new Person(21);//这个Person()就是构造器
System.out.println(p.age);
}
/* 构造器:constructor
* 作用:搭配new关键字 创建类的实例
* 在创建对象的同时 可以给对象的相关属性赋值
*
* 构造器声明格式
* 权限修饰符 类名(形参列表){}
*
* 创建类以后在没有显式的提供构造器的情况下 系统会默认提供一个空参构造器 且构造器的权限与类声明的权限相同
*
* 一旦类中显式的声明构造器 则系统不在提供默认的空参的构造器
* 一个类中可以声明多个构造器 彼此之间可以构成重载
*
* */
// 构造器
/*public Person(){
System.out.println("构造器");
}*/
// 声明其他构造器
public Person(int a){
age=a;
}
String name;
int age;
public void eat(){
System.out.println("吃饭");
}
public void sleep(int hour){
System.out.println("每天睡眠"+hour+"小时");
}
}
package demo12.constor;
/**
* className:Student
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/16 13:51
* @Version 1.0
**/
public class Student {
/*
* 定义:Student类 有四个属性
* string name;
* int age;
* string school
* string major
* */
public static void main(String[] args) {
Student student = new Student("吴邪",12,"浙江大学","盗墓");
String info = student.getInfo();
System.out.println(info);
}
String name;
int age;
String school;
String major;//专业
// 以下是各种构造器
public Student(String n ,int a){
name=n;
age=a;
}
public Student(String n,int a,String s){
name=n;
age=a;
school=s;
}
public Student(String n, int a, String s ,String m){
name=n;
age=a;
school=s;
major=m;
}
public String getInfo(){
return "name:"+name+"age:"+age+"school::"+school+"major:"+major;
}
}
package demo12.constor;
/**
* className:TriAngle
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/16 13:59
* @Version 1.0
**/
public class TriAngle {
/*
* 编写一个三角形面积的类 其中类中声明私有化的底边长base和高height 同时声明公共方法访问私有量 此外 提供必要的构造器
* */
private double base;//底边长
private double heigt;//高
// 提高get和set方法
public double getBase() {
return base;
}
public void setBase(double b){
base=b;
}
public double getHeigt() {
return heigt;
}
public void setHeigt(double h){
heigt=h;
}
// 提供构造器
public TriAngle(){
}
public TriAngle(double b,double h){
base=b;
heigt=h;
}
public TriAngle(double b)
{
base=b;
}
// 求面积的方法
public double finArea(){
return (base*heigt)/2;
}
public static void main(String[] args) {
// 测试一些方法
TriAngle triAngle = new TriAngle(12.90);//可以传递多个构造器的方法 这样子不会报错
double v = triAngle.finArea();
System.out.println(v);
double base1 = triAngle.getBase();
System.out.println("底边长为:"+base1);
}
}
package demo12.constor;
/**
* className:Account
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/16 14:07
* @Version 1.0
**/
public class Account {
private int id;
private double balance;//
private double annual;//年利率
// 构造器
// 1.空参构造器
public Account(){
}
public Account(int i){
id=i;
}
public Account(int i,double b ,double a){
// balance=i;
balance=b;
id=i;
annual=a;
}
public void setId(int i){
id=i;
}
public int getId(){
return id;
}
public void setBalance(double b){
balance=b;
}
public double getBalance(){
return balance;
}
public double getAnnual() {
return annual;
}
public void setAnnual(double a){
annual=a;
}
// 取钱
public void withdraw(double amount){
if (amount<=balance){
balance-=amount;
System.out.println("成功取出"+amount);
}else {
System.out.println("取款失败!");
}
}
// 存钱
public void deposit(double amount){
if(amount>0){
balance+=amount;
System.out.println("成功存入!");
}
}
}
//创建一个Customer类
class Custromer{
private String fistName;
private String lastName;
private Account account;//自定义的类型
// 提供一个构造器
public Custromer(String f,String l){
fistName=f;
lastName=l;
}
// 书写get和set方法
public String getFistName(){
return fistName;
}
public String getLastName(){
return lastName;
}
public void setAccount(Account a){
account=a;
}
public Account getAccount(){
return account;
}
// 书写方法 测试
public static void main(String[] args) {
Custromer custromer = new Custromer("吴邪","解雨臣");
/*
* 匿名对象:只能被调用一次
* 匿名对象作为实参传递给方法的形参
* */
// new Account(200,2000,0.2233);
custromer.setAccount(new Account(10000,2000,0.2923));
// 创建账户的实例
Account account1 = new Account(1000,2000,0.01293);
custromer.setAccount(account1);
// 针对于客户的账户进行存钱取钱操作
custromer.getAccount().deposit(100);
custromer.getAccount().deposit(129092);
custromer.getAccount().deposit(92983);
System.out.println("客户"+custromer.getLastName()+"客户"+custromer.getLastName()+"客户"+custromer.getLastName());
}
}
12.UML类图
package demo12.constor;
/**
* className:UMLTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/16 14:33
* @Version 1.0
**/
public class UMLTest {
public static void main(String[] args) {
User user1 = new User();
User user2 = new User();
/*
* 在类的属性中 可以由那些位置给属性赋值
* 1.默认赋值 2.显示赋值 3.构造器中赋值 4通过方法赋值 通过对象.方法赋值 5. 通过对象.属性的方式赋值
*
* 赋值的顺序;1 2 3 4/5
* 只能执行一次:1 2 3
* 可以多次执行 4,5
*
* javaBean:是使用java语言写成的可重用的组件
* 类是公共的
* 有一个无参的公共的构造器
* 有属性 且有公共的get和set方法
*
* 2.uml类图:
* - 代表private
* +代表public
*
*
* */
}
}
class User{
// 属性或者实例变量
String name;
int age;
}
13.面向对象初级-复习
1.面向过程 与面向对象
不管是面向过程还是面向对象 还是面向函数 都是程序设计的思路
面向过程:以函数为基本单位 适合解决简单问题
面向对象:以类为基本单位 适合解决复杂问题
2.类 对象
类:抽象的 概念上的定义
对象:具体的 类的一个一个的实例
创建类 创建类的对象 通过对象去调用相关方法 属性
对象的内存解析
创建类的一个对象 创建类的多个多个对象 方法的内存解析
java中内存结构的划分:
`虚拟机栈 本地方法栈 堆` 程序计数器 本地方法栈
虚拟机栈:以栈帧为基本单位 有出栈和入栈操作 每个栈帧入栈操作对应一个方法的执行
方法内的局部变量会存在于栈帧中
堆:new 出来的结构都在这里面 数组 对象 1.数组 数组的元素在堆中 2.对象的成员变量在堆中
方法区:
加载的类的模板结构
3.类的成员之一:属性(或成员变量)
属性 局部变量对比:
属性<==>成员变量<===>域 ,字段
声明的位置
内存中存放的位置
作用域不一样
权限修饰符
初始化值
生命周期不一样
3.类的成员之二:方法
方法的声明:权限修饰符 返回值类型 方法名(参数列表){方法体}
重点:返回值类型 形参列表
return 关键字的使用
5.方法:
方法的重载 overload
方法重载的要求
: 两同一不同
调用方法时:如何确定调用的是指定的方法:1.方法名 2.形参列表
可变个数的方法
格式(int ...age)等
方法的参数传递机制
值传递机制
递归方法
方法自己调自己
构成了一种隐式的循环
6.对象数组的使用
string[]; Person[]等
7.package 与import
package 指明声明的类所属的包
import当前类中 如果使用其他包下的类 原则上就是要导入
8.oop的特征之一:
封装:
java中规定了4种权限 private 缺省 protected public
我们可以使用这四种修饰来修饰类的内部成员 当这些成员被调用时 体现可见性的大小
举例:
私有化private; 类的属性 提供公共的get和set方法 对此属性进行获取和修改
理论上:高内聚 低耦合的原则
9.类的成员之三:构造器
如何定义:
权限修饰符 类名(形参列表){}
构造器的作用:1.搭配new关键字 用来创建对象 2.初始化对象的成员变量
10.三个新知识
类的实例变量的赋值工程
JavaBean
面试题:
1.面向对象 面向过程的了解?
略
2.java中的引用类型有几种:
类 数组 接口 枚举 注解 记录
3.类和对象的区别?
4.对象存在那个区域?
堆空间
5.main方法的public能不能换成private ?为什么?
能 但是改成之后就不能作为程序的入口了 就只能是普通方法
6.构造方法和普通方法的区别?
没有共同点 声明格式 ,作用都不同
字节码的角度:构造器会以init方法的方式去呈现 用于初始化对象
7.构造器是否能被重载?
能
8.无参构造器和有参构造器的作用和应用?
初始化对象
9.变量赋值和构造方法加载的优先级问题?
变量显式赋值先与构造器中的赋值
字节码文件说明了
第六章:面向对象-进阶
1.关键字this调用属性 方法 构造器
package demo13;
/**
* className:ThisTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/18 15:17
* @Version 1.0
**/
public class ThisTest {
/*
* 1.目前可能出现的问题 及解决方案?
* 我们在声明一个属性 对应的setXxx方法时 我们通过形参对应的属性赋值 如果形参名和属性名同名了
* 如何在方法内区分两个变量?
*
* 解决方案:使用this
* 使用this修饰的变量 表示的是属性 没有使用this修饰的 表示的形参
*
* this可以调用的结构 成员变量 方法 构造器
* this的理解:当前对象(在方法中调用时) 或当前正在创建的对象 在构造器中调用时。
*
* this调用属性和方法
* 针对于方法内的使用情况 正确的来说是非static修饰的方法
* 一般情况 我们通过对象调用方法 可以在方法内调用当前对象的属性或其他方法
* 此时我们可以在属性和其他方法前使用 this. 表示当前属性或方法所属的对象 但是我们一般情况下 我们都是选择省略
* this.
*
* 特使情况:如果方法的形参合对象对象名重名了 我们必须使用this.进行区分 使用this.修饰的变量即为属性(或成员变量)
* 没有实体this。修饰的变量 即为局部变量
*
*
* this调用构造器
* 我们可以使用this(形参列表) 格式 调用 当前类中指定构造器
* 我们可以在类的构造器中 调用当前类中指定的其他构造器
* 要求:this(形参列表) 必须声明在当前构造器的首行
* 结论:this(形参列表)在构造器最多声明一个
*
* 如果一个类中声明了n个构造器 则最多有一个构造器
*
*
*
* */
public static void main(String[] args) {
Person person = new Person("吴邪",12);
person.setAge(12);
System.out.println(person.age);
User user = new User("吴邪");//只是创建了一个对象
//
}
}
class Person{
String name;
int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
public void setAge(int age){
this.age=age;//使用this来带表 当前属性所属的对象
}
}
class User{
String name;
int age;
public User(){
// 模拟对象创建时 需要初始化50行代码
}
public User(String name){
// 模拟对象创建时 需要初始化50行代码
this();
this.name=name;
}
public User(String name,int age){
// this.name=name;
this(name);
this.age=age;
}
}
package demo14;
/**
* className:Boy
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/18 16:03
* @Version 1.0
**/
public class Boy {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 生成构造器
public Boy() {
}
public Boy(String name, int age) {
this.name = name;
this.age = age;
}
public void marry(Girl girl){
System.out.println("love"+girl);
}
public void shout(){
if (this.age>=22){
System.out.println("结婚了");
}else {
System.out.println("没有结婚了");
}
}
}
class Girl{
private String name;
private int age;
public Girl() {
}
public Girl(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void marry(Boy boy){
System.out.println("我嫁给了"+boy.getName());
boy.marry(this);
}
/**
* 比较联合Grill对象的大小
* @param girl
* @return 正数 当前对象大 负数:当前对象小 0:相等
*/
public int compare(Girl girl){
/*
* 比较两个girl对象的大小
* */
if (this.age>girl.age){
return 1;
}else if(this.age< (girl.age)){
return -1;
}else {
return 0;
}
}
public static void main(String[] args) {
Boy boy = new Boy("吴邪",24);
Girl girl = new Girl("解雨臣",90);
girl.marry(boy);
}
}
package demo14;
/**
* className:Account
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/18 16:28
* @Version 1.0
**/
public class Account {
private double balance;//
public Account(double init_balance){
this.balance=init_balance;
}
public double getBalance(){
return balance;
}
// 存钱
public void deposit(double amt){
if (amt>0){
balance+=amt;
System.out.println("成功存入!");
}
}
// 取钱
public void withdraw(double amt){
if (balance>=amt&&amt>0){
balance-=amt;
System.out.println("成功取出!");
}else {
System.out.println("剩下的金额不足");
}
}
}
//创建客户类:
class Customer{
private String firstName;
private String lastName;
private Account account;//账户
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
//创建客户的类
class Bank{
private Customer[] customer;//用于保存多个客户
private int numberOfCustomer;//用于记录存储的客户的个数
// 空参构造器
public Bank(){
// 一调用方法的时候 就创建好数组
customer=new Customer[10];
}
/**
* 将指定姓名的客户保存在银行的客户列表中
* @param f
* @param l
*/
// 添加客户的方法
public void addCustomer(String f,String l){
Customer cust = new Customer(f,l);
customer[numberOfCustomer]=cust;
numberOfCustomer++;
}
/**
* 获取客户列表中存储的客户的个数
* @return
*/
public int getNumberOfCustomer(){
return numberOfCustomer;
}
/**
* 获取指定索引位置上的客户
* @param index
* @return
*/
public Customer getCustomer(int index){
if(index<0||index>=numberOfCustomer){
return null;
}
else {
return customer[index];
}
}
public static void main(String[] args) {
Bank bank = new Bank();
bank.addCustomer("邪","吴");
bank.addCustomer("雨辰","谢");
// 调用存钱的方法
bank.getCustomer(0).setAccount(new Account(10));
bank.getCustomer(1).getAccount().withdraw(903.03);
}
}
2.面向对象的特征二:继承性
package demo15;
/**
* className:ObjectMainTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/18 20:30
* @Version 1.0
**/
public class ObjectMainTest extends Person{
/* 1.继承性的了解:财产的继承 土地的继承
* 代码层面:
* 自上而下:定义了一个类A 在定义另一个类时 发现类的功能与类A相似 考虑B继承于类A
*
* 自下而上:定义了类BC D等 发现这些类有类似的属性或方法 则可以考虑将相同的属性和方法进行抽取
* 封装到类A中 让类BCD继承于类A BCD相似的功能就可以删除了
*
*
* 2.继承性的好处:
* 继承减少了代码冗余 提高代码的复用性
* 继承的出现 更有利于功能的扩展
* 继承的出现让类与类之间产生了 is-a的关系 为多态的使用提供了前提
* 继承描述事物之间的所属关系 这种关系是is-a的关系 可见父类更通用 更一般 子类更具体
*
* 3.继承的格式
* class A{
*
* }
*
* class B extends A{}
*
* 继承的基本概念:
* 类A: 父类 superClass 超类
* 类B 子类 subClass 派生类
*
* 有了继承性以后?
* 子类就获取到了父类中声明的所有属性和方法
* 但是由于封装性的影响 可能子类不能追调用父类中声明的属性或方法
* 子类在继承父类以后 还可以扩展自己特有的功能
* extends:延展 延伸
* 子类和父类的理解 要区别于集合和子集
* 不要为了继承而继承 在继承之前 判断一下is- a的关系
*
* 默认的父类:
* Object类 java中声明的类 没有显式的声明其父类的时 默认继承于Object
*
* java中支持多层继承
* 但是不支持多重继承 一个子类继承多个父类的情况不允许出现
*
* java中子父类的概念是相对的
* java中一个父类 可以声明多个子类 反之一个子类只能有一个父类 (java的单继承性)
*
*
* */
public static void main(String[] args) {
ObjectMainTest test = new ObjectMainTest();
test.eat();
System.out.println(test.getClass().getSuperclass());
}
}
class Person{
String name;
int age;
public Person(){
// 空参构造器
System.out.println("我是空参构造器!");
}
public void eat(){
System.out.println("可以吃饭!");
}
public void sleep(){
System.out.println("人睡觉!");
}
}
class A extends Person{}
class B extends A{
}
class C extends B{}
class D extends C{}
package demo15;
/**
* className:Mankind
* Package:$(PACKAGE_HAME)
* Description:
*
*
* @Author:~风轻云淡~
* @Create 2023/3/18 20:59
* @Version 1.0
**/
public class Mankind {
/*
* 第一个一个mankind类 包括:
* 成员变量int sex和int salary
* 方法void manOrWord() 根据sex的值显示 man和woman
* 方法void employee() 根据salary显示no job 或者job(salary!=0)
*
*
* */
private int sex;
private int salary;
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Mankind() {
}
public Mankind(int sex, int salary) {
this.sex = sex;
this.salary = salary;
}
public void manOrWoman(){
if (sex==1){
System.out.println("man");
}else if(sex==0){
System.out.println("woman");
}
}
public void employee(){
if (salary==0){
System.out.println("no job");
}else {
System.out.println("job");
}
}
}
class kids extends Mankind{
private int yearOld;
public kids(){
}
public kids(int yearOld){
this.yearOld=yearOld;
}
public kids(int sex,int salary,int yearOld){
this.yearOld=yearOld;
setSex(sex);
setSalary(salary);
}
public int getYearOld() {
return yearOld;
}
public void setYearOld(int yearOld) {
this.yearOld = yearOld;
}
public static void main(String[] args) {
kids kids = new kids();
kids.setSex(1);
kids.setSalary(100);
kids.setYearOld(12);
System.out.println(kids.getYearOld());
}
}
package demo15;
/**
* className:Circle
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/18 21:10
* @Version 1.0
**/
public class Circle {
private double radius;//半径
// 初始化半径值为1
public Circle(){
this.radius=1;
}
// 生成get和set方法
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
// 计算圆面积的方法
public double findArea(){
return 3.14*radius*radius;
}
}
class Cylinder extends Circle{
private double height;//圆柱的高
// 提供一个空参构造器
public Cylinder(){
this.height=1;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double Vit(){
return findArea()*getHeight();
}
public static void main(String[] args) {
Cylinder cylinder = new Cylinder();
cylinder.height=19;
double vit = cylinder.Vit();
System.out.println("体积为:"+vit);
}
}
3.方法的重写
package demo15;
/**
* className:OverwriteTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/18 21:25
* @Version 1.0
**/
public class OverwriteTest {
/*
* Overwrite 方法的重写
* 子类在继承父类以后 就获取了父类中声明的所有方法 但是 父类中的方法可能不太适用于子类
* 子类需要对父类继承过来的方法进行覆盖 重写操作
* 因此 子类对父类继承过来的方法进行的覆盖 重写的操作 就称为方法的重写
* class Account{
*
* }
*
* */
}
class m{
public void eat(){
System.out.println("吃饭!");
}
}
class n extends m{
public void eat(){
// 方法的重写
System.out.println("方法的重写!");
/*
* 方法声明的格式:
* 方法声明的格式 权限修饰符 返回值类型 方法名(形参列表)【throws 异常】{方法体}
*
* 方法重写的要求:
* 1.父类被重写的方法与子类重写的方法的方法名和形参列表必须相同
* 2.子类重写的方法的权限修饰符不小于父类被重写的方法的权限 只要权限比父类的大就可以
* 注意:子类中不能重写父类中声明为private权限修饰的方法
*
* 3.关于返回值类型
* 父类被重写的方法的返回值类型是void 则子类重写的方法的返回值类型必须是void
*
* 4.父类被重写的方法的返回值类型是基本数据类型 则子类重写的方法 返回值类型必须与被重写的方法的返回值类型相同
* 父类被重写的方法的返回值类型是引用数据类型 (比如类) 则子类重写的方法的返回值可以与被重写的方法的返回值
* 类型相同 或是被重写的方法的返回值 类型的子类
*
* 方法体:没有要求 但是子类重写的方法的方法体必然与父类被重写的方法不同
* 子类重写的方法抛出的异常类型可以与父类被重写的方法抛出的异常类型相同 或父类被重写的方法抛出的异常类型的子类
*
* 面试题:
* 重载:两同一不同
* 重写 创建以后 子类覆盖同名参数方法
* */
}
}
4.super关键字
package demo16;
/**
* className:SuperTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/18 21:57
* @Version 1.0
**/
public class SuperTest {
/*
* 1.为什么要使用super:子类继承父类后 对父类的方法进行了重写 那么在子类中 是否还可以对父类中被重写的方法进行调用?
* 可以的
*
* 2.子类继承父类以后 发现子类和父类中定义了同名的属性 是否可以在子类中区分两个同名的属性?
* 可以
*
* 3.需要使用super关键字
*
*
* super调用属性 方法
* 子类继承父类以后 我们就可以在子类的方法或构造器中 调用父类中声明的属性或方法 满足封装性的前提下
* 调用时 需要使用 super. 的结构 表示调用父类的属性或方法
* 一般情况下我们省略super.属性(方法)的结构 但是 如果出现了子类重写父类的方法或子父类出现了同名的属性时
* 则必须使用 super. 的声明 显式的调用重写的方法或者属性
* super调用构造器
* 子类调用父类时 不会继承父类的构造器 只能通过super(形参列表)的方式去调用父类指定的构造器
* 规定1super(形参列表) 必须声明在构造器的首行
* 注意 在构造器的首行 this(形参列表)和super(形参列表)只能二选一
* 在构造器的首行没有显式的调用this(形参列表) 也没有显式的调用super1(形参列表)
* 则子类次构造器默认调用super()即调用父类中空参的构造器
*
* 子类的任何一个构造器中 要么会调用被类中重载的构造器 要么会调用父类的构造器
* 只能是这两种的情况之一
* 一个类中声明有n个构造器 最多只能有n-1个构造器中使用了 this(形参列表) 则剩下的哪一个一定使用super(形参列表)
*
*
* 在子类的构造器去创建对象时 一定在调用子类构造器的过程中 直接或间接的调用到父类的构造器;‘也正因为调用过父类的构造器 我们才会将父类中声明的属性或方法加载到内存中 供子类对象使用
*
*
* */
}
class P{
public int id=100;
public void eat(){
System.out.println("学生吃饭");
}
public P(){
System.out.println("我是父类构造器!");
}
}
class student extends P{
public int id=101;//学号
public void eat(){
System.out.println("学生吃了");
}
public void sleep(){
System.out.println("学生要保证好睡眠");
}
public void show(){
eat();
super.eat();//这个调用也是不影响封装性 使用super是直接奔着父类去找的 也就是被重写的方法
System.out.println("父类"+super.id);
System.out.println("子类"+id);
}
public student(){
super();
System.out.println("子类构造器");
}
public static void main(String[] args) {
student student = new student();
student.show();
System.out.println(student.id);//就近原则
System.out.println();
student.show();
// this是就近原则 super是指定了目标
}
}
5.面向对象特征三:多态性
package demo17;
/**
* className:Polymorphic
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/19 13:44
* @Version 1.0
**/
public class Polymorphic {
/*
* 多态:
* 如何理解多态 理解为一个事物的多种形态
* java中多态性质的体现:
*
*
* 父类的引用指向子类的对象 (或子类的对象赋给父类的引用)
* 比如:Person p=new Man();
*
* 编译看左边 运行看右边
* 多态性使用前提:
* 1.要有类的继承关系 2.要有方法的重写
*
*
* 多态是适用:
* 适用于方法 不适用于属性
*
* 使用多态的好处:减少代码的冗余
*
* 使用多态的弊端:
* 在多态的场景下 我们创建了子类的对象 也加载了子类特有的属性和方法 但是由于声明为父类的引用
* 导致我们没有办法直接调用子类特有的属性和方法
*
*
*
*
*
* */
}
class Person{
String name;
int age;
public void eat(){
System.out.println("人吃饭!");
}
public void sleep(){
System.out.println("人睡觉");
}
}
class Man extends Person{
boolean isSomking;
// 对父类方法进行重写
public void eat(){
System.out.println("男人要多吃饭");
}
public void walk(){
System.out.println("男人走路");
}
public void earnMoney(){
System.out.println();
}
}
class Woman extends Person{
boolean isBeauty;
public void eat(){
System.out.println("女人吃饭");
}
public void walk(){
System.out.println("女人走路");
}
public void goShopping(){
System.out.println("逛街!");
}
public static void main(String[] args) {
// 多态性之前的场景
Person person = new Person();
Man man = new Man();
Woman woman = new Woman();
// 多态性
Person p2=new Man();//这个就是多态了 因为男人是人这个类 子类对象的多态性
// 多态性的应用
p2.eat();
p2.sleep();//虚拟方法调用
// 在多态场景下 调用方法时 编译时 认为方法是在左边声明的父类的类型 在执行时 实际执行的子类重写父类的方法
}
}
class Animal{
public void eat(){
System.out.println("动物进食!");
}
public void jump(){
System.out.println("动物跳!");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃屎");
}
public void jump(){
System.out.println("狗急跳墙!");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("狗吃屎");
}
public void jump(){
System.out.println("狗急跳墙!");
}
}
class AnimalTest{
public void adopt(Animal animal){
animal.eat();
animal.jump();
}
public static void main(String[] args) {
AnimalTest animalTest = new AnimalTest();
animalTest.adopt(new Dog());
}
}
6.向下转型
package demo19;
/**
* className:GeometricObject
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/19 15:00
* @Version 1.0
**/
public class GeometricObject {
protected String color;
protected double weight;
// 提供构造器
protected GeometricObject(String color, double weight) {
this.color = color;
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
// 计算面积的方法
public double finArea(){
return 0.0;
}
}
class Circle extends GeometricObject{
private double radius;
public Circle(String color, double weight, double radius) {
super(color, weight);//调用父类的构造器 后就不会出现报错的情况
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
//
public double finArea(){
return 3.14*radius*radius;
}
}
class MyRectangle extends GeometricObject{
private double width;
private double height;
public MyRectangle(String color, double weight, double width, double height) {
super(color, weight);
this.width = width;
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
// 重写方法
@Override
public double finArea(){
return width*height;
}
}
class GeometricTest{
/**
* 比较两个图形的面积是否相等
* @param g1
* @param g2
* @return true表示面积相等 false表示面积不相等
*/
public boolean equalsArea(GeometricObject g1,GeometricObject g2){
return g1.finArea()==g2.finArea();//判断是否相等
}
/**
* 显示几何图形的面积
* @param g
*/
public void displayGeomer(GeometricObject g){
System.out.println("几何图形的面积为:"+g.finArea());
}
public static void main(String[] args) {
GeometricTest test = new GeometricTest();
Circle circle = new Circle("red",1.0,2.6);
Circle jis = new Circle("jis", 21.2, 31);
test.displayGeomer(circle);
test.displayGeomer(jis);
boolean b = test.equalsArea(circle, jis);
if (b){
System.out.println("相等");
}
else {
System.out.println("不相等!");
}
}
}
7.Object类的使用
package demo20;
/**
* className:ObjectTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/19 15:42
* @Version 1.0
**/
public class ObjectTest {
/* 1.Object类的说明:
* 明确:java.lang.object
* 任何一个java类都直接或间接的继承于Object类
* Object类称为java类中的根父类
* Object类中声明的结构 属性 方法 等就具有通用性
* Object类中没有声明属性
* Object类提供了空参构造器
* 重点关注:Object类中声明的方法
*
* 常用方法:
* equals() toString()
* clone() finalize()
* getClass() hashCode() notify() notifyAll() wait() wait(xxx)
*
*
*
*
* */
}
8.equals()方法的使用
package demo21;
/**
* className:ObjectMethods
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/21 21:14
* @Version 1.0
**/
public class ObjectMethods {
public static void main(String[] args) {
User user = new User();
User user1 = new User();
System.out.println(user1.equals(user));
String s = new String("吴邪");
System.out.println(s);
}
}
/* 1.equals()方法的使用
* --任何引用类型都可以使用
*
* 自定义
* 自定义的类自在没有重写Object中的equals()方法的情况下 调用的就是Object类中声明的equals 比较
*两个对象的引用地址是否相同 (或者比较两个对象是否指向了堆空间的同一个对象实体)
*
*对于像string file date和包装类 他们都重写了Object类中的equals()方法 用于比较两个对象的实体内容是否相等
*
* 在实际开发中 针对于 自定义的类 常常会判断两个对象是否相等equals() 而此时主要判断两个对象的属性值是否相等
*所以 我们要重写Object类的equals()方法
* 如何重写:
* 手动自己实现
* idea自动实现
*
*
*面试:区分 == 和equals()
* == :运算符 使用范围:
* 基本数据类型 引用数据类型
* 基本数据类型 判断数据值是否相等
* 引用数据类型:比较两个引用变量的地址值是否相等 (或比较两个引用是否指向同一个对象实体)
* equals()方法
* 只能使用在引用数据类型上
* 具体使用:
* 对于类来说 重写equals 和不重写equals
*
*
*
*
*
*
* */
class User{
String name;
int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
// 重写equals()方法
public boolean equals(Object obj){
if(this==obj){
return true;
}
if (obj instanceof User){
User user=(User) obj;
return this.age==user.age&&this.name.equals(user.name);
}
return false;
}
// idea自动实现 alt + ins 点击equals()即可
}
9.tosting()方法的使用
package demo21;
/**
* className:ToStringTest
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/21 21:44
* @Version 1.0
**/
public class ToStringTest {
/* ToString()方法:
* 在调用输出方法打印对象引用对象时 其实就是调用了对象的toString()
*
* 子类使用说明:
* 自定义的类:在没有重写object的toString方法的情况下 默认返回的是当前镀锡的地址值
*
* 像string file date或包装类等Object的子类 他们都重写了Object类的toString方法 在调用toString时
* 返回当前对象的实体内容
*
* 开发中:
* 习惯上开发中对于自定义的类在调用toString() 也希望显示对象的实体内容 而非地址值 这时候 就需要重写Object中的toString方法了
* */
public static void main(String[] args) {
User user = new User("吴邪",90);
System.out.println(user.toString());
String s = new String("吴邪");
System.out.println(s.toString());
}
}
class User{
String name;
int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package demo21;
import java.util.Objects;
/**
* className:GeometricObject
* Package:$(PACKAGE_HAME)
* Description:
*
* @Author:~风轻云淡~
* @Create 2023/3/21 21:55
* @Version 1.0
**/
public class GeometricObject {
/*定义父类代表几何形状 子类代表Circle代表圆形
*
*
*
* */
protected String color;
protected double weight;
public GeometricObject() {
color="white";
weight=1.0;
}
public GeometricObject(String color, double weight) {
this.color = color;
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
class Circle extends GeometricObject{
protected double radius;
public Circle() {
color="white";
weight=1.0;
radius=1.0;
}
public Circle(double radius) {
// 构造器初始化值
color="white";
weight=1.0;
this.radius = radius;
}
public Circle(String color, double weight, double radius) {
super(color, weight);
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
// 计算圆的面积
public double findArea(){
return 3.14*radius*radius;
}
// 重写equals()方法
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public int hashCode() {
return Objects.hash(radius);
}
// 重写toString
@Override
public String toString() {
return "Circle{" +
"radius=" + radius +
", color='" + color + '\'' +
", weight=" + weight +
'}';
}
public static void main(String[] args) {
Circle circle = new Circle(2.3);
Circle circle1 = new Circle("red",9.2,3.2);
System.out.println(circle1.equals(circle));
}
}
10.复习
1.this关键字的使用
this调用的结构:
属性 方法 构造器
this调用属性或方法 理解为 当前对象或当前正在创建的对象
当属性名和形参名同名的时候 就必须使用this来区分
this(形参列表的方式 表示调用当前当前类中其他的重载的构造器)
2.面向对象的特征二:继承性
继承的好处:减少了代码的冗余 提高了复用性
提高了扩展性
为多态的使用提供了前提
java中继承的特点:
类的单继承性
后续我们通过类实现接口的方式来解决单继承的局限性
支持多层 一个父类可以声明多个子类
基础:class A extends B {
}
子类就获取了父类中声明的全部的属性 方法 可能受封装性的影响 不能直接调用
3.方法的重写
overwrite
面试题:方法重写与重载的关系 二者没有什么关系 只是一字之差
重写:前提条件得先有继承关系
子类对父类同名同参数覆盖 覆写
4.super关键字的使用
基于继承这个大前提:
super可以调用的结构 属性 方法 构造器
super:父类的
super调用父类属性 方法
如果子父类中出现了同名的属性 此时使用super的方式 表明调用的是父类中声明的属性
子类重写了父类的方法 如果子类的任何一个方法中需要调用父类被重写的方法时 需要使用super
super调用构造器
在子类的构造器中 首行要么使用this(形参列表) 要么使用super(形参列表)
5.子类对象实例化的全过程
结果上:体现为继承性
从过程上来看“子类调用构造器创建对象时 一定会直接或间接的调用其父类的构造器 以及父类的父类的构造器 直到调用到Object的构造器
6.面向对象的特征三:多态性
广义:子类对象的多态性 方法的重写 方法的重载在一定状态上也是多态
狭义上的理解:子类对象的多态性
java中的多态性:主要指的
格式:
Person per=new Man() 父类的引用指向子类的对象
多态的好处:
减少耦合 减少了大量重载方法的定义 开闭原则
多态的使用:
虚拟方法的调用:
编译看左边 运行看右边 属性 不存在多态性
多态的逆过程
向下转型 使用强转符()
为了避免强转出现异常 建议在强转前 使用instanceOf() 进行判断
7.Object类的使用
根父类
equals()和toString的使用
重写和不重写的区别:
==和equals()的区别:
toString()的使用
Object中toString()调用后 返回当前对象所属的类和地址值
开发中 重写toString用于返回当前对象的属性信息
面试题:
1.父类那些成员可以被继承 属性可以被继承吗
父类的属性 方法可以被继承 构造器可以被子类调用
2.重写:
1.什么是Overwride 与Overload的区别?
3.Overload的方法是否可以改变返回值的类型
public void methods(int i)
3.构造器是否可以被重写
不能 构造器可以重载 但是不能重写
4.为什么有重载 随便命名一个别的函数名不行吗 谈谈你是怎么理解的
见名知意 即可
5.super和this的区别?
把两个关键字的各自的特点说清楚
this,super与static是不能共用的 这个一定要注意
6.多态new出来的对象更不多态new出来的镀锡区别在哪?
Person p=new Man() 虚方法调用 屏蔽了子类Man类特有的属性和方法
Man m=new Man()
多态在代码中的体现无处不在
重写equals要注意:
明确判断两个对象实体equals的标准 是否需要所有的属性参与
对象的属性 又是自定义的类型 此属性也需要重写equals
java中的所有类的父类是OBject 它有equals Object 等