admin管理员组文章数量:1565247
视频:狂神说Java
预科 (P7-12)
什么是计算机
-
Computer:全称电子计算机,俗称电脑。
-
能够按照程序运行,自动、高速处理海量数据的现代化智能电子设备。
-
由硬件和软件所组成。
-
常见的形式有台式计算机、笔记本计算机、大型计算机等。
-
广泛应用在:科学计算、数据处理、自动控制、计算机辅助设计、人工智能、网络等领域。
硬件及冯诺依曼结构
-
计算机硬件:一些物理装置按系统结构的要求构成一个有机整体为计算机软件运行提供物质基础。
-
计算机硬件组成:CPU、主板、内存、电源、主机箱、硬盘、显卡、键盘、鼠标、显示器等。
-
装机:CPU、Memory(内存)、Motherboard(主板)、IO(input/output)设备。
软件及软件开发
-
计算机软件可以使计算机按照事先预定好的顺序完成特定功能。
-
计算机软件按照其功能可划分为系统软件和应用软件。
-
系统软件:DOS(Disk Operating System)、Windows、Linux、Unix、Mac、Android、ios。
-
应用软件:WPS、QQ、微信、英雄联盟。
-
软件、开发、软件开发。(IntelliJ IDEA)
-
人机交互(图形化界面、命令行)
Windows常用快捷键
-
键盘功能键:Tab、Shift、Ctrl、Alt、空格、Enter、Window、上下左右箭头。
-
键盘快捷键:全选(Ctrl+A)、复制(Ctrl+C)、粘贴(Ctrl+V)、剪切(Ctrl+X)、撤销(Ctrl+Z)、保存(Ctrl+S)、关闭窗口(Alt+F4)、运行、永久删除(Shift+Delete)、打开CMD窗口(Windows+R)、打开文件资源管理器(Windows+E)、打开任务管理器(Ctrl+Shift+Esc)、切换应用程序(Windows+Tab)。
基本的Dos命令
-
开启DOS控制台(cmd)的几种方式:1. 开始+系统+命令提示符。2. Win+R。 3. 在任意文件夹下,Shift+鼠标右键。 4. 资源管理器地址栏前加 ‘cmd 路径’。(管理员方式运行:选择以管理员方式运行。)
-
常见DOS命令:切换目录、开启软件、创建目录文件、删除目录文件、查看ip、ping。
#盘符切换 >D: #查看当前目录下的所有文件 >dir #切换目录 change directory >cd /d f: (/d 跨盘符切换) >cd .. (返回上级文件) #清理屏幕 clear screen >cls #退出终端 >exit #查看电脑IP >ipconfig #打开计算器 >calc #打开画图工具 >mspaint #新建记事本 >notepad #ping命令(用于测试网络) >ping www.baidu #文件操作 >md 目录名(在当前目录创建) >cd 目录名(进入目录) >cd>文件名(在当前目录创建文件) >del 文件名(删除文件) >rd 目录名(删除目录)
计算机语言发展史
-
第一代语言:机器语言
计算机的基本计算方式都是基于二进制的方式。
二进制:010110010101100。
这种代码是直接输入给计算机使用的,不经过任何的转换。
-
第二代语言:汇编语言
解决人类无法读懂机器语言的问题。
指令代替二进制。
目前应用:逆向工程、机器人、病毒。
-
第三代语言:高级语言
摩尔定律:每一美元所能买到的电脑性能,将每隔18个月翻一倍。
大体上分为:面向过程和面向对象两大类。
C语言是典型的面向过程的语言;C++、Java是典型的面向对象的语言。
各种语言:C语言⭐、C++语言、Java语言、C#语言、Python、PHP、JavaScript。
Java入门 (P13-20)
Java帝国的诞生
-
1972年C诞生
-
优点:贴近硬件,运行极快,效率极高
-
应用于操作系统,编译器,数据库,网络系统等
-
缺点:指针和内存管理等
-
-
1982年**C++**诞生
- 面向对象
- 兼容C
- 应用于图形领域、游戏等
-
建立一个新语言C+±-
- 语法有点像C
- 没有指针
- 没有内存管理
- 真正的可移植性,编写一次,到处运行
- 面向对象
- 类型安全
- 高质量的类库
-
Java初生
-
1995年的网页简单而粗糙,缺乏互动性——图形界面的程序(Applet)
Bill Gates说:这是迄今为止设计的最好的语言!
Java 2 标准版(J2SE): 去占领桌面
Java 2 移动版(J2ME): 去占领手机
Java 2 企业版(J2EE): 去占领服务器✔
-
大量巨头加入
他们基于Java开发了巨多的平台、系统、工具
构建工具:Ant,Maven,Jekins
应用服务器:Tomcat,Jetty,Jboss,Websphere,weblogic
Web开发:Struts,Spring,Hibernate,myBatis
开发工具:Eclipse,Netbean,intellij idea,Jbuilder
-
2006:Hadoop (大数据领域)
2008:Android (手机端)
一个伟大的帝国诞生了!
-
Java特性和优势
-
简单性
-
面向对象
-
可移植性 (write once, run anywhere)
-
高性能
-
分布式
-
动态性 (反射机制)
-
多线程
-
安全性
-
健壮性
Java三大版本
-
Java是一种跨平台语言:write once, run anywhere.
这是由于JVM虚拟机可以在任意平台运行
-
JavaSE: 标准版 (桌面程序、控制台开发…)⭐
JavaME: 嵌入式开发 (手机、小家电…)
JavaEE: E企业级开发 (web前端、服务器开发…)
JDK JRE JVM
-
JDK: Java Development Kit
JRE: Java Runtime Environment
JVM: Java Virtual Machine
安装开发环境
-
卸载JDK
此电脑——属性——高级系统设置——环境变量——JAVA_HOME——浏览文件——删除已有文件——删除JAVA_HOME——Path种删除JAVA_HOME相关——打开cmd——输入java -version——显示“java不是内部命令或外部命令,也不是可运行的程序或批处理文件”——卸载成功!
- 删除Java的安装目录
- 删除JAVA_HOME
- 删除path下关于Java的目录
- Java -version
-
安装JDK
-
百度搜索JDK8,找到下载地址
-
同意协议,下载
-
下载电脑对应版本 (x64)
-
双击安装JDK
-
记住安装路径
-
配置环境变量
- 我的电脑——右键——属性
- 环境变量——JAVA_HOME
- 配置path变量
-
测试JDK是否安装成功
- 打开cmd
- Java -version
-
-
notepad++安装
HelloWorld详解
-
新建文件夹,存放代码
-
新建一个Java文件
- 后缀名为.java
- HelloWorld.java
-
编写代码(注意保存)(注意大小写,符号均为英文)(文件名和类名一致)
public class HelloWorld{ public static void main (String[] arges){ System.out.print("Hello, World!"); } }
-
编译 javac HelloWorld.java ,会生成一个class文件
-
运行class文件 java HelloWorld (路径前+cmd+空格回车进入)
编译型和解释型——Java程序运行机制
-
编译型(直接翻译全部) (操作系统、C、C++)
-
解释型(哪里不会翻哪里?)
使用IDEA开发
- 百度搜索IDEA优化
Java基础(语法) (P21-32)
注释
- 平时我们编写代码,在代码量比较少的时候,还可以看懂自己写的。但是当项目结构复杂起来,就需要用到注释。
- 注释并不会被执行,是给写代码的人看的。
- 书写注释是一个非常好的习惯。
- 平时写代码一定要注意规范。
- Java中的注释有三种
- 单行注释
- 多行注释
- 文档注释
public class HelloWorld {
public static void main(String[] args) {
//单行注释
//输出一个Hello, World!
System.out.println("Hello, World!");
//多行注释:可以注释一段文字 /* 注释 */
/*
我是多行注释
*/
//JavaDoc:文档注释 /** */
/**
* @Description HelloWorld
* @Author Geminy
*/
//有趣的代码注释
/***
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ____/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
*
* .............................................
* 佛祖保佑 永无BUG
*/
}
}
标识符和关键字
-
关键字
abstract、assert、boolean、break、byte、case、catch、char、class、const、continue、default、do、double、else、enum、extends、final、finally、float、for、goto、if、implements、import、instanceof、int、interface、long、native、new、package、private、protected、public、return、strictfp、short、static、super、switch、synchronized、this、throw、throws、transient、try、void、volatile、while
-
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
- 所有的标识符都应该以字母(A-Z或者a-z)、美元符($)或者下划线(_)开始。
- 首字母之后可以是字母(A-Z或者a-z)、美元符($)、下划线(_)或数字的任何字符组合。
- 不能使用关键字作为变量名或方法名。
- 标识符是大小写敏感的。
- 可以使用中文命名,但一般不建议使用,也不建议使用拼音,很Low。
public class Demo01 {
public static void main(String[] args) {
String Ahello = "Geminy";
String hello = "Geminy";
String $hello = "Geminy";
String _hello = "Geminy";
//String 1hello = "Geminy";
//String #hello = "Geminy";
//String *hello = "Geminy";
String _1 = "Geminy";
//String _# = "Geminy";
//String class = "Geminy"; 不能用关键字
String Man = "Geminy";
String man = "Geminy";//大小写敏感
String 名字 = "Geminy";//可以用中文但不建议
}
}
数据类型讲解
-
强类型语言
变量的使用要严格符合规定,所有变量都必须先定义后使用。→安全性高,速度慢。
-
弱类型语言
变量的使用要符合规定。
-
Java的数据类型分为两大类
- 基本类型(primitive type)
- 数值类型
- 整数类型
- byte占1个字节 范围:-128-127
- short占2个字节 范围:-32768-32767
- int占4个字节 范围:-2147483648-2147483647
- long占8个字节 范围:-9223372036854775808-9223372036854775807
- 浮点类型
- float占4个字节
- double占8个字节
- 字符类型:char占2个字节
- 整数类型
- boolean类型:true和false 占1位
- 数值类型
- 引用类型(reference type)
- 类
- 接口
- 数据
- 基本类型(primitive type)
-
什么是字节
- 位 (bit):是计算机内部数据储存的最小单位,11001100是一个八位二进制数。
- 字节 (byte):是计算机中数据处理的基本单位,习惯上用大写B来表示。
- 1 B (byte,字节) = 8 bit (位)
- 字符:是指计算机中使用的字母、数字、字和符号。
- 1 bit 表示一位;1 Byte 表示一个字节 1 B = 8 bit ;1024 B = 1 KB ; 1024 KB = 1 M ; 1024 M = 1 G ;
public class Demo02 {
public static void main(String[] args) {
//test1
/*
String a = "Hello";//字符串
int b = 10;
System.out.println(a);
System.out.println(b);
*/
//test2 八大基本数据类型
//整数类型
int num1 = 10;//最常用
byte num2 = 20;
short num3 = 30;
long num4 = 30L;//long类型后面加L用以区分
//浮点类型 小数
float num5 = 50.1F;//float类型后面加F用以区分
double num6 = 3.141592654;
//字符类型
char name = 'A';//''之间只能写一个字符
//字符串,不属于数值类型,String不是关键字,是类
String name1 = "geminy";
//boolean类型 布尔类型:是、非
boolean flag = true;
boolean flag1 = false;
}
}
数据类型扩展及面试题讲解
public class Demo03 {
public static void main(String[] args) {
//-----------------------------------------------------------------
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
//-----------------------------------------------------------------
int i1 = 0b10;//二进制
int i2 = 10;//十进制
int i3 = 010;//八进制
int i4 = 0x10;//十六进制 0~9 A~F
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
System.out.println(i4);
System.out.println("--------------------------------------");//分割线
//-----------------------------------------------------------------
//浮点数拓展 银行业务怎么表示?钱 → BigDecimal 数学工具类
//-----------------------------------------------------------------
//float 有限 离散 舍入误差 大约 接近但不等于
//double
//最好避免使用浮点数进行比较
//最好避免使用浮点数进行比较
//最好避免使用浮点数进行比较
float f = 0.1f; //0.1
double d = 1.0/10;//0.1
System.out.println(f==d);//==返回布尔值false?
System.out.println(f);
System.out.println(d);
float f1 = 12345678912345f;
float f2 = f1 + 1;
System.out.println(f1==f2);//true?
System.out.println("--------------------------------------");//分割线
//-----------------------------------------------------------------
//字符拓展
//-----------------------------------------------------------------
char c1 = 'a';
char c2 = '鱼';
System.out.println(c1);
System.out.println((int)c1);//强制转换
System.out.println(c2);
System.out.println((int)c2);//强制转换
//所有的字符本质还是数字
//编码 Unicode 表:(97 = a, 65 = A) 2字节 65536 Excel 2^16=65536
//U0000 UFFFF
char c3 = '\u0061';
System.out.println(c3);//a
//转义字符: \t 指标符;\n 换行;...
System.out.println("Hello\tWorld");
System.out.println("Hello\nWorld");
System.out.println("--------------------------------------");//分割线
String s1 = new String("Hello World");
String s2 = new String("Hello World");
System.out.println(s1==s2);//false
String s3 = "Hello World";
String s4 = "Hello World";
System.out.println(s3==s4);//true
//对象 从内存分析
System.out.println("--------------------------------------");//分割线
//布尔值拓展
boolean flag = true;
if (flag==true){}//新手
if (flag){}//老手
//less is more! 代码要精简易读
}
}
输出:
2
10
8
16
--------------------------------------
false
0.1
0.1
true
--------------------------------------
a
97
鱼
40060
a
Hello World
Hello
World
--------------------------------------
false
true
--------------------------------------
类型转换
-
由于Java是强类型语言,所以进行有些运算的时候,需要用到类型转换。
低---------------------------------------------------------------->高 (容量)
byte, short, char --> int --> long --> float --> double
-
运算中,不同类型的数据先转化为同一类型,然后进行运算。
-
强制类型转换
-
自动类型转换
public class Demo04 {
public static void main(String[] args) {
int i = 128;
byte b = (byte)i;//内存溢出
//强制转换(高-->低):(类型)变量名
System.out.println(i);//128
System.out.println(b);//-128
double d = i;
//自动转换(低-->高)
System.out.println(d);//128.0
System.out.println((int)23.7);//23
System.out.println((int)-45.89f);//-45
char c = 'a';
int ii = c + 1;
System.out.println(ii);//98
System.out.println((char)ii);//b
/*
注意点:
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3.在把高容量转换到低容量的时候,强制转换
4.转换的时候可能存在内存溢出,或者精度问题
*/
}
}
输出:
128
-128
128.0
23
-45
98
b
public class Demo05 {
public static void main(String[] args) {
//操作比较大的数的时候,注意溢出问题
//JDK7新特性,数字之间可以用下划线分割
int money = 10_0000_0000;
System.out.println(money);//1000000000
int years = 20;
int total = money * years;
System.out.println(total);//-1474836480, 计算时溢出
long total2 = money * years;//默认是int,转换之前已经存在问题
System.out.println(total2);//-1474836480
long total3 = money * ((long)years);
System.out.println(total3);//20000000000
}
}
输出:
1000000000
-1474836480
-1474836480
20000000000
变量、常量、作用域
- 变量
- 变量是什么:就是可以变化的量!(存放位置确定,存放内容可变)
- Java是一种强类型语言,每个变量都必须声明其类型。
- Java变量是程序中最基本的储存单元,其要素包括变量名,变量类型和作用域。
- 注意事项
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符。
- 变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
type varName [=value] [{,varName[=value]}];
//数据类型 变量名 = 值; 可以使用逗号隔开来声明多个同类型变量, 但不建议, 尽量每个变量分行写。
public class Demo06 {
public static void main(String[] args) {
//程序可读性
int a = 1;
int b = 2;
int c = 3;
String name = "Geminy";
char x = 'X';
double pi = 3.14;
}
}
- 变量作用域
- 类变量
- 实例变量
- 局部变量
public class Variable{
static int allClicks = 0; //类变量
String str = "Hello World"; //实例变量
public void method(){
int i = 0; //局部变量
}
}
public class Demo07 {
//类变量 static
static double salary = 2500;
//属性:变量
//实例变量(在整个类中起作用):从属于对象
//如果不自行初始化,默认值 0 0.0 false(除了基本类型,其他的默认值都是null)
String name;
int age;
//main方法
public static void main(String[] args) {
//局部变量(只在定义方法的大括号间起作用):必须声明和初始化值
int i = 10;
System.out.println(i);
//实例变量使用
//变量类型 变量名字 = new Demo07();
Demo07 demo07 = new Demo07();
System.out.println(demo07.age);
System.out.println(demo07.name);
//类变量 static
System.out.println(salary);
}
//其他方法
public void function(){
}
}
输出:
10
0
null
2500.0
-
常量(Constant)
- 初始化后不能再改变值!不会变动的值。
- 所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变。
- 常量名一般使用大写字符。
final 常量名 = 值; final double PI = 3.14;
public class Demo08 { //修饰符(变量类型之前) 不存在先后顺序 static final double PI1 = 3.14; final static double PI2 = 3.14; public static void main(String[] args) { System.out.println(PI1);//3.14 System.out.println(PI2);//3.14 } }
-
变量的命名规范
-
所有变量、方法、类名:见名知意
-
类成员变量:首字母小写和驼峰原则
monthSalary、lastName 除了第一个单词以外,后面的单词首字母大写
-
局部变量:首字母小写和驼峰原则
-
常量:大写字母和下划线
MAX_VALUE
-
类名:首字母大写和驼峰原则
Man、GoodMan
-
方法名:首字母小写和驼峰原则
run()、runRun()
-
基本运算符
-
Java语言支持如下运算符
-
算数运算符:+、-、*、/、%(模,取余)、++、–
package operator; public class Demo01 { public static void main(String[] args) { //二元运算符 //Ctrl + D 复制当前行到下一行 int a = 10; int b = 20; int c = 25; int d = 25; System.out.println(a+b);//30 System.out.println(a-b);//-10 System.out.println(a*b);//300 System.out.println(a/b);//0 System.out.println(a/(double)b);//0.5 System.out.println(c%b);//5 } }
package operator; public class Demo02 { public static void main(String[] args) { long a =123123123123123L; int b = 123; short c = 10; byte d = 8; System.out.println(a+b+c+d);//long System.out.println(b+c+d);//int System.out.println(c+d);//int //运算后:有long转long,有double转double,其他转int } }
-
赋值运算符:=
-
关系运算符:>、<、>=、<=、==、!=、instanceof
package operator; public class Demo03 { public static void main(String[] args) { //关系运算符返回的结果:正确/错误 布尔值 //一般与if搭配使用 int a = 10; int b = 20; System.out.println(a>b);//f System.out.println(a<b);//t System.out.println(a==b);//f System.out.println(a!=b);//t } }
-
逻辑运算符:&&(与)、||(或)、!(非)
-
位运算符:&、|、^、~、>>、<<、>>> (了解)
-
条件运算符:? :
-
扩展复制运算符:+=、-=、*=、/=
-
自增自减运算符、初识Math类
package operator;
public class Demo04 {
public static void main(String[] args) {
//一元运算符
//++ 自增 --自减
int a = 3;
int b = a++;//执行这行代码,先给b赋值,再自增
//b=a,a=a+1
System.out.println(a);//4
int c = ++a;//执行这行代码,先自增,再给c赋值
//a=a+1,c=a
System.out.println(a);//5
System.out.println(b);//3
System.out.println(c);//5
//幂运算 2^3=2*2*2=8
//很多运算,我们会使用一些工具类来操作!Math类!
double pow1 = Math.pow(2,3);
double pow2 = Math.pow(3,2);
System.out.println(pow1);//8.0
System.out.println(pow2);//9.0
}
}
逻辑运算符、位运算符
- 逻辑运算符:&&(与)、||(或)、!(非)
package operator;
//逻辑运算符
public class Demo05 {
public static void main(String[] args) {
//与(and) 或(or) 非(取反)
boolean a = true;
boolean b = false;
System.out.println("a && b:" + (a&&b));
//逻辑与运算:两个变量都为真,结果为真;否则,结果为假。
System.out.println("a || b:" + (a||b));
//逻辑或运算:两个变量都为假,结果为假;否则,结果为真。
System.out.println("!(a && b):" + !(a&&b));
//逻辑非运算:取反。真变假;假变真。
//短路运算
int c = 5;
boolean d = (c<4)&&(c++<4);
System.out.println(d);//c<4 false
System.out.println(c);//c++未执行
}
}
输出:
a && b:false
a || b:true
!(a && b):true
false
5
- 位运算符:&、|、^(异或:相同得0,不同得1)、~(取反)、<<(左移)、>>(右移)、>>>
package operator;
public class Demo06 {
public static void main(String[] args) {
/*
A = 0011 1100
B = 0000 1101
--------------------------------------
A&B 0000 1100
A|B 0011 1101
A^B 0011 0001
~B 1111 0010
*/
/*
2*8=16=2*2*2*2
0000 0000 0
0000 0001 1
0000 0010 2
0000 0011 3
0000 0100 4
0000 1000 8
0001 0000 16
<< *2
>> /2
效率极高!
*/
System.out.println(2<<3);//16
}
}
三元运算符及小结
- 扩展复制运算符:+=、-=、*=、/=
package operator;
public class Demo07 {
public static void main(String[] args) {
int a = 10;
int b = 20;
a+=b;//a=a+b
System.out.println(a);//30
a-=b;//a=a-b
System.out.println(a);//10
//字符串链接符 + String
System.out.println(a+b);//30
System.out.println(""+a+b);//1020
//""在前面,a和b转为String连接
System.out.println(a+b+"");//30
}
}
- 三元运算符/条件运算符:? :
package operator;
//三元运算符
public class Demo08 {
public static void main(String[] args) {
// x?y:z
//如果x==true,则结果为y,否则结果为z
int score1 = 80;
int score2 = 50;
String type1 = score1 < 60 ? "不及格" : "及格";
String type2 = score2 < 60 ? "不及格" : "及格";
System.out.println(type1);
System.out.println(type2);
}
}
- 优先级–>用括号()
包机制
-
为了更好地组织类,Java提供了包机制,用于区别类名地命名空间。
-
包语句的语法格式为:
package pkg1[.pkg2[.pkg3...]]
-
一般利用公司域名倒置作为包名 com.geminy
www.baidu --> com.baidu.www
-
为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用import语句可完成此功能。导入的包名(与现有包名)不能重复。
import package1[.paceage2...].(classname|*); import com.geminy.base.*;//导入包下所有的类
-
《阿里巴巴Java开发手册》
JavaDoc生成文档
- javadoc命令是用来生成自己API的文档的。
- 参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
package com.geminy.base;
/**
* @author Geminy
* @version 1.0
* @since 1.8
*/
public class Doc {
String name;
/**
* @author Geminy
* @param name
* @return
* @throws Exception
*/
public String test(String name) throws Exception{
return name;
}
}
-
通过命令行生成Doc文档
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
打开index.html
-
用IDEA生成Doc文档
- 选中文件
- Tools --> Generate JavaDoc
- Custom scope --> Current File
- Output directory
- Other command line arguments --> -encoding utf-8 -charset utf-8
- OK
-
-
Java流程控制 (P33-44)
用户交互Scanner
-
通过Scanner类来获取用户的输入 java.util.Scanner
-
基本语法
Scanner s = new Scanner(System.in);
-
通过Scanner类的 next() 与 nextLine() 方法获取输入的字符串,在读取前需要使用 hasNext() 与 hasNextLine() 判断是否还有输入的数据。
-
next()
-
一定要读取到有效字符后才可以结束输入。
-
对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其去掉。
-
只有在输入有效字符之后,next()方法才将其后输入的空格键、Tab键或Enter键等视为分隔符或结束符。
-
简单地说,next()查找并返回来自此扫描器的下一个完整标记。
完整标记的前后是与分隔模式匹配的输入信息,所以next方法不能得到带空格的字符串。
package com.geminy.scanner; import java.util.Scanner; public class Demo01 { public static void main(String[] args) { //创建一个扫描器对象,用于接收键盘数据 Scanner scanner = new Scanner(System.in); System.out.println("使用next方式接收:"); //判断用户有没有输入字符串 if (scanner.hasNext()){ //使用next方式接收 String str = scanner.next(); System.out.println("输出的内容为:"+str); } //凡是属于IO流的类,如果不关闭会一直占用资源,要养成习惯用完就关掉 scanner.close(); } }
输出:
使用next方式接收: hello world 输出的内容为:hello
-
-
nextLine()
- 方法返回的是Enter键之前的所有字符
- 它是可以得到带空格的字符串的。
package com.geminy.scanner; import java.util.Scanner; public class Demo02 { public static void main(String[] args) { //创建一个扫描器对象,用于接收键盘数据 Scanner scanner = new Scanner(System.in); System.out.println("使用nextLine方式接收:"); //判断用户有没有输入字符串 if (scanner.hasNextLine()){ //使用nextLine方式接收 String str = scanner.nextLine(); System.out.println("输出的内容为:"+str); } //凡是属于IO流的类,如果不关闭会一直占用资源,要养成习惯用完就关掉 scanner.close(); } }
输出:
使用nextLine方式接收: Hello World 输出的内容为:Hello World
-
-
package com.geminy.scanner; import java.util.Scanner; public class Demo03 { public static void main(String[] args) { //创建一个扫描器对象,用于接收键盘数据 Scanner scanner = new Scanner(System.in); System.out.println("请输入数据:"); String str = scanner.nextLine(); System.out.println("输出的内容为:" + str); scanner.close(); } }
输出:
请输入数据: 先搞好自己 再搞肖宇梁! 输出的内容为:先搞好自己 再搞肖宇梁!
Scanner进阶使用
package com.geminy.scanner;
import java.util.Scanner;
public class Demo04 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//从键盘接收数据
int i = 0;
float f = 0.0F;
System.out.println("请输入整数:");
if (scanner.hasNextInt()){
i = scanner.nextInt();
System.out.println("整数数据:"+i);
}else{
System.out.println("输入的不是整数数据!");
}
System.out.println("请输入小数:");
if (scanner.hasNextFloat()){
f = scanner.nextFloat();
System.out.println("小数数据:"+f);
}else{
System.out.println("输入的不是小数数据!");
}
}
}
输出:
//正确示例
请输入整数:
10
整数数据:10
请输入小数:
1.1
小数数据:1.1
//错误示例
请输入整数:
10.1
输入的不是整数数据!
请输入小数:
小数数据:10.1
package com.geminy.scanner;
import java.util.Scanner;
public class Demo05 {
public static void main(String[] args) {
//我们可以输入多个数字,并求其总和与平均数
//每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果
Scanner scanner = new Scanner(System.in);
//和
double sum = 0;
//计算输入了多少个数字
int m = 0;
System.out.println("请输入数据:");
//通过循环判断是否还有输入,并在里面对每一次输入进行求和与统计
//条件不成立则退出while
while(scanner.hasNextDouble()){
double x = scanner.nextDouble();
//输入数字+1
m++;
//和
sum = sum + x;
System.out.println("你输入了第"+m+"个数据,当前数据和:"+sum);
}
System.out.println(m+"个数的和为:"+sum);
System.out.println(m+"个数的平均值为:"+(sum/m));
scanner.close();
}
}
输出:
请输入数据:
10
你输入了第1个数据,当前数据和:10.0
40
你输入了第2个数据,当前数据和:50.0
dh //退出while
2个数的和为:50.0
2个数的平均值为:25.0
顺序结构
- Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序(从上到下)一句一句执行。
- 顺序结构是最简单的算法结构。
- 语句与语句之间,框与框之间是按从上到下的顺序执行的,它是由若干个依次执行的处理步骤组成的,是任何一个算法都离不开的一种基本算法结构。
package com.geminy.struct;
public class ShunXuDemo {
public static void main(String[] args) {
System.out.println("Hello1");
System.out.println("Hello2");
System.out.println("Hello3");
System.out.println("Hello4");
System.out.println("Hello5");
}
}
输出:
Hello1
Hello2
Hello3
Hello4
Hello5
if选择结构
-
if单选择结构
-
判断一个程序是否可行,然后才去执行
-
语法
if(布尔表达式){ //如果布尔表达式为true将执行的语句 }
-
图示
-
package com.geminy.struct; import java.util.Scanner; public class IfDemo01 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入内容:"); String s = scanner.nextLine(); //equals:判断字符串是否相等 if (s.equals("Hello")){ System.out.println(s); } System.out.println("End"); scanner.close(); } }
输出:
//if不成立 请输入内容: 123 End //if成立 请输入内容: Hello Hello End
-
-
if双选择结构
-
语法
if(布尔表达式){ //如果布尔表达式为true将执行的语句 }else{ //如果布尔表达式为false将执行的语句 }
-
图示
-
package com.geminy.struct; import java.util.Scanner; public class IfDemo02 { public static void main(String[] args) { //考试分数大于60分就及格,小于60分就不及格 Scanner scanner = new Scanner(System.in); System.out.println("请输入成绩:"); int score = scanner.nextInt(); if (score>60){ System.out.println("及格"); }else{ System.out.println("不及格"); } scanner.close(); } }
输出:
请输入成绩: 80 及格
-
-
if多选择结构
-
语法
if(布尔表达式1){ //如果布尔表达式1为true将执行的语句 }else if(布尔表达式2){ //如果布尔表达式2为true将执行的语句 }else if(布尔表达式3){ //如果布尔表达式3为true将执行的语句 }else{ //如果以上布尔表达式都不为true将执行的语句 }
-
图示
-
package com.geminy.struct; import java.util.Scanner; public class IfDemo03 { public static void main(String[] args) { //考试分数大于60分就及格,小于60分就不及格 Scanner scanner = new Scanner(System.in); System.out.println("请输入成绩:"); int score = scanner.nextInt(); if (score==100){ System.out.println("满分!"); }else if (score<100 && score>=90){ System.out.println("A级"); }else if (score<90 && score>=80){ System.out.println("B级"); }else if (score<80 && score>=70){ System.out.println("C级"); }else if (score<70 && score>=60){ System.out.println("D级"); }else if (score<60 && score>=0){ System.out.println("不及格!"); }else{ System.out.println("成绩不合法"); } scanner.close(); } }
输出:
//1 请输入成绩: 102 成绩不合法 //2 请输入成绩: 100 满分! //3 请输入成绩: 90 A级 //4 请输入成绩: 40 不及格!
-
-
嵌套的if结构
-
使用嵌套的 if…else 结构是合法的。
也就是说可以在一个 if 或者 else if 语句中使用 if 或者 else if 语句。
-
语法
if(布尔表达式1){ //如果布尔表达式1为true将执行的语句 if(布尔表达式2){ //如果布尔表达式2为true将执行的语句 } }
-
Switch选择结构
-
判断一个变量与一系列值中的某个值是否相等,每个值称为一个分支
-
语法
switch(expression){ case value1: //语句1 break;//可选 case value2: //语句2 break;//可选 case valuen: //语句n break;//可选 default://可选 //语句n+1 }
-
switch语句中的变量类型可以是:byte、short、int、char
从 Java SE 7 开始,switch支持字符串String类型。
case标签必须为字符串常量或字面量。
-
package com.geminy.struct; public class SwitchDemo01 { public static void main(String[] args) { //case穿透 不写break造成 因此要在每个case后加上break! //switch 匹配一个具体的值 char grade = 'C'; switch (grade){ case 'A': System.out.println("优秀"); break; case 'B': System.out.println("良好"); break; case 'C': System.out.println("及格"); break; case 'D': System.out.println("再接再厉"); break; case 'E': System.out.println("挂科"); break; default: System.out.println("未知等级"); } } }
-
package com.geminy.struct; public class SwitchDemo02 { public static void main(String[] args) { String name = "Geminy"; //JDK7的新特性,表达式结果可以是字符串! //字符的本质还是数字 //反编译 java --> class(字节码文件) IDEA switch (name){ //switch(name.hashCode()) { case "AA": System.out.println("AA"); break; case "Geminy": System.out.println("Geminy"); break; default: System.out.println("???"); } } }
While循环详解
-
while循环是最基本的循环
-
语法
while(布尔表达式){ //循环内容 }
-
- 只要布尔表达式为true,循环就会一直执行下去。
- 大多数情况会让循环停止下来,需要一个让表达式失效的方式来结束循环。
- 少部分情况下需要循环一直执行,比如服务器的请求响应监听等。
- 循环条件一直为true就会造成无限循环(死循环),会影响程序性能或造成程序卡死崩溃,正常的业务编程中应该尽量避免死循环。
-
package com.geminy.struct; public class WhileDemo01 { public static void main(String[] args) { //输出1~10 int i = 0; while(i<10){ i++; System.out.println(i); } } }
输出:
1 2 3 4 5 6 7 8 9 10
-
package com.geminy.struct; public class WhileDemo02 { public static void main(String[] args) { while(true){ //死循环 //等待客户端连接 //定时检查 } } }
-
package com.geminy.struct; public class WhileDemo03 { public static void main(String[] args) { //计算1+2+3+...+100=? int i = 0; int sum = 0; while (i<100){ i++; sum = sum + i; } System.out.println(sum);//5050 } }
DoWhile循环
-
对于while语句而言,如果不满足条件,则不能进入循环。
但有时候需要即使不满足条件,也至少执行一次。–> do…while 循环
-
语法
do{ //代码语句 }while(布尔表达式);
-
while 和 do…while 的区别
- while 先判断后执行;do…while 先执行后判断。
- do…while总是保证循环体会被至少执行一次。
-
package com.geminy.struct; public class DoWhileDemo01 { public static void main(String[] args) { //计算1+2+3+...+100=? int i = 0; int sum = 0; do { i++; sum = sum + i; } while (i < 100); System.out.println(sum); } }
-
package com.geminy.struct; public class DoWhileDemo02 { public static void main(String[] args) { int a = 0; while (a<0){ System.out.println(a); a++; } System.out.println("---------------------------"); do { System.out.println(a); a++; }while (a<0); } }
输出:
--------------------------- 0
For循环详解⭐
-
for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
-
for循环执行的次数是在执行前就确定的。
-
语法:
for(初始化; 布尔表达式; 更新){ //代码语句 }
-
package com.geminy.struct; public class ForDemo01 { public static void main(String[] args) { int a = 1;//初始化条件 while (a<=100) {//条件判断 System.out.println(a); a += 2;//迭代 } System.out.println("while循环结束"); for (int i = 1; i <= 100; i++){ System.out.println(i); } System.out.println("for循环结束"); //100.for /* 关于for循环的几点说明: 最先执行初始化步骤,可以声明一种类型,可初始化一个或多个循环控制变量,也可以是空语句。 然后,检测布尔表达式的值。如果为true,循环体被执行;如果为false,循环终止,开始执行循环体后面的语句。 执行一次循环后,更新循环控制变量。 再次检测布尔表达式,循环执行上面的过程 */ //死循环 /* for(;;) { } */ } }
-
package com.geminy.struct; public class ForDemo02 { public static void main(String[] args) { //练习1:计算0到100之间的奇数和偶数的和 int oddSum = 0;//奇数和 int evenSum = 0;//偶数和 for (int i = 0; i <= 100; i++) { if(i%2!=0){//奇数 oddSum+=i; }else{//偶数 evenSum+=i; } } System.out.println("奇数和为:"+oddSum); System.out.println("偶数和为:"+evenSum); } }
输出:
奇数和为:2500 偶数和为:2550
-
package com.geminy.struct; public class ForDemo03 { public static void main(String[] args) { //用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个 //while int i = 1; int j = 0; while (i<=1000){ if(i%5==0){ System.out.print(i+"\t"); j++; if(j%3==0){ System.out.print("\n"); } } i++; } System.out.println(); System.out.println("---------------------------------"); //for for (int a = 1; a <= 1000; a++) { if(a%5==0) { System.out.print(a + "\t"); } if(a%(5*3)==0) { System.out.print("\n"); } } //println 输出完会换行 //print 输出完不会换行 } }
打印九九乘法表
package com.geminy.struct;
public class ForDemo04 {
public static void main(String[] args) {
//打印九九乘法表
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
if (i>=j){
System.out.print(j+"*"+i+"="+(i*j)+"\t");
}
}
System.out.println();
}
System.out.println("----------------------------------------------------------------");
for (int a = 1; a <= 9; a++) {
for (int b = 1; b <= a; b++) {
System.out.print(b+"*"+a+"="+(a*b)+"\t");
}
System.out.println();
}
}
}
输出:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
----------------------------------------------------------------
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
增强for循环
-
用于数组或集合
-
语法
for(声明语句 :表达式){ //代码句子 }
- 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
- 表达式:是要访问的数组名,或者是返回值为数组的方法。
-
package com.geminy.struct; public class ForDemo05 { public static void main(String[] args) { int[] numbers = {10,20,30,40,50}; //定义了一个数组 for (int i = 0; i < 5; i++) { System.out.println(numbers[i]); } System.out.println("-----------------------"); //遍历数组的元素 简化 for (int x:numbers) System.out.println(x); } }
输出:
10 20 30 40 50 ----------------------- 10 20 30 40 50
break、continue、goto
-
break
在任何循环语句的主体部分,均可用break控制循环的过程。
break用于强行退出循环,不执行循环中剩余的语句。
break语句也在switch语句中使用。
package com.geminy.struct; public class BreakDemo { public static void main(String[] args) { int i = 0; while (i < 100){ i++; System.out.println(i); if (i == 10){ break; } } System.out.println("break"); } }
输出:
1 2 3 4 5 6 7 8 9 10 break
-
continue
continue语句用在循环语句体中,用于终止某次循环过程。
即跳过循环体中尚未执行的语句,接着进行是否执行循环的判定。
package com.geminy.struct; public class ContinueDemo { public static void main(String[] args) { int i = 0; while (i < 100){ i++; if (i%10==0){ System.out.println(); continue;//回到while } System.out.print(i);//continue之后不执行 } } }
输出:
123456789 111213141516171819 212223242526272829 313233343536373839 414243444546474849 515253545556575859 616263646566676869 717273747576777879 818283848586878889 919293949596979899
-
goto关键字
package com.geminy.struct; public class LabelDemo { public static void main(String[] args) { //打印101-150之间所有质数 只能被1和本身整除 int count = 0; //了解 不建议使用 outer: for (int i = 101; i < 150; i++) { for (int j = 2; j < i/2; j++) { if (i % j ==0){ continue outer; } } System.out.print(i+" "); } } }
输出:
101 103 107 109 113 127 131 137 139 149
打印三角形及Debug
package com.geminy.struct;
public class TestDemo {
public static void main(String[] args) {
//打印三角形 5行
for (int i = 1; i <= 5; i++) { //第i行
for(int j = 5; j >= i; j--){
System.out.print(" ");
}
for(int j = 1; j <= i; j++){
System.out.print("*");
}
for(int j = 1; j < i; j++){
System.out.print("*");
}
System.out.println();
}
}
}
输出:
*
***
*****
*******
*********
Java方法 (P45-50)
什么是方法?
-
System.out.println() 调用System类的out对象的println方法
-
Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用(调用)
-
设计方法的原则
- 方法的本意是功能块,就是实现某个功能的语句块的集合。
- 设计方法的时候,虽好保持方法的原子性,就是一个方法只完成一个功能,这样利于后期扩展。
-
方法的命名规则:首字母小写+驼峰原则
-
package com.geminy.method; public class Demo01 { //main方法 public static void main(String[] args) { //System.out.println(add(1,2)); test(); } //加法 public static int add (int a, int b){ return a+b; } //输出1-1000之间能被5整除的数,并且每行输出3个 public static void test (){ for (int a = 1; a <= 1000; a++) { if(a%5==0) { System.out.print(a + "\t"); } if(a%(5*3)==0) { System.out.print("\n"); } } } }
方法的定义和调用
-
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段。
方法包含一个方法头和方法体。
一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名 (参数类型 参数名){ //形式参数 ... 方法体 ... return 返回值; }
-
修饰符:可选。告诉编译器如何调用该方法,定义了该方法的访问类型。
-
返回值类型:方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。
-
方法名:方法的实际名称。方法名和参数表共同构成方法签名。
-
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 形式参数:在方法被调用时用于接收外界输入的数据。
- 实参:调用方法时实际传给方法的数据。
-
方法体:包含具体的语句,定义该方法的功能。
-
-
方法调用
-
调用方法:对象名.方法名(实参列表)
-
Java支持两种调用方法的方式,根据方法是否返回值来选择:
-
当方法返回一个值的时候,方法调用通常被当作一个值。
int larger = max(30,40);
-
如果方法返回值是void,方法调用一定是一条语句。
System.out.println("Hello");
-
-
-
package com.geminy.method; public class Demo02 { public static void main(String[] args) { System.out.println(max(10,20));//20 System.out.println(max(10,10));// } //比大小 public static int max (int num1, int num2){ int result = 0; if (num1==num2){ System.out.println("num1==num2"); return 0; //终止方法 } if(num1>num2){ result = num1; }else{ result = num2; } return result; } }
输出:
20 num1==num2 0
-
拓展了解:值传递和引用传递。Java是值传递。
方法的重载
-
重载就是在一个类中,有相同的名称,但形参不同的方法。
-
规则:
- 方法名称必须相同
- 参数列表必须不同(个数不同、或类型不同、或参数排列顺序不同等)
- 方法的返回类型可以相同也可以不同
- 仅仅返回类型不同不足以称为方法的重载
-
现实理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
-
package com.geminy.method; public class Demo02 { public static void main(String[] args) { System.out.println(max(10,20));//20 System.out.println(max(10,10));// System.out.println(max(10.0,5.0));// } //比大小 public static int max (int num1, int num2){ int result = 0; if (num1==num2){ System.out.println("num1==num2"); return 0; //终止方法 } if(num1>num2){ result = num1; }else{ result = num2; } return result; } public static double max (double num1, double num2){ double result = 0; if (num1==num2){ System.out.println("num1==num2"); return 0; //终止方法 } if(num1>num2){ result = num1; }else{ result = num2; } return result; } }
输出:
20 num1==num2 0 10.0
命令行传递参数
-
有时候希望在运行一个程序的时候给它传递消息,这要靠传递命令行参数给main()函数实现。
package com.geminy.method; public class Demo03 { public static void main(String[] args) { //args.length 数组长度 for (int i = 0; i < args.length; i++) { System.out.println("args["+i+"]:"+args[i]); } } }
注意执行路径!
可变参数
- JDK 1.5开始,Java支持传递同类型的可变参数给一个方法。(个数不限)
- 在方法声明中,在指定参数类型后加一个省略号(…)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
package com.geminy.method;
public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
demo04.test(1,2,3,4,5);
}
public void test (int... i){
System.out.println((i[0]));
System.out.println((i[1]));
System.out.println((i[2]));
System.out.println((i[3]));
System.out.println((i[4]));
}
/*
public void method(){}
public void method(int i){}
public void method(int i, int j){}
public void method(int i, double j){}
*/
}
输出:
1
2
3
4
5
package com.geminy.method;
public class Demo04 {
public static void main(String[] args) {
printMax(34,3,3,2,56.5);
printMax(new double[]{1,2,3});
}
public static void printMax (double... numbers){
if (numbers.length == 0){
System.out.println("No argument passed");
return;
}
double result = numbers[0];
//排序 取最大值
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > result){
result = numbers[i];
}
}
System.out.println("The max value is:" + result);
}
}
输出:
The max value is:56.5
The max value is:3.0
递归讲解
-
A方法调用B方法,我们很容易理解;
递归就是:A方法调用A方法!就是自己调用自己!
-
递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
package com.geminy.method;
public class Demo06 {
public static void main(String[] args) {
System.out.println(f(5));
System.out.println(f(4));
}
//阶乘 2!=2*1 3!=3*2*1
//1!=f(1)=1
//2!=f(2)=2*f(1)=2*1=2
//3!=3*f(2)=3*2*f(1)=3*2*1=6
public static int f(int n){
if(n==1){
return 1;//递归头
}else{
return n*f(n-1);//递归体
}
}
}
输出:
120
24
-
Java栈机制
-
作业:写一个计算器,实现加减乘除功能,并且能够循环接收新的数据,通过用户交互实现。
package com.geminy.method; import java.util.Scanner; public class Calculator { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String s = ""; double i = 0; double j = 0; while(true){ System.out.println("请输入计算类型(+-*/)(输入q退出):"); if (scanner.hasNext()) { s = scanner.next(); if (s.equals("q")) break; }else{ System.out.println("输入的不是有效计算类型!"); } System.out.println("请输入第一个数:"); if (scanner.hasNextDouble()) { i = scanner.nextDouble(); }else{ System.out.println("输入的不是有效数据!"); } System.out.println("请输入第二个数:"); if (scanner.hasNextDouble()) { j = scanner.nextDouble(); }else{ System.out.println("输入的不是有效数据!"); } switch(s){ case "+": System.out.println("计算结果:"+i+"+"+j+"="+add(i,j)); break; case "-": System.out.println("计算结果:"+i+"-"+j+"="+sub(i,j)); break; case "*": System.out.println("计算结果:"+i+"*"+j+"="+mul(i,j)); break; case "/": System.out.println("计算结果:"+i+"/"+j+"="+div(i,j)); break; default: System.out.println("输入计算类型错误!"); } } } public static double add (double a,double b){ return a+b; } public static double sub (double a,double b){ return a-b; } public static double mul (double a,double b){ return a*b; } public static double div (double a,double b){ return a/b; } }
输出:
请输入计算类型(+-*/)(输入q退出): - 请输入第一个数: 6 请输入第二个数: 4 计算结果:6.0-4.0=2.0 请输入计算类型(+-*/)(输入q退出): * 请输入第一个数: 7 请输入第二个数: 3 计算结果:7.0*3.0=21.0 请输入计算类型(+-*/)(输入q退出): / 请输入第一个数: 9 请输入第二个数: 2 计算结果:9.0/2.0=4.5 请输入计算类型(+-*/)(输入q退出): q
Java数组 (P51-59)
什么是数组
- 数组是相同类型数据的有序集合。
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标(从0开始)来访问。
数组的声明和创建
-
首先必须声明数组变量,才能在程序中使用数组。声明数组变量的语法:
dataType[] arrayRefVar;//首选方法 dataType arrayRefVar[];//效果相同,但不是首选
-
Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
-
数组的元素是通过索引访问的,数组索引从0开始。
-
获取数组长度:
arrays.length();
package com.geminy.array;
public class ArrayDemo01 {
//变量类型 变量名 = 变量值;
//数组类型
public static void main(String[] args) {
int[] nums; //1.声明一个数组
nums = new int[10];//2.创建一个数组,可以存放10个int类型数字
//3.给数组元素赋值
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
nums[4] = 5;
nums[5] = 6;
nums[6] = 7;
nums[7] = 8;
nums[8] = 9;
nums[9] = 10;
System.out.println(nums[0]);//1
System.out.println(nums[9]);//若赋值,默认0
//计算所有元素的和
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
System.out.println("总和为:"+sum);
}
}
输出:
1
10
总和为:55
三种初始化及内存分析
-
Java内存分析
Java内存:
- 堆
- 存放new的对象和数组
- 可以被所有的线程共享,不会存放别的对象引用
- 栈
- 存放基本变量类型 (会包含这个基本类型的具体数值)
- 引用对象的变量 (会存放这个引用在堆里面的具体地址)
- 方法区
- 可以被所有的线程共享
- 包含了所有的class和static变量
- 堆
-
三种初始化
-
静态初始化
int[] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)};
-
动态初始化
int[] a = new int[2]; a[0] = 1; a[1] = 2;
-
数组的默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。(int: 0; String: null)
-
package com.geminy.array;
public class ArrayDemo02 {
public static void main(String[] args) {
//静态初始化:创建+赋值
int[] a = {1,2,3,4,5,6,7,8};
System.out.println(a[0]);//1
//动态初始化 (包含默认初始化)
int[] b = new int[10];
b[0] = 10;
System.out.println(b[0]);//10
System.out.println(b[1]);//0
}
}
下标越界及小结
-
数组的四个基本特点
- 其长度是确定的。数组一旦被创建,它的大小就是不可以更改的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
-
数组边界
-
下标的合法区间:[0, length-1],如果越界就会报错
public static void main(String[] args){ int[] a = new int[2]; System.out.println(a[2]); }
-
ArrayIndexOutOfBoundsException: 数组下标越界异常!
-
-
小结
- 数组是相同数据类型 (数据类型可以为任意类型) 的有序集合。
- 数组也是对象。数组元素相当于对象的成员变量。
- 数组长度是确定的,不可变的。如果越界,则报错。
数组的使用
- 普通的For循环
package com.geminy.array;
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5};
//打印全部数组元素
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]);
}
System.out.println("----------------------------------");
//计算所有元素的和
int sum = 0;
for (int i = 0; i < arrays.length; i++) {
sum += arrays[i];
}
System.out.println("sum=" + sum);
System.out.println("----------------------------------");
//查找最大元素
int max = arrays[0];
for (int i = 1; i < arrays.length; i++) {
if (arrays[i] > max){
max = arrays[i];
}
}
System.out.println("max=" + max);
}
}
输出:
1
2
3
4
5
----------------------------------
sum=15
----------------------------------
max=5
- For-Each循环
- 数组作方法入参
- 数组作返回值
package com.geminy.array;
public class ArrayDemo04 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5};
//arrays.for 没有下标
// For-Each循环
for (int array : arrays) {
System.out.println(array);
}
System.out.println("------------");
printArray(arrays);
System.out.println();
System.out.println("------------");
int[] reverse = reverse(arrays);
printArray(reverse);
}
//打印数组元素
// 数组作方法入参
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
}
//反转数组
// 数组作返回值
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
//反转
for (int i = 0; i < arrays.length; i++) {
result[i] = arrays[arrays.length-i-1];
}
return result;
}
}
输出:
1
2
3
4
5
------------
1 2 3 4 5
------------
5 4 3 2 1
二维数组
-
多维数组可以看成是数组的数组。比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
-
二维数组
int a[][] = new int[2][5];
可以看成是一个两行五列的数组。
package com.geminy.array;
public class ArrayDemo05 {
public static void main(String[] args) {
//int[4][2]
/*
1,2 array[0]
2,3 array[1]
3,4 array[2]
4,5 array[3]
*/
int[][] array = {{1,2},{2,3},{3,4},{4,5}};
System.out.println(array[0]);
System.out.println("---------------------------");
printArray(array[0]);
System.out.println("---------------------------");
System.out.println(array[0][0]);
System.out.println(array[0][1]);
System.out.println("---------------------------");
System.out.println(array.length);
System.out.println("---------------------------");
System.out.println(array[0].length);
System.out.println("---------------------------");
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j]+" ");
}
System.out.println();
}
}
//打印数组元素
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
System.out.println();
}
}
输出:
[I@1b6d3586
---------------------------
1 2
---------------------------
1
2
---------------------------
4
---------------------------
2
---------------------------
1 2
2 3
3 4
4 5
Arrays类讲解
package com.geminy.array;
import java.util.Arrays;
public class ArrayDemo06 {
public static void main(String[] args) {
int[] a = {1,2,3,4,9090,31231,543,21,3,23};
System.out.println(a);//[I@1b6d3586 hashCode
//打印数组元素
System.out.println(Arrays.toString(a));
printArray(a);
System.out.println();
Arrays.sort(a);//升序排序
System.out.println(Arrays.toString(a));
Arrays.fill(a,0);//填充
System.out.println(Arrays.toString(a));
Arrays.fill(a,2,4,1);//[2,4)区间填充
System.out.println(Arrays.toString(a));
}
public static void printArray(int[] a){
System.out.print("[");
for (int i = 0; i < a.length; i++) {
if (i==a.length-1) {
System.out.print(a[i] + "]");
}else{
System.out.print(a[i] + ", ");
}
}
}
}
输出:
[I@1b6d3586
[1, 2, 3, 4, 9090, 31231, 543, 21, 3, 23]
[1, 2, 3, 4, 9090, 31231, 543, 21, 3, 23]
[1, 2, 3, 3, 4, 21, 23, 543, 9090, 31231]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0]
冒泡排序
- 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序。
- 冒泡排序的代码有两层循环,外层冒泡轮数,里层依次比较。
- 算法时间复杂度为O(n2)。
package com.geminy.array;
import java.util.Arrays;
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a = {2,34,56,3,67,4,76,2,0};
int[] sort = sort(a);
System.out.println(Arrays.toString(sort));
}
//冒泡排序
//1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,交换位置
//2.每一次比较,都会产生出一个最大或者最小的数字
//3.下一轮则可以少一次排序
//4.依次循环,直到结束
public static int[] sort(int[] array){
int temp = 0; //临时变量
//外层循环,判断要走多少次
for (int i = 0; i < array.length-1; i++) {
boolean flag = false; //通过flag标识位减少没有意义的比较
//内层循环,比较判断两个数,如果第一个数比第二个数大,则交换位置
for (int j = 0; j < array.length-1-i; j++) {
if (array[j+1]>array[j]) {//>从大到小;<从小到大
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
}
if (flag==false){
break;
}
}
return array;
}
}
输出:
[76, 67, 56, 34, 4, 3, 2, 2, 0]
稀疏数组
package com.geminy.array;
public class ArrayDemo08 {
public static void main(String[] args) {
//1.创建一个二维数组 11*11 0:没有棋子;1:黑棋;2:白棋
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始的数组
System.out.println("输出原始的数组:");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
//转换为稀疏数组保存
//获取有效值的个数
int sum= 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if(array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值个数:"+sum);
//创建一个稀疏数组的数组
int[][] array2 = new int[sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//遍历二维数组,将非零的值,存放在稀疏数组中
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j]!=0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
//输出稀疏数组
System.out.println("稀疏数组:");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]);
}
//还原
//1.读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
//2.给其中的元素还原它的值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//3.打印
System.out.println("输出还原的数组:");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
}
}
输出:
输出原始的数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
有效值个数:2
稀疏数组:
11 11 2
1 2 1
2 3 2
输出还原的数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
面向对象 (P60-76)
什么是面向对象
-
面向过程思想
- 步骤清晰简单,第一步做什么,第二步做什么…
- 面向过程适合处理一些较为简单的问题
-
面向对象思想
-
物以类聚,分类的思维方式。
首先思考解决问题需要哪些分类,然后对这些分类进行单独思考,最后对某个分类下的细节进行面向过程的思索。
-
面向对象适合处理复杂的问题,适合处理需要多人协作的问题。
-
-
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面对过程的思路去处理。
-
什么是面向对象?
-
面向对象编程(Object-Oriented Programming, OOP)
-
本质就是:以类的方式组织代码,以对象的形式组织 (封装) 数据。
-
抽象 (提取共同点)
-
三大特性
- 封装
- 继承
- 多态
-
从认识论角度考虑是先有对象后有类。对象,是具体的事物;类,是抽象的,是对对象的抽象。
-
从代码运行角度考虑是先有类后有对象。类是对象的模板。(new)
-
回顾方法的定义
- 修饰符
- 返回类型
- break 和 return 的区别
- break:跳出switch,结束循环
- return:结束方法,返回一个结果
- 方法名:注意规范,见名知意,驼峰原则
- 参数列表:参数类型 参数名 (可以有多个)
- 异常抛出:疑问,后面讲解
package com.oop;
//Demo01 类
public class Demo01 {
//main 方法
public static void main(String[] args) {
}
/*
修饰符 返回值类型 方法名 (...){
//方法体
return 返回值;
}
*/
public String sayHello(){
return "Hello, World!";
}
public int max(int a,int b){
return a>b ? a : b;
}
}
回顾方法的调用
-
静态方法
非静态方法
package com.oop.demo01; //学生类 public class Student { //静态方法 和类一起加载的 public static void say1(){ System.out.println("学生说话了"); } //非静态方法 类实例化之后才存在 public void say2(){ System.out.println("学生说话了"); //静态方法不能调用非静态方法 } }
package com.oop.demo01; public class Demo02 { public static void main(String[] args) { //静态方法 static Student.say1(); //非静态方法 实例化这个类new Student student = new Student(); student.say2(); } }
输出:
学生说话了 学生说话了
-
形参和实参
package com.oop.demo01; public class Demo03 { public static void main(String[] args) { //形参和实参的类型要对应 Demo03 demo03 = new Demo03(); System.out.println(demo03.add1(1,2));//3 实参 System.out.println(Demo03.add2(1,2));//3 实参 } public int add1(int a,int b){//形参 return a+b; } public static int add2(int a,int b){//形参 return a+b; } }
-
值传递和引用传递
package com.oop.demo01; //值传递 public class Demo04 { public static void main(String[] args) { int a = 1; System.out.println(a);//1 Demo04.change(a); System.out.println(a);//1 } //返回值为空 public static void change(int a){ a = 10; } }
package com.oop.demo01; //引用传递:对象,本质还是值传递 //对象,内存! public class Demo05 { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name);//null Demo05.change(person); System.out.println(person.name);//Geminy } public static void change(Person person){ //person是一个对象:指向的--->Person person = new Person();这是一个具体的人,可以改变属性 person.name = "Geminy"; } } //定义了一个Person类,有一个属性:name class Person{ String name; }
-
this 关键字
类与对象的创建
-
类与对象的关系
-
类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,但是并不能代表某一个具体的事物。
- 动物、植物、手机、电脑…
- Person类、Pet类、Car类…
- 这些都是用来描述/定义某一类具体的事物应该具备的特点和行为。
-
对象是抽象概念的具体实例。
- 张三是人的一个具体实例。
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念。
-
-
创建和初始化对象
-
使用new关键字创建对象。
package com.oop.demo02; //学生类 public class Student { //属性: 字段 String name;//null int age;//0 //方法 public void study(){ System.out.println(this.name+"在学习"); } }
package com.oop.demo02; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { //类是抽象的,需要实例化 //类实例化后会返回一个自己的对象 //student对象就是Student类的一个具体实例 Student xiaoming = new Student(); Student xiaohong = new Student(); xiaoming.name = "小明"; xiaoming.age = 3; System.out.println(xiaoming.name);//小明 System.out.println(xiaoming.age);//3 xiaohong.name = "小红"; xiaohong.age = 4; System.out.println(xiaohong.name);//小红 System.out.println(xiaohong.age);//4 } }
-
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
-
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。
构造器的特点:
- 必须和类名字相同
- 必须没有返回类型,也不能写void
-
构造器详解
- 构造器
- 和类名相同
- 没有返回值
- 作用
- new本质在调用构造方法
- 初始化对象的值
- 注意点
- 定义有参构造之后,如果想使用无参构造,显式地定义一个无参构造
- Alt + Insert 创建构造器
package com.oop.demo02;
//java-->class
public class Person {
//一个类即使什么都不写,它也会存在一个方法
//显式的定义构造器
String name;
//实例化初始值
//1.使用new关键字,本质是在调用构造器
//2.用来初始化值
public Person(){ //无参构造
this.name = "Geminy";//初始值
}
//有参构造:一旦定义了有参构造,无参构造就必须显式定义,否则不能 new Person();
public Person(String name){
this.name = name;
}
//Alt+Insert 生成构造器
}
package com.oop.demo02;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//new 实例化一个对象
Person person1 = new Person();
System.out.println(person1.name);//Geminy
Person person2 = new Person("xyl");
System.out.println(person2.name);//xyl
}
}
创建对象内存分析
package com.oop.demo03;
public class Pet {
public String name;
public int age;
//无参构造
public void shout(){
System.out.println("叫了一声");
}
}
package com.oop;
//import class
import com.oop.demo03.Pet;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name = "旺财";
dog.age = 3;
dog.shout();//叫了一声
System.out.println(dog.name);//旺财
System.out.println(dog.age);//3
Pet cat = new Pet();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4gQsBZEW-1621173008315)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210515174331.png)]
简单小结类与对象
-
类与对象:类是一个模板:抽象;对象是一个具体的实例。
-
方法:定义、调用。
-
对象的引用
- 引用类型、基本类型(8个)
- 对象是通过引用来操作的:堆–>栈
-
属性:字段Field 成员变量
默认初始化:
- 数字:0 0.0
- char:u0000
- boolean:false
- 引用:null
修饰符 属性类型 属性名 = 属性值
-
对象的创建和使用
- 必须使用new关键字创造对象,需要构造器。Person person = new Person();
- 对象的属性 person.name
- 对象的方法 person.sleep()
-
类
- 静态的属性 属性
- 动态的行为 方法
封装详解
-
程序设计要追求"高内聚,低耦合"。
-
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;
-
低耦合就是仅暴露少量的方法给外部使用。
-
-
封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
-
属性私有,get / set
-
封装的意义:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口(get/set)
- 提高系统可维护性
package com.oop.demo04;
//类 private:私有
public class Student {
//属性私有
private String name;//名字
private int id;//学号
private char sex;//性别
private int age;//性别
//提供一些可以操作这个属性的方法!
//提供一些public的get/set方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个数据设置值
public void setName(String name){
this.name = name;
}
//Alt+Insert --> Getter Setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>120 || age<0){
this.age = 3;
}else {
this.age = age;
}
}
}
package com.oop;
//import class
import com.oop.demo04.Student;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
//s1.name 不能直接访问私有属性
s1.setName("Geminy");
System.out.println(s1.getName());//Geminy
s1.setAge(999);//不合法
System.out.println(s1.getAge());//3
s1.setAge(20);//合法
System.out.println(s1.getAge());//20
}
}
什么是继承
- 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
- extends的意思是"扩展"。子类是父类的扩展。
- Java中类只有单继承,没有多继承。(一个儿子只能有一个爸爸,一个爸爸可以有多个儿子)
- 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
- 子类和父类之间,从意义上来讲应该具有 “is a” 的关系。
package com.oop.demo05;
//在Java中,所有的类,都默认直接或间接继承Object类
//Person 人 :基类、父类
public class Person /*extends Object*/{
//public✔
//private×
//protected
//default
public int money = 10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
}
package com.oop.demo05;
//老师 is 人 :派生类、子类
public class Teacher extends Person{
}
package com.oop.demo05;
//学生 is 人 :派生类、子类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person{
//Ctrl+H 显示继承树
}
package com.oop;
//import class
import com.oop.demo05.Student;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();//说了一句话
System.out.println(student.money);//1000000000
}
}
Super详解
-
super() 调用父类的构造方法,必须在构造方法的第一行。
-
super() 只能出现在子类的方法或构造方法中。
-
super 和 this 不能同时调用构造方法。
-
super vs this
-
代表的对象不同:
- this:本身调用者这个对象
- super:代表父类对象的应用
-
前提
- this:没有继承也可以使用
- super:只能在继承条件下使用
-
构造方法
- this(); 本类的构造
- super(); 父类的构造
-
package com.oop.demo06;
//在Java中,所有的类,都默认直接或间接继承Object类
//Person 人 :基类、父类
public class Person /*extends Object*/{
public Person() {
System.out.println("Person无参构造执行了");
}
protected String name = "Geminy";
//私有的东西无法被继承
public void print(){
System.out.println("Person");
}
}
package com.oop.demo06;
//学生 is 人 :派生类、子类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person {
public Student() {
//隐藏代码:调用了父类的无参构造
//super(); 调用父类的构造器,必须在子类构造器的第一行
System.out.println("Student无参构造执行了");
}
private String name = "szd";
public void print(){
System.out.println("Student");
}
public void test(String name){
System.out.println(name);//yrjz 通过方法传入的name实参
System.out.println(this.name);//szd 自己的name
System.out.println(super.name);//Geminy 父类的name
}
public void test1(){
print();//Student
this.print();//Student
super.print();//Person
}
}
package com.oop;
//import class
import com.oop.demo06.Student;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
Student student = new Student();
System.out.println("------------------");
student.test("yrjz");
System.out.println("------------------");
student.test1();
}
}
输出:
Person无参构造执行了
Student无参构造执行了
------------------
yrjz
szd
Geminy
------------------
Student
Student
Person
方法重写
-
重写需要有继承关系,子类重写父类的方法。
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小 public > protected > default > private
- 抛出的异常:范围可以被缩小但不能扩大 ClassNotFoundException --> Exception (大)
- 方法一致,方法体不同
- Alt + Insert:override 重写快捷键
-
为什么需要重写:父类的功能,子类不一定需要,或者不一定满足。
package com.oop.demo07;
//重写都是方法的重写,和属性无关
public class B {
public static void test1(){
System.out.println("B=>test1()");
}
public void test2(){
System.out.println("B=>test2()");
}
}
package com.oop.demo07;
public class A extends B{
public static void test1(){
System.out.println("A=>test1()");
}
public void test2(){
System.out.println("A=>test2()");
}
}
package com.oop;
//import class
import com.oop.demo07.A;
import com.oop.demo07.B;
public class Application {
//一个项目应该只存在一个main方法
public static void main(String[] args) {
//静态方法和非静态方法的区别很大
//静态方法:方法的调用只和左边定义的数据类型有关
//非静态方法:重写(父类的修饰符不能是private)
A a = new A();
a.test1();//A=>test1() 静态方法
a.test2();//A=>test2() 非静态方法
//父类的引用指向了子类
B b = new A(); //子类重写了父类的方法 重写只和非静态方法有关 子类方法旁有上箭头表示重写
b.test1();//B=>test1() 静态方法
b.test2();//A=>test2() 非静态方法
//b是A new出来的对象,因此调用了A的方法
//静态方法是类的方法,而非静态方法是对象的方法
}
}
什么是多态
-
动态编译:类型:可扩展性
-
同一方法可以根据发送对象的不同而采用多种不同的行为方式。
-
一个对象的实际类型是确定的,但可以指向对象的引用类型(父类,有关系的类)有很多。
-
多态存在的条件
- 有继承关系 ( 否则–>类型转换异常ClassCastException )
- 子类重写父类方法 ( static/final/private 方法不能重写 )
- 父类引用指向子类的对象 ( Person s2 = new Student(); )
-
注意:多态是方法的多态,属性没有多态性。
package com.oop.demo08;
public class Person {
public void run(){
System.out.println("run");
}
}
package com.oop.demo08;
public class Student extends Person{
@Override
public void run() {
System.out.println("sonrun");
}
public void eat() {
System.out.println("soneat");
}
}
package com.oop;
//import class
import com.oop.demo08.Person;
import com.oop.demo08.Student;
public class Application {
//一个项目应该只存在一个main方法
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型就不确定了
//Student能调用的方法都是自己的或者继承父类的
//Person父类型,可以指向子类,但是不能调用子类独有的方法
Student s1 = new Student();
Person s2 = new Student(); //父类的引用指向子类
Object s3 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
s2.run();//sonrun 子类重写了父类的方法,执行子类的方法
s1.run();//sonrun
s1.eat();//soneat
//s2.eat(); //不能执行
((Student) s2).eat();//soneat 强制类型转换
}
}
instanceof和类型转换
- instanceof
- 判断两个类的父子关系
package com.oop;
//import class
import com.oop.demo09.Person;
import com.oop.demo09.Student;
import com.oop.demo09.Teacher;
public class Application {
//一个项目应该只存在一个main方法
public static void main(String[] args) {
//Object > Person > Student
//Object > Person > Teacher
//Object > String
Object object = new Student();
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("------------------------");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Teacher);//false
//System.out.println(person instanceof String);//编译报错 同级不能比较
System.out.println("------------------------");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher);//编译报错
//System.out.println(student instanceof String);//编译报错
//System.out.println(X instanceof Y); 能不能编译通过取决于是否为父子关系(同一条线)
}
}
- 类型转换
- 父类引用指向子类的对象
- 把子类转换为父类,向上转型 (可能丢失方法);自动转换
- 把父类转换为子类,向下转型 (可能损失精度);强制转换
- 方便方法的调用,减少重复的代码
package com.oop.demo09;
public class Person {
public void run(){
System.out.println("run");
}
}
package com.oop.demo09;
public class Student extends Person {
public void go(){
System.out.println("go");
}
}
package com.oop;
//import class
import com.oop.demo09.Person;
import com.oop.demo09.Student;
import com.oop.demo09.Teacher;
public class Application {
//一个项目应该只存在一个main方法
public static void main(String[] args) {
//类型之间的转化:父 子 自动:低-->高 强制:高-->低
// 高 低
Person student = new Student();
//student.go(); 不能执行
((Student) student).go(); //go
Student student1 = (Student) student;
student1.go(); //go
//子类转换为父类,可能丢失一些方法
Student student2 = new Student();
student2.go(); //go
Person person = student2;
}
}
static关键字详解
- test1
package com.oop.demo10;
//static 静态不能调用非静态,静态和类一起加载,非静态new之后才加载
public class Student {
private static int age;//静态变量
private double score;//非静态变量
public void run(){
go();
}
public static void go(){}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1.age);
System.out.println(s1.score);
System.out.println(Student.age);
//System.out.println(Student.score); 无法调用非静态变量
//Non-static field 'score' cannot be referenced from a static context
//run(); 无法调用非静态方法
new Student().run();
Student.go();
go();
}
}
- test2
package com.oop.demo10;
public class Person {
{ //2
//代码块(匿名代码块)可以用来赋初始值
System.out.println("匿名代码块");
}
static{ //1
//静态代码块 只执行一次
System.out.println("静态代码块");
}
public Person(){ //3
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("----------");
Person person2 = new Person();
}
}
输出:
静态代码块
匿名代码块
构造方法
----------
匿名代码块
构造方法
- test3
package com.oop.demo10;
//静态导入包
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
System.out.println(Math.random());//直接调用
System.out.println(random());//导入包之后
}
}
抽象类
- 不能new一个抽象类,只能靠子类去实现它:约束!
- 抽象类中可以写普通方法,抽象方法必须写在抽象类中。
- 抽象的抽象:约束
- 抽象类存在构造器
- 意义:提高开发效率
package com.oop.demo11;
//abstract class 抽象类 类extends只能单继承;接口可以多继承
public abstract class Action {
//约束,有人帮我们实现
//abstract 抽象方法,只有方法名字,没有方法的实现
public abstract void doSomething();//没有方法体
}
package com.oop.demo11;
//抽象类的所有方法,继承了它的子类都必须要实现它的方法,除非子类也是抽象类
public class A extends Action{
@Override
public void doSomething() {
}
}
package com.oop;
//import class
import com.oop.demo11.A;
import com.oop.demo11.Action;
public class Application {
//一个项目应该只存在一个main方法
public static void main(String[] args) {
//new Action(); 不能new抽象类
}
}
接口的定义与实现
-
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有
- 接口:只有规范,自己无法写方法,专业的约束,约束和实现分离:面向接口编程
-
接口就是规范,定义的是一组规则,体现了现实世界中"如果你是…则必须能…"的思想。
-
接口的本质是契约,制定以后都要遵守。
-
面向对象的精髓,是对对象的抽象,最能体现这一点的就是接口。
-
接口的作用:
- 约束
- 定义一些方法,让不同的人实现
- 接口的方法都是public abstract
- 接口的常量都是public static final
- 接口不能被实例化,接口中没有构造方法
- implements可以实现多个接口
- 必须重写接口中的方法
package com.oop.demo12;
public interface TimeService {
void timer();
}
package com.oop.demo12;
//interface 接口都需要有实现类
public interface UserService {
//接口中的所有定义的都是常量 public static final
int AGE = 99;
//接口中的所有定义的方法其实都是抽象的public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package com.oop.demo12;
//类 可以实现接口 implements 接口
//实现了接口的类需要重写接口中的方法
//利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
N种内部类
- 内部类就是在一个类的内部再定义一个类。
- 分为:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
package com.oop.demo13;
public class Outer {
private int id = 10;
public void out(){
System.out.println("外部类方法");
}
//public static class Inner { 静态内部类,不能调用id
public class Inner { //成员内部类
public void in(){
System.out.println("内部类方法");
}
//获得外部类的私有属性
public void gerID(){
System.out.println(id);
}
}
public void methed(){
class Inner1{ //局部内部类
public void in(){
}
}
}
}
//一个Java类中可以有多个class类,但是只有有一个public class
class A{
}
package com.oop;
//import class
import com.oop.demo13.Outer;
public class Application {
//一个项目应该只存在一个main方法
public static void main(String[] args) {
//实例化外部类
Outer outer = new Outer();
//通过外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();//内部类方法
inner.gerID();//10
}
}
package com.oop.demo13;
import com.oop.demo12.UserService;
public class Test {
public static void main(String[] args) {
Apple apple = new Apple();
//匿名内部类,没有名字的初始化类,不用将实例保存到变量中
new Apple().eat();
new UserServise(){
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserServise{
void hello();
}
异常 (P77-79)
Error和Excption
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WOE8XlNu-1621173008319)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210516204152.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GRgIgGx6-1621173008322)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210516204341.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-beDuCo2c-1621173008376)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210516204629.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-69vQzdWJ-1621173008378)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210516204717.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e96hynoE-1621173008379)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210516204853.png)]
package com.exception;
public class Demo01 {
public static void main(String[] args) {
//Exception in thread "main" java.lang.StackOverflowError
//new Demo01().a();
//Exception in thread "main" java.lang.ArithmeticException: / by zero
//System.out.println(11/0);
System.out.println();
}
public void a(){
b();
}
public void b(){
a();
}
}
捕获和抛出异常
- 抛出异常
- 捕获异常
- 异常处理五个关键字
- try
- catch
- finally
- throw
- throws
package com.exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
//Exception in thread "main" java.lang.ArithmeticException: / by zero
//System.out.println(a/b);
try{ //try监控区域
System.out.println(a/b);
}catch(ArithmeticException e){ //捕获异常
System.out.println("程序出现异常,变量b不能为0");
}finally{ //处理善后工作
System.out.println("finally");
}
//finally用于IO、资源关闭 可以不要finally
System.out.println("--------------");
//假设要捕获多个异常:从小到大捕获
try{ //try监控区域
System.out.println(a/b);
}catch (Error e){ //捕获异常
System.out.println("Error");
}catch (Exception e){ //捕获异常
System.out.println("Exception");
}catch (Throwable e){ //捕获异常
System.out.println("Throwable");
}finally{ //处理善后工作
System.out.println("finally");
}
}
public void a(){
b();
}
public void b(){
a();
}
}
输出:
程序出现异常,变量b不能为0
finally
--------------
Exception
finally
package com.exception;
public class Test2 {
public static void main(String[] args) {
int a = 1;
int b = 0;
//Ctrl + Alt + T + 选中
try {
System.out.println(a/b);
} catch (Exception e) {
System.exit(0);//结束程序
e.printStackTrace();//打印错误的栈信息
} finally {
}
}
}
package com.exception;
public class Test {
public static void main(String[] args) {
try {
new Test().test(1,0);
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
//假设这个方法中,处理不了这个异常,方法上抛出异常
public void test(int a,int b) throws ArithmeticException{
if (b==0){
throw new ArithmeticException();
//主动抛出异常,一般在方法中使用
}
}
}
自定义异常及经验小结
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ium4HaBv-1621173008381)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210516213555.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DmoT7RlB-1621173008382)(C:\Users\RJY\Desktop\Java2021\MarkDown学习\笔记图片\QQ图片20210516213631.png)]
package com.exception.demo02;
//自定义的异常类
public class MyException extends Exception{
//传递数字 >10 抛出异常
private int detail;
public MyException(int a) {
this.detail = a;
}
//toString:异常的打印信息
@Override
public String toString() {
return "MyException{" +
"detail=" + detail +
'}';
}
}
package com.exception.demo02;
public class Test {
//可能会存在异常的方法
static void test(int a) throws MyException{
System.out.println("传递的参数为:"+a);
if(a>10){
throw new MyException(a);//抛出
}
System.out.println("OK");
}
public static void main(String[] args) {
try {
test(1);
} catch (MyException e) {
System.out.println("MyException->"+e);
}
System.out.println("-----------");
try {
test(11);
} catch (MyException e) {
System.out.println("MyException->"+e);
}
}
}
输出:
传递的参数为:1
OK
-----------
传递的参数为:11
MyException->MyException{detail=11}
JavaSE总结 (P80)
版权声明:本文标题:【狂神说Java】视频笔记 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1727169785a1100110.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论