java学习笔记(二)--数组、数据类型转换、类和对象、类的方法、抽象和封装、常用快捷键、编程规范

50 阅读15分钟

1.java 数组理解

  • 变量的类型不同,决定了变量在内存上占有的空间大小的不同。

  • 数组是一组数据的集合

  • 数组作为一种引用类型,申请的空间在堆中

  • 数组元素的类型可以是基本类型,也可以是引用类型,但同一个数组只能是同一种类型

  • 数组作为对象,数组中的元素作为对象的属性,除此之外数组还包括一个成员属性 length, length 表示数组的长度

  • 数组的长度在数组对象创建后就确定了,就无法再修改了

    • 数组长度不可变,那么数组怎么扩容呢?

    • 原数组满了之后,可以新建一个新的容量更大的数组,将原数组中的数据拷贝到新数组中,原数组对象被 GC 回收,以后向新数组中存储数据。这就是数组的扩容。

  • 数组元素是有下标的,下标从 0 开始,也就是第一个元素的下标为 0,依次类推最后一个元素的下标为n-1,我们可以通过数组的下标来访问数组的元素

  1. 小例子:求数组最大值
package cn.java.day01;

import java.util.Scanner;
//求数组最大值
public class T07 {
    public static void main(String[] args) {
        //    数组求最大值
        int[] score = new int[5];
        Scanner input = new Scanner(System.in);
//    赋值循环
        for (int i = 0; i < score.length; i++) {
            score[i] = input.nextInt();
        }
//        默认第0项为最大值
        int max = score[0];
        for (int i = 1; i < score.length; i++) {
            if (score[i] > max) {
                max = score[i];
            }
        }
//        max最大值
        System.out.println(max);
    }

}

2.数组排序


package cn.java.day01;

//导入工具类
import java.util.Arrays;

public class T08 {
    public static void main(String[] args) {
//        数组排序
        int[] nums = {2, 7, 99, 9, 77};
//        实现数组升序排序
        Arrays.sort(nums);
        
    }
}
  1. 数组的插入
package cn.java.day01;

import java.util.Scanner;

public class T09 {
    public static void main(String[] args) {
//        数组插入元素
        int[] nums = {2, 42, 61, 77, 79, 90, 100};
        Scanner input = new Scanner(System.in);
//       定义变量来保存新插入的的分数
        int score = input.nextInt();
//        找到插入元素的位置
        int index = nums.length - 1;
        for (int i = 0; i < nums.length; i++) {
            if (score < nums[i]) {
                index = i;
                break;
            }
        }
//      元素后移
        for (int j = nums.length - 1; j > index; j--) {
            nums[j] = nums[j - 1];

        }
//        重新赋值
        nums[index] = score;
//        打印新的数组结果
        for (int i = 0; i <nums.length ; i++) {
            System.out.print(" "+nums[i]);
        }
    }
}

2.java引用类型和值类型

二维数组 与一维数组相同
Java中内存图:栈内存、堆内存、方法区。

  • 栈内存:保存的是执行方法、运行方法(例如主方法)。
  • 堆内存:保存的是具体的对象、数组等。
  • 代码中带 new的就会在堆内存中开辟空间。
  1. 四类八种--基本数据类型
    基本数据类型只有8种,可按照如下分类
    ①整数类型:long、int、short、byte
    ②浮点类型:float、double
    ③字符类型:char
    ④布尔类型:boolean
  • 基本类型只是栈栈上存空间
  1. 引用类型
  • 引用类型是堆和栈都要占空间。

image.png 引用数据类型非常多,大致包括:类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型
例如,String类型就是引用类型,还有Double,Byte,Long,Float,Char,Boolean,Short(注意这里和基本类型相比首字母是大写)
简单来说,所有的非基本数据类型都是引用数据类型

3.数据类型转换

Java中的数据转换主要分为两种:自动类型转换(也称为隐式转换)、强制类型转换(也称为显式转换)。

转换从低级到高级:byte、short、char(三者同级)——> int ——> long ——> float ——> double

  • 自动类型转换:代码无需任何处理,在代码编译时 编译器会自动进行处理。特点——低级转换高级
  • 强制类型转换:需要在待转换数据类型前 使用 (type)value, type是要强制类型转换后的数据类型,可能会导致溢出或损失精度 。特点——高级转换低级

数据类型转换必须满足如下规则

  • 不能对boolean类型进行类型转换。
  • 不能把对象类型转换成不相关类的对象。
  • 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
  • 转换过程中可能导致溢出或损失精度,
    • 例如: int i = 128; byte b = (byte)i; 因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
  • 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,
    • 例如: (int)23.7 == 23; (int)-45.89f == -45;

int 和 long 互转、int和double互转、int和byte互转、int和char互转、int和String互转

package cn.java.day01;

public class T02 {
    public static void main(String[] args) {
        int aInt = 20;
        long bLong = 50L;
        double cDouble = 4.8;

        //低优先级类型数据 + 高优先级类型数据 ——> 结果会自动转换为高优先级数据
        long sum = aInt + bLong;

        //long -> int 需要强制类型转换
        int d = (int) bLong;
        //double -> int 需要强制类型转换
        int e = (int) cDouble;

        System.out.println("自动类型转换 int—>long:  " + sum);
        System.out.println("强制类型转换 long—>int:  " + d);
        System.out.println("强制类型转换 double—>int:  " + e);
        System.out.println();


        //int 和 byte 转换
        byte fByte = (byte) aInt;  //高转低,强转
        int gInt = fByte;          //低转高,自动
        System.out.println("高转低-强转,int->byte:  " + fByte);
        System.out.println("低转高-自动,byte->int:  " + gInt);
        System.out.println();

        //int 和 char 转换
        char hChar = 'a';
        int iInt = hChar;
        char j = (char) iInt;
        System.out.println("低转高-自动,char->int:  " + iInt);
        System.out.println("高转低-强转,int->char:  " + j);
        System.out.println();

        //int 和 String 转换
        //int转String: 1)使用String的ValueOf方法   2)直接使用 String类+ (即字符串拼接),任意字符串和其他类型"+" 都会把其他类型转为字符串
        String str1 = String.valueOf(aInt);
        String str2 = "" + aInt;
        System.out.println("int转String: " + str1 + ",  " + str2);
        //String转int:调用包装类的Integer.parseInt方法,当字符串中包含非数字时会出错
        String str3 = "18";
        int k = Integer.parseInt(str3);
        System.out.println("String转int: " + k);
        System.out.println();

        //byte 和 char 互转
        byte m = (byte) hChar;
        char n = (char) m;
        System.out.println("char->byte,强转:  " + m);
        System.out.println("byte->char,强转:  " + n);
    }
}

Java的八种基本类型:(按字节来分)

boolean   布尔型   1个字节 8bit(8位)

byte     字节类型   1个字节

char     字符类型   2个字节

short     短整型     2个字节

int          整型        4个字节

float      浮点型(单精度)4个字节

long      长整型      8个字节

double   双精度类型  8个字节

Java中默认的整数类型是int,如果要定义为long ,则要在数值后加上L或者l

默认的浮点型是双精度浮点,如果要定义float,则要在数值后面加上f或者F

一个字节等于8位,1个字节等于256个数。2^8

一个英文字母或者阿拉伯数字占一个字节

一个汉字占2个字节

4. 类和对象

类是具有相同属性和行为的一系列事物的集合。对象现实生活中看得见,摸得着的具体的事务。

  • 关系:类是对象的模版,对象是类的实例
  1. 类的定义
public class Dog {
    //   静态属性
    String name;//名称
    int age;//年龄
    //    动态属性 行为 方法
    public void sayHello() {
        System.out.println("我的名字是" + name + ",我今年" + age + "岁了");
    }
}
  1. 类的调用
package day08.t01;

import day08.t01.Dog;

public class T01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name="小黑";
        dog.age=9;
        dog.sayHello();
    }
}
  1. 简单登录demo

image.png 用户自定义的类型也是一种数据类型

  • 对象数组: UserInfo[] users = new UserInfo[50]; image.png
  • 在java中需要判定两个字符串是否相同,得使用equals()
  • String,数组,以及自定义类都是引用类型。
package day08.t03;
//定义一个用户类
//用户定义的类也是一种类型,属于引用类型
public class UserInfo {
    String username;
    String pssword;//密码
}

登录代码

package day08.t03;


import java.util.Scanner;

public class T01 {
    public static void main(String[] args) {
//        写一个面向对象的登录程序
//        users数组的每一项都是一个用户对象
        UserInfo[] users = new UserInfo[50];
//        创建一个UserInfo的对象
        UserInfo info = new UserInfo();
        info.username = "fly";
        info.pssword = "123456";
        users[0] = info;

//        用户输入的用户名
        Scanner input = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String uname = input.next();

        //        用户输入的密码
        System.out.println("请输入密码:");
        Scanner upwd = new Scanner(System.in);
        String pwd = upwd.next();

//        默认登录失败
        boolean flag = false;
//        如何判定用户是否登录成功
        for (int i = 0; i < users.length; i++) {
//            在java中判定两个字符串是否相等,使用equals()
            if (users[i] != null && users[i].username.equals(uname) && users[i].pssword.equals(pwd)) {
                flag = true;
                break;
            }
        }
        if(flag){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败!");
        }
    }
}

image.png

image.png

5. 全局变量(成员变量)与局部变量

  • 在方法体中声明的变量叫做:局部变量。在方法中定义的变量,出了这个方法{}他就死亡了。方法结束后内存空间就会结束和释放。
  • 在方法体外声明的变量叫做:全局变量。全局变量在类中定义的变量,他不属于任何一个方法。所有的方法都可以共性(读取值,修改值),并且全局变量不赋初值,系统会给默认值。

image.png

6. 类的方法

6.1 带参方法

image.png

6.2 数组作为参数

image.png

6.3 对象作为参数

目录结构如下:

image.png

image.png T06代码如下:

package day09.t06;

import java.util.Scanner;

public class T06 {
    public static void menu() {
        System.out.println("欢迎来到图书管理系统~");
        System.out.println("1、图书列表");
        System.out.println("2、添加图书");
        System.out.println("0、退出系统");
        System.out.println("请输入对应的操作:输入数字既可");
    }

    public static void main(String[] args) {
        BookManger bookManger = new BookManger();
        bookManger.initBoooks();
        menu();
        Scanner input = new Scanner(System.in);
        int num = input.nextInt();
        while (num != 0) {//0退出程序
            if (num == 1) {
                bookManger.booklist();
                menu();
                num = input.nextInt();
            } else if (num == 2) {
//            添加图书
                Book book = new Book();
                System.out.println("这里是添加图书界面");
                System.out.println("请输入图书名称");
                book.bookname = input.next();
                System.out.println("请输入图书作者");
                book.bookauthor = input.next();
                System.out.println("请输入图书价格");
                book.price = input.nextInt();
                boolean flag = bookManger.addBook(book);
                if (flag == true) {
                    System.out.println("添加成功~");
                } else {
                    System.out.println("添加失败!");
                }
                menu();
                num = input.nextInt();
            } else if (num == 0) {
                break;
            }
        }
        System.out.println("感谢使用该系统");
    }
}

BookManger代码如下:

package day09.t06;

public class BookManger {
    //   维护一个数组,数组的类型,图书类型,对象数组
    Book[] books = new Book[50];

    public void initBoooks() {
//        构建一个图书对象
        Book book = new Book();
        book.bookname = "唐诗";
        book.bookauthor = "李白";
        book.price = 35;

//        图书对象和数组books进行关联绑定
        books[0] = book;

        Book book2 = new Book();
        book2.bookname = "宋词";
        book2.bookauthor = "辛弃疾";
        book2.price = 36;
        books[1] = book2;
    }

    //    book[0].bookname
//图书列表
    public void booklist() {
        System.out.println("这是图书列表");
        System.out.println("书名\t\t\t\t作者\t\t价格");
        for (int i = 0; i < books.length; i++) {
            if(books[i]!=null){
                System.out.println(books[i].bookname + "\t\t"
                         + books[i].bookauthor + "\t\t" + books[i].price
                );
            }

        }
    }

    //    添加图书的方法
    public boolean addBook(Book book) {
        boolean flag=false;
        for (int i = 0; i < books.length; i++) {
//            判断对象是否为空,和null进行比较
            if (books[i] == null) {
                books[i] = book;
                flag=true;//添加成功~
                break;
            }
        }
        return  flag;
    }

}
                                                                                                        

7. 抽象和封装

7.1 类的提炼

从现实生活中总结出多种相同物种,具有的相同的特性(属性+行为)提炼到一个容器里,给这个类起一个名字,名字就是类

    1. 发现类(Dog)
    1. 发现类的属性(毛色,品种)
  • 3.发现类的方法(跑,叫)

设计优于编码

image.png

构造方法:主要完成对象的创建工作

image.png

方法重载(overload):有多个方法,他们实现的功能相同(不用为起方法名而头疼),方法名称相同,但是参数列表不同。 包含三重含义:

  • 参数的个数不同
  • 参数的类型不同
  • 参数的顺序不同

与返回值与访问修饰符无关

image.png 个数相同,类型不同,也可以方法重载。 image.png 普通方法可以实现重载,构造方法也可以重载。他们也可以构成重载的条件是他们的参数的顺序不同。如下:

image.png

7.2 static

  1. 直接使用类名直接访问类的属性和方法

image.png

在类中,用static声明的成员变量为静态成员变量,也成为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。

这里要强调一下:

  • static修饰的成员变量和方法,从属于类
  • 普通变量和方法从属于对象
  • 静态方法不能调用非静态成员,编译会报错

static关键字的用途 一句话描述就是:方便在没有创建对象的情况下进行调用(方法/变量)。

显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。

static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能。

image.png 静态成员变量占用的内存是静态存储区,而且一个成员一旦变成静态的,他就是类本身所有,只有一份和对象没有关系了。它会一直生存到程序结束。所以不能将所有的变量都定义到静态存储区。

  1. 静态代码块 JVM加载类时,加载静态代码块
  • 如果有多个静态块,按顺序加载
  • 每个静态代码块只会执行一次

image.png 静态方法中,不能访问非静态的

image.png static变量和传统的类属性变量有什么区别吗?

主要有以下几点:

  • static修饰的变量是属于整个类所有,而不是某个对象所有。
  • static修饰的变量可以被所有对象所共享,普通的类变量只能被定义该变量的对象共享。
  • static修饰的变量可以直接用类名调用,而普通的类变量则需要通过实例调用。

7.3 封装

封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体

数据被保护在类的内部,尽可能地隐藏内部的实现细节,只保留一些对外接口使之与外部发生联系。

其他对象只能通过已经授权的操作来与这个封装的对象进行交互。也就是说用户是无需知道对象内部的细节(当然也无从知道),但可以通过该对象对外的提供的接口来访问该对象。

使用封装有 4 大好处:

  • 1、良好的封装能够减少耦合。
  • 2、类内部的结构可以自由修改。
  • 3、可以对成员进行更精确的控制。
  • 4、隐藏信息,实现细节。
  1. 使用封装的过程
  • 将属性的可见性,设置为private
  • 创建公有的getter和seteer方法
  • 在getter和setter方法中加入判断语句

2.封装的两种体现

  • 一个类中可以出现成员变量和方法
  • 将私有的成员变量封装公有的get和set方法

image.png

案例练习,实现一个Car类,帮助理解

image.png

package day10.t07;

public class T07 {
    public static void main(String[] args) {
        Car car = new Car("吉利", "星越", 2024);
        car.setMile(200);
        car.show();
    }

}
package day10.t07;

public class Car {
//    属性

    //    品牌
    String brand;
    //    型号
    String model;
    //    生产年份
    int year;
    //    行驶的里程数
    private int mile;

    public int getMile() {
        return mile;
    }

    public void setMile(int mile) {
        this.mile = mile;
    }

    //    两个构造方法
    public Car() {

    }

    //带三个参数的构造
    public Car(String brand, String model, int year) {
        this.brand = brand;
        this.model = model;
        this.year = year;
    }

    public void show() {
        System.out.println("车的品牌:" + this.brand);
        System.out.println("车的型号:" + this.model);
        System.out.println("车的生产年份:" + this.year);
        System.out.println("车的里程数:" + this.mile);

    }


}
  • 封装

封装是把数据和操作数据的方法封装在一起,将对象的属性和行为封装到一个对象中,是面向对象编程的一个基本特性。

  • 继承

继承是指一个类可以从另一个已存在的类中继承其属性和行为,也可以在继承的基础上增加自己特有的属性或行为,使得子类具有超越父类的功能。

  • 多态

多态是指一个事物可以具有多种形态,即一个对象可以根据不同的情况具有不同的形态,也就是说在不同的时刻可以表现出不同的行为。

8. 常用快捷键

  • IntelliJ IDEA格式化快捷键: 按下 Ctrl + Alt + L 格式化代码。
  1. 快捷键
  • sout 快速生成
System.out.println("");
  • psvm快速生成
public static void main(String[] args) {
}
  • 快速创建getter和setter,按Alt+enter

private  int age;

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

Ctrl系列快捷键

  • Ctrl + Y: 删除当前行。
  • Ctrl + D: 复制当前行,并插入到下一行。
  • Ctrl + W: 选中文本,连续按可以扩大选中范围。
  • Ctrl + F: 在当前文件中查找文本。
  • Ctrl + R: 查找并替换文本。
  • Ctrl + N: 快速搜索和打开类。
  • Ctrl + O: 快速重写基类或者接口中的方法。

Alt系列快捷键

  • Alt + Enter: 快速提示完成,在代码存在语法问题时,IDEA会提示使用该快捷键自动修正语法。
  • Alt + Insert: 快速生成含有任意形参的构造器和私有属性的Getter/Setter等方法。
  • Alt + 1: 快速打开或隐藏Project面板。

Shift系列快捷键

  • Shift + Enter: 在当前行下面生成一行空行,光标自动移到空行行首。
  • Shift + F6: 批量修改变量名,先选中变量名,然后点击快捷键。

Ctrl + Alt系列快捷键

  • Ctrl + Alt + L: 快速格式化代码。
  • Ctrl + Alt + O: 优化导入的类和包。
  • Ctrl + Alt + T: 将选中的代码使用if、while、try/catch等代码块包装起来。

Ctrl + Shift系列快捷键

  • Ctrl + Shift + F10: 快速运行当前的程序。
  • Ctrl + Shift + J: 快速整合两行代码,将光标所在行和下一行的代码合并成一行。

9. 常用编程规范

package的命名:  package 的名字由全部小写的字母组成,例如:com.runoob。

class和interface的命名:  class和interface的名字由大写字母开头而其他字母都小写的单词组成,例如:Person,RuntimeException。

class变量的命名:  变量的名字用一个小写字母开头,后面的单词用大写字母开头,例如:index,currentImage。

class 方法的命名:  方法的名字用一个小写字母开头,后面的单词用大写字母开头,例如:run(),getBalance()。

staticfinal变量的命名:  static final变量的名字所有字母都大写,并且能表示完整含义。例如:PI,PASSWORD。

参数的命名:  参数的名字和变量的命名规范一致。

数组的命名:  数组应该总是用这样的方式来命名:byte[] buffer。