JAVA笔记

参考链接:【狂神说Java】Java零基础学习视频通俗易懂_哔哩哔哩_bilibili

基础

注释

//单行注释
/*
第1行注释
第2行注释
···
第n行注释
*/  多行注释
​

标识符

关键字

标识符注意点

  • 所有标识符都应该以 字母、$(美元符)、_(下划线) 开头

  • 首字母之后可以是 字母、$、_ 或数字任何字符组合

  • 关键字不能作为变量名或方法名

  • 标识符大小写敏感

  • 可以用中文命名,但不建议使用,即使用拼音命名也Low

数据类型

  • 强类型语言

    • 要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用

  • 弱类型语言:JavaScript,Python

  • Java的数据类型分为两大类

    • 基本类型(primitive type),有8大基本类型,此外都是引用类型

    • 引用类型(reference type)

在这里插入图片描述

        //整数
        int num1 = 10;
        byte num2 = 20;
        short num3 = 30;
        long num4 = 40;
​
        //小数:浮点数
        float num5 = 50.1F;  //float类型要在数字后面加个F
        double num6 = 3.14159;
​
        //字符
        char name = 'A';
​
        //字符串,String不是关键词,类
        String namea = "张三";
​
        //布尔值:是非
        boolean flag = true;
        boolean fLag = false;

什么是字节

  • 位(bit):是计算机内部数据存储的最小单位,11001100是一个八位二进制数

  • 字节(byte, B):是计算机中 数据处理 的基本单位,习惯上用大写B表示

  • 1B(byte) = 8bit,1字节等于8位

  • 字符:指计算机中使用的字母,数字,字和符号

    • 1bit表示1位

    • 1Byte表示一个字节 1B=8b

    • 1024B = 1KB, 1024KB = 1M, 1024M = 1G

扩展及面试题

        //整数拓展:     二进制0b   八进制0    十进制     十六进制0X
        int i = 10;
        int i2 = 010; //八进制 8
        int i3 = 0x10; //十六进制 16
        System.out.println(i); //10
        System.out.println(i2); //8
        System.out.println(i3);//16
        System.out.println("================");
​
        //浮点数拓展:
        //面试题: 银行业务字母怎么表示钱? BigDecimal(数学·工具类)
        //float double 是有问题的,最好避免使用浮点数进行比较
        float f = 0.1f;
        double d = 1.0/10;
        System.out.println(f==d);//false
        //浮点数 位有限 舍入误差 大约 接近但不等于
        //最好避免使用浮点数进比较
        float f1 = 23131313131f;
        float f2 = f1+1;
        System.out.println(f1==f2);//ture
        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);
​
        char c3 = '\u0061';
        System.out.println(c3);
​
        //转义字符
        // \t   制表符
        // \n   换行
        //···
        System.out.println("hello\nworld");
        System.out.println("================");
​
        String sa = new String("hello world");
        String sb = new String( "hello world");
        System.out.println(sa==sb);
​
        String sc = "hello world";
        String sd = "hello world";
        System.out.println(sc==sd);
​
        //布尔值:是非
        boolean flag = true;
        if(flag==true){}    //新手
        if (flag){}         //老手

类型转换

  • 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换。

  • 容量高–>低: 在这里插入图片描述

  • 运算中,不同类型的数据先转化位同一类型,再进行运算。

    • 强制转换,(类型)变量名,容量由高到低

    • 自动转换,容量由低到高

        //强制转换 (类型) 变量名 高--低
        //自由转化 低--高
        int i = 128;
        byte b =(byte)i; //强制转换 内存溢出 -128~127
        double d = i; //自由转换
        System.out.println(i); //128
        System.out.println(b); //-128
        System.out.println(d); //128.0
        /*
            注意点:
            1.不能对布尔值进行转换
            2.不能把对象类型转化为不相干的类型
            3.在把高容器转换到低容量的时候,强制转换
            4.可能存在内存溢出,或者精度问题
         */
        System.out.println("===============");
        System.out.println((int)23.7); //23
        System.out.println((int)-45.89f);//-45
​
        System.out.println("===============");
        char c = 'a';
        int e = c+1;
        System.out.println(e); //98
        System.out.println((char)e); //b
        //操作比较大的数的时候,注意溢出问题
        int money = 1000000000;
        int years = 20;
        int total = money*years; //计算的时候已经溢出
        long total2 = money*years; //默认是int,转换之前已经存在问题了
        long total3 = money*(long)years; //先把一个转换为long
        System.out.println(total); //-1474836480
        System.out.println(total2); //-1474836480
        System.out.println(total3); //20000000000

变量、常量、作用域

  • 变量是什么:就是可以变化的量

  • Java是一种强类型语言,每个变量都必须声明其类型

  • Java变量是程序中最基本的存储单元,要素包括变量名,变量类型和作用域

变量作用域

  • 类变量(static)

  • 实例变量

  • 局部变量

//类变量 static
static double salary = 2500;
​
//属性:变量
​
//实例变量:从属于对象;如果不自行初始化,这个类型的默认值
//布尔值:默认是false
//除了基本类型,其余的默认值都是null
String name;
int age;
​
//main方法
public static void main(String[] args) {
​
    //局部变量:必须声明和初始化值
    int i = 10;
    System.out.println(i);
​
    //变量类型  变量名字 = new Demo08();
    Demo08 demo08 = new Demo08();
    System.out.println(demo08.age);
    System.out.println(demo08.name);
​
    //类变量 static
    System.out.println(salary);

常量

  • 常量:初始化后不能再改变的值,不会变动的值。

  • 可以理解为一种特殊的变量,其值被设定后,在程序运行过程不允许被更改。

//修饰符,不存在先后顺序
static final double PI = 3.14;

变量的命名规范

  • 所有变量、方法、类名:见名知意

  • 类成员变量:首字母小写+驼峰原则:lastName

  • 局部变量:首字母小写+驼峰原则

  • 常量:大写字母和下划线:MAX_VALUE

  • 类名:首字母大写+驼峰原则:Man,GoodMan

  • 方法名:首字母小写+驼峰原则:run(),fastRun()

运算符

在这里插入图片描述

        long a = 12341234;
        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

自增自减运算符

        //++    --  自增自减 一元运算符
        int a = 3;

        int b = a++; //执行这行代码后,先赋值给b,再自增
        //a = a + 1;
        System.out.println(a); //4
        //a = a + 1;
        int c = ++a; //执行这行代码前,先自增,再赋值给c
        System.out.println(a); //5
        System.out.println(b); //3
        System.out.println(c); //5

        //幂运算 2^3 = 8
        double pow = Math.pow(2,3);
        System.out.println(pow); //8.0

逻辑运算符

  • && 逻辑与运算:两个变量都为真,结果为true

  • || 逻辑与运算:两个变量有一个为真,结果为true

  • ! 取反,真变为假,假变为真

        //  与(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);
        System.out.println(c);

位运算

        /*
        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
        效率极高!
        <<      *2
        >>      /2

        0000 0000   0
        0000 0001   1
        0000 0010   2
        0000 0011   3
        0000 0100   4
        0000 1000   8
        0001 0000   16
         */
        System.out.println(2<<3); //16
        System.out.println(2>>1); //1

包机制

  • 为了更好地组织类,Java提供了包机制,由于区分类名的命名空间

  • 包的语法格式:

package pkg1[.pkg2[.pkg3...]];
  • 一般利用公司域名倒置作为包名;com.kuangstudy.www

  • 为了能够使用一个包的成员,需要在Java程序中导入该包

import package1[.package2...].(className|*); //通配符* 导入包下所有的类
  • 参考:阿里巴巴Java开发手册

JavaDoc生成文档

  • javadoc命令是用来生成自己API文档的

  • 参数信息

    • @author 作者名

    • @version 版本号

    • @since 指明最早用的jdk版本

    • @param 参数名

    • @return 返回值情况

    • @throws 异常抛出情况

  • API文档:Java Platform SE 8

  1. 打开某个类所在文件夹下的cmd命令行

  2. 输入:javadoc -encoding UTF-8 -charset UTF-8 Doc(类名).java

  3. 会自动生成该类有关的API文档,查看文件夹发现多了一些文件

  4. 打开 index.html(首页)查看文档注释

Java流程控制

用户交互Scanner

  • 之前我们学的基本语法并没有实现程序和人的交互,Java给我们提供了一个工具类,可以获取用户的输入java.util.Scanner是Java5的新特征,我们通过Scanner类来获取用户的输入。

  • 基本语法

Scanner scanner = new Scanner(System.in);
  • 通过Scanner类的 next()与 nextLine()方法获取用户的字符串,读取前一般用hasNext()与hasNextLine()判断是否还有输入的数据。

        //创建一个扫描器对象,用于接受键盘数据
        Scanner scanner = new Scanner(System.in);
        System.out.println("使用next方式接受:");

        //判断用户有没有输入字符串
        if(scanner.hasNext()){
            //使用next方式接受
            String str = scanner.next();
            System.out.println("输入的内容为:"+str);
        }
        scanner.close();

next()

  1. 一定要读取到有效字符才可以结束输入

  2. 对输入有效字符之前遇到的空白,next()方法会将其去掉

  3. 只有输入有效字符后才将其后面输入的空白作为结束符

  4. next()不能得到带有空格的字符串

nextLine()

  1. Enter作为结束符,即返回输入回车之前所有的字符

  2. nextLine()可以获取空白

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入数据:");

        String str = scanner.nextLine();
        System.out.println("输入的数据为"+str);
        scanner.close();
 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("输入的数据不为小数");
        }

        scanner.close();

顺序结构

  • Java的基本结构就是顺序结构,除非特别指明,否则就按语句一条一条执行。

  • 顺序结构是最简单的算法结构。

  • 语句语句之间是按从上到下执行的,它是由若干个依次执行的处理步骤组成的,它是如何一种算法都离不开的一种基本算法结构。

选择结构

  • if单选择结构 if( )

  • if双选择结构 if( ){ }else{ }

  • if多选择结构 if( ){ }else if{ }else{}

  • 嵌套的if结构 if( ){ if( ) }

        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("不1及格");
        }else{
            System.out.println("成绩不合法");
        }
        //case 穿透   switch  匹配一个具体的值
        char grade = 'M';

        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; //可选
            default:
                System.out.println("挂科");
        }

循环结构

  • while循环

        int i =0;
        while(i<100){
            i++;
            System.out.println(i);
  • do…while循环

		int i = 0;
        int sum = 0;
        //先执行后判断,至少执行一次
		do{
            sum = sum + i;
            i++;
        }while(i<=100);
        System.out.println(sum);
  • for循环

        for(int i=0;i<100;i++){
            System.out.println(i);
        }
        //练习1:求1-100内的奇数和,偶数和
        int Jsum = 0;
        int Osum = 0;
        for(int i=0;i<=100;i++){
            if(i%2!=0){
                Jsum+=i;
            }else {
                Osum+=i;
            }
        }
        System.out.println("奇数和为:"+Jsum);
        System.out.println("偶数和为:"+Osum);
        //练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
		for(int i=0;i<=1000;i++){
            if(i%5==0){
                System.out.print(i+"\t");
            }
            if(i%15==0){
                System.out.println();
            }
        }
        //打印9X9乘法表

        for (int j = 1; j < 10; j++) {
            for (int i = 1; i <= j; i++) {
                System.out.print(j+"*"+i+"="+(j*i)+"\t");
            }
            System.out.println();
        }

增强for循环

        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);
        }

break & continue

  • break可用在任何循环的主体部分,由于强行退出循环,也可以用在switch语句。

  • continue用于循环语句中,终止某次循环过程,跳过剩余语句,之间进行下一次循环条件判断。

  • 标签:后面跟一个冒号的标识符 label:

        int i = 0;
        while(i<100){
            i++;
            System.out.println(i);
            if(i==30){
                break;
            }
        }
        int i= 0;
        while(i<100){
            i++;
            if(i%10==0){
                System.out.println();
                continue;
            }
            System.out.print(i+" ");
        }

Java方法

方法的定义

  • Java的方法类似与其他语言的函数,是一段用来完成特定功能的代码片段

  • 方法包含一个方法头和一个方法体

    • 修饰符:可选,定义了方法的访问类型,告诉编译器如何调用该方法。

    • 返回值类型:方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法没有返回值,则returnValueType为关键字void。

    • 方法名:是方法的实际名称,方法名与参数表共同构成方法签名。

    • 参数类型

      :像一个占位符。方法被调用时,传递值给参数,该值称为实参或变量。参数列表是指方法的参数类型、顺序和参数个数。参数是可选的,方法可以不包含任何参数。

      • 形式参数:在方法被调用时用于接收外界输入的数据。

      • 实参:调用方法时实际传给方法的数据。

    • 方法体:方法体包含具体的语句,定义该方法的功能。

修饰符 返回值类型 方法名(参数类型 参数名,...){
   方法体...
   return 返回值;
}
1234

方法的调用

  • 调用方法:对象名.方法名(实参列表)。

  • Java支持两种调用方法的方式,根据方法是否返回值来选择。

  • 当方法返回一个值的时候,方法调用通常被当成一个值

int larger = max(30,40);
1
  • 如果方法返回值是void,方法调用一定是一条语句。

  • 扩展:值传递和引用传递 ( Java都是值传递)。

  • 调用其他类的方法,除非是static静态方法,不然必须实例化这个类(new)

public class Demo01 {
   
    public static void main(String[] args) {
        int add = Demo01.add(1,2); // 通过类名直接调用静态方法
        System.out.println(add); // 3
    }
	// static静态方法,否则就要new实例化来调用
    public static int add(int a,int b){
        return a+b;
    }
}
1234567891011

值传递 &引用传递

在这里插入图片描述


在这里插入图片描述

方法的重载

  • 重载是在一个类中,有相同的方法名,参数列表不同的方法。

  • 方法重载的规则:

    • 方法名称必须相同

    • 参数列表必须不同(个数、参数类型、或排序不同)

    • 返回类型可以相同也可以不相同

    • 仅仅返回类型不同不足以成为方法的重载

  • 实现理论

    • 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

命令行传参

  • 有时候你希望运行一个程序时候传递给它消息,这要靠传递命令行参数给main()函数实现。

public static void main(String[] args) {
    //args.length 数组长度
    for (int i = 0; i < args.length; i++) {
        System.out.println("args["+i+"]: "+args[i]);
    }
}

可变参数

  • Jdk1.5开始,Java支持传递同类型的可变参数给一个方法。

  • 在方法声明中,在指定参数类型后加一个省略号 (…)。

  • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。

//打印最大值
public static void printMax(int... num){
    if(num.length==0){
        System.out.println("没有值传入");
        return;
    }
    int result = num[0];
    for (int i = 1; i < num.length; i++) {
        if(num[i] > result){
            result = num[i];
        }
    }
    System.out.println("最大值是:"+result);
}
public static void main(String[] args) {
    printMax(1,2,3,4); //最大值是:4
    printMax(new int[]{1,2,3,4,5}); //最大值是:5
}

递归

  • 递归就是:A方法调用A方法,自己调用自己!

  • 递归策略只需少量的代码可描述解题过程中多次重复计算,大大减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

  • 递归结构

    • 递归头:什么时候不调用自身方法,没有头 将陷入死循环。

    • 递归体:什么时候需要调用自身方法。

//阶乘 n! n*(n-1)*...*2*1
public static int f(int n){
    if(n==1) return 1;
    return n*f(n-1); //递归:调用自身
}
public static void main(String[] args) {
    System.out.println(f(5)); //5!= 120
}


Java数组

数组的定义

  • 数组是相同类型数据的有序集合

  • 数组描述的是相同类型的若干数据,按照一定先后次序排序组合而成

  • 其中,每一个数据称作一个数组元素,每个数组元素可以通过下标访问它们

数组的声明创建

  • 数组的声明创建

    • 首先必须声明数组变量,才能在程序中使用数组。

    dataType[] arrayRefVar; //首选
    dataType arrayRefVar[]; //效果相同,但不是首选
    • Java语言使用new操作符来创建数组,语法如下

    dataType[] arrayRefVar = new dataType[arraySize]; //int[] nums=new int[10]
    • 数组的元素是通过索引访问的,数组索引从0开始

    • 获取数组长度:arrays.length

    int[] nums; //1.声明一个数组
    nums = new int[3]; //2.创建一个数组
    //3.给数组元素赋值
    nums[0]=1;
    nums[1]=2;
    nums[2]=3;
    for (int num : nums) { //打印数组所有元素
        System.out.println(num);
    }

    内存分析

    在这里插入图片描述


    在这里插入图片描述


    数组的三种初始化

    • 静态初始化

    //静态初始化:创建+赋值
    int[] a={1,2,3};
    Man[] mans={new Man(1,1),new Man(2,2)}
    • 动态初始化

    //包含默认初始化
    int[] a=new int[2]; //默认值为0
    a[0]=1;
    a[1]=2;
    • 默认初始化

      • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

    数组的基本特点

    1. 其长度是确定的,数组一旦被创建,它的大小就是不可改变的。

    2. 其元素必须是相同类型,不允许出现混合类型。

    3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型。

    4. 数组变量属于引用类型,数组也可以看作对象,其中每个元素相当于该对象的成员变量。

      数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,

      数组本身是在堆中的

    数组边界

    在这里插入图片描述

    数组的使用

    • For-Each循环

    int[] arrays = {1,2,3,4,5};
    //打印全部的数组元素 JDK1.5 没有下标
    for (int array : arrays) {
        System.out.println(array);
    }
    • 数组作方法入参

    //打印数组元素
    public static void printArray(int[] a){
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[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;
    }

    多维数组

    • 多维数组可以看成数组的数组,比如二维数组就是一个特殊的数组,其每一个元素都是一个一维数组。

    int arr[][] = new int[3][2]; //二维数组,三行两列
    

    在这里插入图片描述

    int[][] array = {{1,2},{3,4},{5,6}};
    //打印二维数组所有元素
    for (int i = 0; i < array.length; i++) { //arrays.length=3
        for (int j = 0; j < array[i].length; j++) {
            System.out.print(array[i][j]+" ");
        }
        System.out.println();
    }

    Arrays类

    • 数组的工具类java.util.Arrays

    • 由于数组对象本身并没有什么方法可以供我们使用,但API提供了一个工具类Arrays供我们使用。

    • Array类中的方法都是static修饰的静态方法,使用时直接使用类名进行调用,可以不用对象调用。

    • 常用功能

      • 给数组赋值:fill方法。

      • 排序:sort方法,升序。

      • 比较数组:equals方法比较数组中元素值是否相等。

      • 查找数组元素:binarySearch对排序好的数组进行二分查找法操作。

        int[] a = {1423, 643, 5743, 2346, 5747, 234, 4236};
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));

冒泡排序

  • 冒泡排序是八大排序最出名的排序算法。

  • 代码:两层循环,外层冒泡轮数,里层依次比较。

  • 当我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2)

    public static void main(String[] args) {
        int[] a = {1,2,5,6,4,3,7};
        int[] sort = sort(a);
        System.out.println(Arrays.toString(sort));
    }
    public static int[] sort(int[] array){
        int temp = 0;
        for (int i = 0; i < array.length-1 ; i++) {
            for (int j = 0; j < array.length-1-i ; j++){
                if(array[j]>array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
        return array;
    }

面向对象

初识面向对象

面向过程&面向对象

  • 面向过程思想

    • 步骤清晰简单,第一步做什么,第二部做什么…

    • 面向过程适合处理一些较为简单的问题

  • 面向对象思想

    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。

    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!

  • 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。

什么是面向对象

  • 面向对象编程(Object-Oriented Programming, OOP)

  • 本质:以类的方式组织代码,以对象的组织(封装)数据。

  • 抽象

  • 三大特性

    • 封装

    • 继承

    • 多态

  • 从认识论的角度考虑是先有对象后有类。对象是具体的事物,类是对象的抽象。

  • 从代码运行角度考虑是先有类后有对象。类是对象的模板

类与对象的关系

  • 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但并不能代表某一个具体的事物。

    • 动物、植物、手机、电脑…

    • Person类、Pet类、Cat类等,都是用来描述/定义某一具体的事物应该具备的特点和行为。

  • 对象是抽象概念的具体实例,如张三是人的一个具体实例、张三家里的狗旺财就是狗的一个具体实例。

创建与初始化对象

  • 使用new来创建对象。

  • 使用new关键字创建的时候,除了分配内存之外,还会给创建好的对象进行默认的初始化,以及对类中构造器的调用。

  • 类中的

    构造器

    也被称为构造方法,创建对象时必须要调用。有以下特点:

    • 必须和类的名字相同

    • 没有返回类型,也不能写void

  • 一个类即使什么都不写,也会存在一个默认的构造方法

构造器

public class Person {
    public String name;
    public Person(String name){
        this.name = name;
    }
}

内存分析

public class Pet {
    public String name;
    public int age;

    public void shout(){
        System.out.println("叫了一声");
    }
public class Application {
    public static void main(String[] args) {
        Pet pet = new Pet();
        
        pet.name = "旺财";
        pet.age = 3;
        pet.shout();
    }
}
  • 对象通过引用类型来操作:栈 - - ->堆

在这里插入图片描述在这里插入图片描述

封装

  • 该露的露,该藏的藏

    • 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据细节由自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。

  • 封装(数据的隐藏)

    • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,称为信息隐藏。

  • 作用

    1. 提高程序的安全性,保护数据

    2. 隐藏代码的实现细节

    3. 统一接口

    4. 系统可维护性增加了

public class Student {
    private String name;
    private int id;
    private char sex;
    private int age;

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    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;
        }
    }
}

继承

  • 继承的本质是对某一批类的抽象,从而实现对世界更好地建模。

  • extends的意思是”扩展“。子类是父类的扩展,使用关键字extends来表示。

  • Java中类只有单继承,没有多继承!一个类只能继承一个父类。

  • 继承是类与类之间的一种关系,此外还有依赖、组合、聚合等。

  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)子类继承父类。

  • 子类和父类之间,从意义上讲应该具有”is a“的关系。

//学生类(子类)继承 人类(父类)
public class Student extends Person{ /*Person extends Object*/
    ...
}
  • 子类继承了父类,就会拥有父类的全部方法,而private私有属性及方法无法继承

  • 在Java中,所有类,都默认直接或间接继承Object类 (Ctrl+H 可以查看类关系)

  • 被final修饰的类,无法被继承(断子绝孙)。

super & this

  1. super()调用父类的构造方法,必须在构造方法的第一个

  2. super必须只能出现在子类的方法或构造方法中

  3. super()this()不能同时调用构造方法,因为this也必须写在第一行

  • super与this的区别:super代表父类对象的引用,只能在继承条件下使用;this调用自身对象,没有继承也可以使用。

super(); //隐藏代码,默认调用了父类的无参构造,要写只能写第一行
public class Person {
    protected String name = "liqiankun";

    public Person() {
        System.out.println("Person无参执行了");
    }

    //私有的东西无法继承
    public void print(){
        System.out.println("Person");
    }
}
public class Student extends Person{
    public Student() {
        //隐藏代码,调用了父类的无参构造
        super(); //调用父类的构造器,必须在子类构造器的第一行
        System.out.println("Student无参执行了");
    }

    private String name = "KD";

    public void print(){
        System.out.println("Student");
    }

    public void test2(){
        print(); //Student
        this.print(); //Student
        super.print(); //Person
    }
    public void test(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);

    }
}

方法的重写

  • 重写:子类的方法必须与父类方法必须一致,方法体不同。

  • 重写是方法的重写,与属性无关

  • 重写方法只与非静态方法有关,与静态方法无关(静态方法不能被重写)

public class A extends B{

    @Override
    public void test() {
        System.out.println("A");
    }
}
public class B {

    public void test(){
        System.out.println("B");
    }
}
  • 静态方法属于类,非静态方法属于对象

  • 注意点:

  1. 方法名、参数列表必须相同

  2. 修饰符范围可以扩大,不能缩小(public>protect>private)

  3. 抛出的异常 范围可以被缩小,不能扩大

  4. static(属于类,不属于实例),final(常量方法),private(私有)修饰的方法不能重写

多态

  • 动态编译:类型

  • 即同一方法可以根据发送对象的不同而采用不同的行为方式

  • 一个对象的实际类型是确定的,但可以指向对象的引用可以有很多

  • 多态存在条件

    • 有继承关系

    • 子类重写父类方法

    • 父类引用指向子类对象

  • 注意点:

    1. 多态是方法的多态,没有属性的多态

    2. 父类和子类,有联系 类型转换异常: ClassCastException

    3. 存在条件:继承关系,方法需要重写,父类引用指向子类对象!

instanceof和类型转换

  • instanceof 引用类型比较,判断一个对象是什么类型

instanceof和类型转换

  • instanceof 引用类型比较,判断一个对象是什么类型

public static void main(String[] args) {

    // Object > String
    // Objest > Person > Student
    // Objest > Person > Teacher
    Object object = new Student();
	// X instanceof Y,X引用指向的对象是不是Y的子类
    System.out.println(object instanceof Student); //true
    System.out.println(object instanceof Person); //true
    System.out.println(object instanceof Teacher); //false
    System.out.println(object instanceof Object); //true
    System.out.println(object instanceof String); //false
	
    //类型之间的转化:父-子(高-低),低可以转换为高
    Person obj = new Syudent(); //只能用Person方法(重写了用子类重写过的方法)
    (Syudent)obj.go(); //强转之后可以用Student方法(Student->go())
}

类型转换

  1. 父类引用指向子类的对象

  2. 把子类转换为父类,向上转型,会丢失自己原来的一些方法

  3. 把父类转换为子类,向下转型,强制转换,才调用子类方法

  4. 方便方法的调用(转型),减少重复的代码,简洁。

Static

  • 静态变量可以直接用类名访问,也称类变量。

  • 静态变量(或方法)对于类,所有对象(实例)所共享。

  • 静态区代码 加载类时一起被初始化,最早执行且只执行一次(第一次new)。

  • Math->随机数:

import java.lang.Math;
public class Test {
    public static void main(String[] args) {
        System.out.println(Math.random());
    }
}

抽象类(abstract)

  • abstract修饰的类就是抽象类,修饰的方法就是抽象方法。

  • 抽象类中可以没有抽象方法,但有抽象方法的类一定要声明为抽象类。

  • 抽象类不能使用new来创建对象,它是用来让子类继承的。

  • 抽象方法只有方法的声明,没有实现,让其子类实现。

  • 子类继承抽象类,必须实现抽象类的所有方法,否则该子类也要声明为抽象类。

public abstract class Action {
    //抽象方法
    public abstract void doSomething();
}

接口(interface)

  • 普通类:只有具体实现

  • 抽象类:具体实现和规范(抽象方法)都有

  • 接口:只有规范,没有方法实现,专业的约束!约束与实现分离:面向接口编程~

  • 接口就是规范,定义的是一组规则,"你是什么…必须做什么…"的思想。

  • 接口的本质是约束,就像人间法律一样,制定好大家都遵守。

public interface UserService {

    //常量  public static final
    int age = 21;

    //public abstract
    void add();
    void delete();
    void update();
    void query();
}

注意点

  • 接口没有构造方法,不能被实例化

  • 实现类必须要重写接口中的方法

  • 实现类(implements) 可以实现多个接口

内部类

  • 内部类就是在一个类的内部再定义一个类,比如A类中定义了一个B类,那么B就是A的内部类,而A相对B来说就是外部类

    1. 成员内部类:可以操作外部类的私有属性及方法

    2. 静态内部类:static修饰,不能访问外部类私有属性

    3. 局部内部类:外部类的方法里定义的类

    4. 匿名内部类:没有名字初始化类

public class Outer {

    public void run(){

        class A{
            public void go(){

            }
        }
    }
}

异常

  • 软件程序在运行过程中,经常可能遇到异常问题,异常英文(Exception),意思是例外,这些例外情况需要我们写程序做出合理的处理,而不至于让程序崩溃。

  • 异常指程序运行中出现的不期而至的各种状况:文件找不到,网络连接错误,非法参数等。

  • 异常发生在程序运行期间,它影响了正常的执行流程。

在这里插入图片描述

简单分类

  • 检查型异常:最具代表性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如用户要打开一个不存在的文件时引发的异常,这些异常在编译时不能被简单地忽略。

  • 运行时异常:是可能被程序员避免的异常,与检查性异常相反,运行时异常可以在编译时忽略。

  • 错误Error:错误不是异常,而是脱离程序员控制的问题。错误在代码经常被忽略。例如当栈溢出,一个异常就发生了,它们在编译也检查不到。

在这里插入图片描述在这里插入图片描述在这里插入图片描述

异常处理机制

  • 抛出异常

  • 捕获异常

  • 异常处理关键字:try、catch、finally、throw、throws

public static void main(String[] args) {
    int a = 1;
    int b = 0;

    try { //try监控区域
        System.out.println(a/b);
    }catch (ArithmeticException e){ //catch 捕获异常
        System.out.println("程序出现异常,变量b不能为0");
    }catch (Exception e){
        e.printStackTrace();
    }finally { //一定会执行,处理善后工作,如关闭资源
        System.out.println("finally");
    }
    
    if(b==0){ //抛出异常一般在方法中使用
        throw new ArithmeticException(); //主动抛出异常
    }
}
//Ctrl+Alt+T 快捷键插入 try-catch

自定义异常

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值