JAVA基础
一、流程控制
Scanner对象
通过Scanner类来获取用户的输入
1、基本语法:
Scanner s = new Scanner(System.in);
用next()或nextLine()方法获取输入的字符串,用hasNext()或hasNextLine()判断是否还有输入的数据。
next()不能得到带有空格的字符串,若有空格,只输出第一个空格前的有效字符。
nextLine()可以获得空白。
2、Scanner关于整数和小数的应用
hasNextInt(); hasNextFloat();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2qcu5xOD-1647442360818)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220305173126639.png)]
顺序结构
JAVA的基本结构就是顺序结构。
选择结构
if或switch
比较字符串:equals函数
if(s.equals("Hello")){
System.out.println(s);
}else {
System.out.println("End");
}
switch、 case、 break、 default等
switch匹配一个具体的值。
case有穿透现象,所有要写上break;
循环结构
while (条件){ 逻辑 } 最基本的循环
do…while :至少执行一次,和while的用法与逻辑很像
for:使用频率最多的循环,最有效的循环结构 for(初始化;布尔表达式;更新)
快捷键:100.for,回车,即可快速生成一个for循环 for(i=0;i<100;i++){ }
System.out.print(i+"\t");//每输出一个数,留一个空格
增强for循环
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C5lk1MnM-1647442360819)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220305221806860.png)]
break continue
break会终止某个循环,用于强制退出循环;可以存放在任意主体部分
continue用于终止某次循环,可以继续执行下一句的循环。只在循环中使用。
二、JAVA方法
1、何为方法
方法是语句的集合,在一起执行一个功能。
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
2、方法调用
调用方法:对象名.方法名(实参列表)
int larger=max(30,40);
JAVA是值传递;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fuZTpS9B-1647442360821)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220311165340747.png)]
3、方法重载
在一个类中,有相同的函数名称,但是参数不同。
public class Demo04 {
public static void main(String[] args) {
int sum = sum(1, 2);
System.out.println(sum);
int sum1 = sum(1, 2, 3);
System.out.println(sum1);
}
public static int sum(int a,int b){
return a+b;
}
public static int sum(int a,int b,int c){
return a+b+c;
}
}
4、可变参数(不定项参数)
在方法声明中,在指定参数类型后面加一个省略号(…)。一个方法只能指定一个可变参数,必须是最后一个参数。
public class Demo05 {
public static void main(String[] args) {
Demo05 demo05 = new Demo05();
demo05.test(1,2,3);
}
public static void test(int x,int... i){
System.out.println(x);
System.out.println(i[0]);
System.out.println(i[1]);
}
}
5、递归(重点)
自己调用自己。
6、方法的调用
静态方法:有static,直接声明方法名就可
static是和类一起加载的
package com.oop;
public class demo02 {
//静态方法,有static
public static void say(){
System.out.println("学生说话了");
}
}
package com.oop;
public class demo01 {
public static void main(String[] args) {
//静态方法,直接调用方法名就可
demo02.say();
}
}
非静态方法:无static,需要实例化这个类new
类实例化之后才会存在
package com.oop;
public class demo01 {
public static void main(String[] args) {
//静态方法,直接调用方法名就可
demo02.say();
//非静态方法,需要实例化这个类
demo02 demo02 = new demo02();
demo02.sayy();
}
}
package com.oop;
public class demo02 {
//静态方法,有static
public static void say(){
System.out.println("学生说话了");
}
//非静态方法,无static
public void sayy(){
System.out.println("闭嘴");
}
}
三、数组
相同类型的有序集合。数组下标从0开始。
1、数组的声明创建
int[] num;//第一种定义(首选方法)
int nums[];//第二种定义,和c的写法相同
//使用new关键字来创建数组;
使用new关键字来创建数组;
public class Demo01 {
//变量类型 变量名字=变量值;
//数组类型
public static void main(String[] args) {
int[] num;//第一种定义(首选方法) 声明数组
//int nums[];第二种定义,和c的写法相同
//使用new关键字来创建数组;
num=new int[3];//可以存放10个int类型的数字,开辟空间
//赋值
num[0]=1;
num[1]=2;
num[2]=3;
int sum=0;
for(int i=0;i<num.length;i++){
sum=sum+num[i];
}
System.out.println(sum);
}
}
输出结果:6
声明和创建可以写一起
int[] num;//声明
num=new int[10];//创建
等价于
int[] num=new int[10];//声明加创建
2、内存分析
Java内存:
1、堆
存放new的对象和数组,后创建,再给数组元素赋值,
2、栈
存放变量的类型,先声明
3、方法区
3、数组的初始化状态
public class demo02 {
public static void main(String[] args) {
//静态初始化,创建+赋值, 基本类型
int[] a={1,2,3,4,5,6,7};
System.out.println(a[0]);
//动态初始化:包含默认初始化
int[] b=new int[10];
b[0]=10;
System.out.println(b[0]);
System.out.println(b[1]);//输出结果为0
}
}
数组中的元素可以是基本类型也可以是引用类型。
数组对象本身在堆中
数组也是一个对象。
4、数组的使用
普通for循环
for each循环,取不到下标
输入array.for,回车
public class demo03 {
public static void main(String[] args) {
int[] array={1,2,3,4,5};
//增强型循环 for(数组中的元素:数组) 没有下标
for (int i : array) {
System.out.println(i);
}
}
}
数组可以作为参数
public class demo03 {
public static void main(String[] args) {
int[] array={1,2,3,4,5};
printArray(array);
}
public static void printArray(int[] array){
for(int i=0;i< array.length;i++){
System.out.print(array[i]+" ");
}
}
}
二维数组
int[][] array={{1,2},{2,3},{3,4}};//三行两列
5、Array类
在java.util.Arrays包中
有个Arrays.toString()类,可以打印数组元素
public class demo04 {
public static void main(String[] args) {
int[] a={1,433,546,222,456,99};
System.out.println(a);
//打印数组元素 Arrays.toString()
System.out.println(Arrays.toString(a));
}
}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c6cg0iWI-1647442360826)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312162650936.png)]
排序:Arrays.sort()方法,升序排序
public class demo04 {
public static void main(String[] args) {
int[] a={1,433,546,222,456,99};
System.out.println(a);
//打印数组元素 Arrays.toString()
Arrays.sort(a);
System.out.println(Arrays.toString(a));
}
}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eZUhhzI9-1647442360827)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312162854982.png)]
冒泡排序
一种排序算法,八大排序之一
时间复杂度O(n^2)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9WMxiKfH-1647442360827)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312163938536.png)]
可以优化,设置一个flag
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JJH8qIds-1647442360828)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312164039926.png)]
稀疏数组
是一种数据结构,可以压缩算法
记录数组有几行几列,把不同元素的行列记录在一个小规模的数组中
三元组(行,列,值)
四、面向对象
面寻对象编程OOP的本质:以类的方式组织代码,以对象的组织(封装)数据。
抽象
三大特性:封装、继承、多态
修饰符 属性类型 属性名=属性值
1、类和对象的关系
类是一种抽象的数据类型
对象是抽象概念的具体实例。
**使用new创建对象。**创建对象时,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
package com.oop.demo;
//学生类
public class Student {
//属性:字段
String name;//null
int age;
//方法
public void study(){
System.out.println(this.name+"在学习");//当前的name
}
}
package com.oop.demo;
public class Application {
public static void main(String[] args) {
//类是抽象的,需要实例化
//类实例化之后,会返回自己的对象xiaoming、xiaohong
Student xiaoming = new Student();
Student xiaohong = new Student();
xiaoming.name="小明";
xiaoming.age=11;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
xiaohong.name="小红";
xiaohong.age=12;
System.out.println(xiaohong.name);
System.out.println(xiaohong.age);
}
}
2、构造器(必须掌握)
构造器(构造方法):必须和类的名字相同,必须没有返回类型,也不能写void。
构造器核心作用:
1、使用new,必须要有构造器,本质实在调用构造器
2、用来初始化值
定义有参构造器,必须有无参构造器,把无参空着就行
package com.oop.demo03;
public class Person {
// 一个类即使什么都不写,也会有构造器
String name;
/*构造器核心作用:
1、使用new,必须要有构造器,本质实在调用构造器
2、用来初始化值
* */
// 无参构造器
public Person(){
}
//有参构造:一旦定义了有参构造,无参就必须显示定义
//定义有参,必须有无参,把无参空着就行
public Person(String name){
this.name=name;
}
}
package com.oop.demo03;
public class Application {
public static void main(String[] args) {
//使用new实例化了一个对象
Person person = new Person("lxx");
System.out.println(person.name);
}
}
alt+insert快捷键,生成构造器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D2ONBHii-1647442360829)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312205952865.png)]
选择ok,生成有参构造器;选择Select None生成无参构造器
内存解析:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWKbOgDb-1647442360830)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312211254473.png)]
3、三大特性(封装、继承、多态)
程序追求高内聚,低耦合。
封装:
数据的隐藏。
一般属性才是私有的
属性私有(private),get/set
//属性私有
private String name;//姓名
private int id;//学号
private char sex;//性别
使用public的get(获得属性) set(给属性设置值)方法
举例:
package com.oop.demo04;
public class Student {
//属性私有
private String name;//姓名
private int id;//学号
private char sex;//性别
//提供一些可以操作这个属性的方法
//public的get(获得属性) set(给属性设置值)方法
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
}
package com.oop.demo04;
public class application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("lxx");
System.out.println(s1.getName());
}
}
alt+insert可以自动生成get、set方法
alt+insert之后,选择getter and setter,选择属性就可自动创建get、set方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mtSftNIh-1647442360831)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312214945449.png)]
封装的好处:
1、提高程序的安全性,保护数据
2、隐藏代码的实现细节
3、统一接口
4、提高系统的可维护性
继承(extends)
继承的本质是对某一批类的抽象,extends就是扩展的意思。子类就是父类的扩展。继承是类和类之间的关系。
Java中只有单继承,不能多继承。
父类(基类)——>子类(派生类)
子类可以继承父类的所有方法
Person.java
package com.oop.demo05;
public class Person {
private int money=10;
public void say(){
System.out.println("说话");
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
Student.java
package com.oop.demo05;
//学生 继承 人
//子类继承了父类,可以拥有父类的全部方法
public class Student extends Person{
}
application.java
package com.oop.demo05;
public class application {
public static void main(String[] args) {
Student student = new Student();
student.say();
student.setMoney(100);
System.out.println(student.getMoney());
}
}
输出结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d97POYT7-1647442360832)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220312225000911.png)]
在Java中,所有的类,都默认直接或者间接继承Object类
super
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZU2KGrOQ-1647442360834)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220313101448528.png)]
父类中有属性name,子类中也有属性name,
在子类中,this.name调用的是子类本身的name,若想调用父类中的name,使用super.name即可(不能是private)
System.out.println(super.name);
this指向当前类,super指向父类
私有的东西无法被继承
调用父类的构造器,必须在子类的第一行
super和this的区别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iwdou93T-1647442360834)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220313102801340.png)]
方法的重写:(前提:需要有继承关系,子类重写父类的方法)
重写都是方法的重写,和属性无关
1、方法名必须相同
2、参数列表相同
3、修饰符:范围可以扩大:public>protected>defualt>private
4、抛出的异常:范围可以被缩小,担不能扩大:ClassNotFoundException<Exception
重写:子类的方法必须和父类一致,但方法体不同
非静态方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIu5ZS5h-1647442360835)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220313104408354.png)]
静态方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jLwNhfo5-1647442360836)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220313104504125.png)]
快捷键:Alt+Insert->override(自动重写)
多态
即同一个方法可以根据发送对象的不同而采用不同的行为方式。
多态是方法的多态
动态编译:类型:增强可扩展性。只有在执行过程中才可以决定。
对象能执行哪些方法,主要看对象的左边,和右边关系不大
public class Person{}
public class Student extends Person{}
Student s1=new Student();
Person s2=new Student();
Object s3=new Student();
子类重写了父类的方法,执行子类的方法
例:
Person.java
public class Person{
public void run(){
System.out.println("person");
}
}
输出:(子类重写了父类的方法,执行子类的方法)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xgBNi1VL-1647442360839)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220313110747139.png)]
子类调用的方法都是自己的或者继承的
父类可以指向子类,但是不能调用子类的独有的方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R9DGEQog-1647442360842)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220313111846252.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PxNm3vjh-1647442360843)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220313112024811.png)]
instanceof
instanceof(类型转换):引用类型之间的转换
instanceof可以判断两个类之间是否存在父子关系:
//Object>Person>Teacher=Student
//Object>String
Object object = new Student();
System.out.println(object instanceof Student);
System.out.println(object instanceof Person);
System.out.println(object instanceof Object);
System.out.println(object instanceof Teacher);
System.out.println(object instanceof String);
输出结果:
true
true
true
false
false
所以,X instanceof Y是否能够通过,取决于XY之间是否有父子关系
引用类型之间的强制转换
//高 —> 低
Person a = new Student();
//将a转化为Student类型,就可以使用Student中的go()方法了
Student student=(Student)a;
student.go();
1、父类引用指向子类对象
2、把子类转化为父类,向上转型
3、把父类转化为子类,向下转型,强制转换
4、方便方法的调用,减少重复的代码
4、static
静态变量,可以直接使用类名来访问
public class Student{
private static int age;//静态变量,静态属性
private double score;
public static void main(String[] args){
Student s1=new Student();
System.out.println(Student.age);
//静态变量,可以直接用Student类来引用
System.out.println(s1.age);
System.out.println(s1.score);
}
}
非静态的方法可以去调用静态方法中的所有东西
public class Student{
private static int age;//静态变量,静态属性
private double score;
public void run(){
}
public static void go(){
}
public static void main(String[] args){
go();
}
}
代码块:
public class Person{
//第2执行,可以用来赋初始值
{
System.out.println("匿名代码块");
}
//1 最早执行,和类一块加载,但只执行一次
static{
System.out.println("静态代码块");
}
//3
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args){
Person person1 = new Person();
System.out.println("==========");
Person person2 = new Person();
}
}
执行结果:
静态代码块
匿名代码块
构造方法
==========
匿名代码块
构造方法
静态导入包:
import static java.lang..Math.random;
5、抽象类
abstract修饰,抽象方法,只有方法的名字,没有方法的实现
public abstract void doSomething();
抽象类的所有方法,继承他的子类,要重新实现(重写)那些方法,除非继承他的子类也是抽象类,就需要子子类去再一次实现方法。
public abstract class Action{
public abstract void doSomething();
}
特点:就是一个约束!
1、不能new,只能考子类去实现它
2、抽象类中可以写普通的方法
3、抽象方法必须在抽象类中
6、接口
声明接口的关键字:interface
接口只有规范(抽象方法),没有具体实现。接口中的所有定义都是抽象的(public abstract)。
可以实现约束和接口分离:面向接口编程
接口的本质是契约。接口中没有构造方法,接口压根不是类。
接口:
public interface UserService{
//默认为public abstract,
//public abstract void add(String name);
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface TimeService{
void timer();
}
接口都需要有实现类
类用implements实现接口,抽象类:extends
实现类(一般以Ipml结束):
实现了接口的类,就需要重写接口中的方法
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(){ }
}
所以,接口可以实现多继承
接口中都是常量:
int age=99;
默认为:
public static final int age=99;
6、内部类
内部类:在一个A类的内部再定义一个B类。B相对于A来说,就是内部类。
内部类可以访问外部类的私有变量
public calss Outer{
private int id=10;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性
public void getId(){
System.out.println(id);
}
}
}
import com.oop.demo01.Outer;
public class Application{
public static void main(String[] args){
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner=outer.new Inner();
inner.getID();
}
}
输出结果:
10
静态内部类:
public static class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//此时不能再访问外部非静态的属性了,即不能获得id,除非id也是static
}
一个.java中只能由一个public class,但是可以有多个class类
五、异常机制Exception
1、异常介绍
文件找不到,非法参数等等
例如:
11/0,0不能当作除数,报异常:ArithmeticException
JAVA当中把异常当作对象处理,并定义一个基类java.lang.Throwable作为所有异常的超类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qE4Ul5Qb-1647442360843)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20220316214900022.png)]
注:只表明了部分异常,不代表全部
2、异常处理机制
抛出异常
捕获异常
五个关键字:try、catch、finally、throw、thows
public class One{
public static void main(String[] args){
int a=1;
int b=0;
try{//try监控区域
System.out.println(a/b);
}catch(ArithmeticException e){//catch(想要捕获的异常类型,最高是Throwable)捕获异常
System.out.println("程序出现异常,变量b不能为0");
}finally{//善后
System.out.println(finally);
}
}
}
输出结果:
程序出现异常,变量b不能为0
finally
try catch必须要,可以写多个catch,最大的异常写在最下面的catch中,可以不要finally,假设IO、资料等等,需要关闭的操作,可以写在finally中
**快捷键:选中行代码,ctrl+alt+t,**选择需要生成的异常捕获代码即可
主动抛出异常:throw(方法里面) throws(方法上)
public class One{
public static void main(String[] args){
int a=1;
int b=0;
try{
if(b==0){//主动抛出异常
throw new ArithmeticException();
}
System.out.println(a/b);
}catch(Exception e){
System.out.println("Exception");
}catch(Throwable e){
System.out.println("Throwable");
}finally{
System.out.println("finally");
}
}
}
public void test(int a,int b) throws ArithmeticException{
}
try{//try监控区域
System.out.println(a/b);
}catch(ArithmeticException e){//catch(想要捕获的异常类型,最高是Throwable)捕获异常
System.out.println("程序出现异常,变量b不能为0");
}finally{//善后
System.out.println(finally);
}
}
}
输出结果:
程序出现异常,变量b不能为0
finally
try catch必须要,可以写多个catch,最大的异常写在最下面的catch中,可以不要finally,假设IO、资料等等,需要关闭的操作,可以写在finally中
**快捷键:选中行代码,ctrl+alt+t,**选择需要生成的异常捕获代码即可
主动抛出异常:throw(方法里面) throws(方法上)
```java
public class One{
public static void main(String[] args){
int a=1;
int b=0;
try{
if(b==0){//主动抛出异常
throw new ArithmeticException();
}
System.out.println(a/b);
}catch(Exception e){
System.out.println("Exception");
}catch(Throwable e){
System.out.println("Throwable");
}finally{
System.out.println("finally");
}
}
}
public void test(int a,int b) throws ArithmeticException{
}
自定义异常:79