Java学习笔记---干货

30 篇文章 0 订阅
22 篇文章 0 订阅

Java学习

一、java版本

JavaSE :标准版(桌面应用程序、控制台程序)

JavaEE:E企业级开发(Web端,服务器的开发)

JDK:Java开发工具

JRE:Java运行环境

JVM:跨平台特性的主要实现方式,Java虚拟环境

二、运行机制

编译型:一次性编译

解释型:边解释边运行

在这里插入图片描述

三、数据类型

  1. 基本数据类型,基本引用类型:类、接口、数组
  2. 基本数据类型:数值值是存在自己的空间中的
  3. 引用数据类型:数据值存储在其他的空间中的,自己的空间存储的是地址值。
  4. 基本数据类型进行的是数值传递,引用数据类型进行的地址传递。
int[] array={1,2,3};`
`int array1=array;
public class test1 {
    public static void main(String[] args) {
         int i=10;
         int i2=010;//八进制
         int i3=0x10;//十六进制
        System.out.println(i);
        System.out.println(i2);
        float f=0.1f;
        double d=1.0/10;
        System.out.println(f==d);//false
//银行大型数据的比较要使用BigDecimal类,慎用float数据类型
    }
}

1.bool型的默认值为false;

2.string类型的默认值为NUll;

3.int型的默认值为0;

4.final定义常量;

四、数组

4.1 数组

//对数组进行乱序排列,堆存储对象或者数组,使用new进行创建
public class test8_array03 {
    public static void main(String[] args) {
        Random r=new Random();
        int[] array={1,2,3,4,6};
        int temp;
        for (int i = 0; i < array.length; i++) {
            int index=r.nextInt(array.length);
            temp=array[index];
            array[index]=array[i];
            array[i]=temp;

        }
        for (int i = 0; i < array.length; i++) {
            System.out.print("\t"+array[i]);
        }
    }
}

4.2 Java内存

1.数组array[]的数组的地址存储在栈中,而数组的数值存储在堆中。

2.main()方法也存在栈内存中。

3.只要是new出来的一定是在堆里面开辟了一个小空间。

4.如果new了很多次,那么在堆里面一定是有很多个小空间,每个小空间都有各自的数据。

 //两个数组共享一个数组的首地址
public static void main(String[] args) {
    int[] array1={11,22};
    int[] array2=array1;
    System.out.println(array1);
    System.out.println(array2);
}

4.3 二维数组

package Basement;

/**
 * @Author: Guojiang
 * @Date: 2022/12/29/14:46
 * @Description:
 */
/*
二维数组的静态初始化:
     数据类型[][] 数组名=new 数据类型[][]{{元素1,元素2,元素3},{元素1,元素2,元素3}};
 简化格式:
     数据类型[][] 数组名={{元素1,元素2,元素3},{元素1,元素2,元素3}};
 元素访问:
     数组名[索引][索引];
 二维数组的遍历:
     先得到一维数组,再遍历一维数组获取元素;

*/
public class test5_method_08 {
    public static void main(String[] args) {
        int[][] arr=new int[][]{{11,22},{23,24,999,25}};
        for (int i = 0; i < arr.length; i++) {
            for (int j=0;j< arr[i].length;j++)
            {
                System.out.println(""+arr[i][j]);
            }
        }
    }
}

在这里插入图片描述

package Basement;

/**
 * @Author: Guojiang
 * @Date: 2022/12/29/16:10
 * @Description:
 */
public class test5_method_09 {
    public static void main(String[] args) {
        int[][] yearArr={
                {22, 44, 66},
                {77, 33, 88},
                {25, 45, 65},
                {11, 66, 99}
        };
        //全年的业务总和
        int yearSum=0;
        for (int i = 0; i < yearArr.length; i++) {
            int[] quarterArr=yearArr[i];
            int sum=Sum(quarterArr);
            System.out.println("第"+(i+1)+"季度"+sum);
            yearSum+=sum;
        }
        System.out.println("全年的营业额为"+yearSum);
    }
    //就算每一个季度的营业额
    public static int Sum(int[] array){
       int sum=0;
        for (int i = 0; i < array.length; i++) {
            sum+=array[i];
        }
        return sum;
    }
}

五、方法

5.1 方法的重载

1.在同一个类中,定义了多个重名的方法,这些同名的方法具有同种的功能。

2.每个方法不同的参数类型或参数个数,这些同名的方法就构成了重载关系。

3.java通过参数区分重载关系中的不同方法。

public class test_5_method01 {
    public static int Sum_a_b(int a,int b)
    {
        return a+b;
    }
    public static  int Sum_a_b(int a,int b,int c)
    {
        return a+b+c;
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入数字a");
        int a=sc.nextInt();
        System.out.println("请输入数字b");
        int b=sc.nextInt();
        System.out.println("请输入数字b");
        int c=sc.nextInt();
        //对a和b求和
        System.out.println("a+b的结果是\t"+Sum_a_b(a,b));
        System.out.println("a+b+c的结果是\t"+Sum_a_b(a,b,c));
    }

}
package Basement;

public class test5_method_02 {
    public static void main(String[] args) {
/*使用重载的方式比较两个整数是否相同
*/ compare((int)10,(int)20);
    }

    public static void compare(short b1,short b2)
    {
        System.out.println("short");
        System.out.println(b1==b2);
    }
    public static void compare(byte b1,byte b2)
    {
        System.out.println("byte");
        System.out.println(b1==b2);
    }
    public static void compare(int b1,int b2)
    {
        System.out.println("int");
        System.out.println(b1==b2);
    }
    public static void compare(long b1,long b2)
    {
        System.out.println("long");
        System.out.println(b1==b2);
    }
}

六、面向对象

6.1 类

1.如何定义一个类?

public class Phone {
//属性(成员变量)
//行为(方法)
    public void call() {
    }
}

2.如何得到类的对象?

类名 对象名=new 类名();

Phone phone=new Phone();

3.定义类的补充注意事项

用来描述一类事物的类,专业叫做:Javabean类,在Javabean类中是不写main方法的。

之前编写main方法的类,叫做测试类。

6.2 封装

1.什么是封装?

对象代表的是什么,就得封装对应的数据,并提供数据对应的行为,例如:人关门,关门这个行为应该封装在”门“这个对象的行为中。

2.private关键字

权限修饰符,可以修饰成员(成员变量和成员方法),被private修饰的成员只能在本类中才能被访问。

6.3.就近原则和this关键字

System.out.println(age);//寻找就近的age
System.out.println(this.age);//寻找成员变量的age:

this关键字可以区分成员变量和局部变量

6.4 构造方法

1.构造方法的作用?

​ 创建对象的时候,由虚拟机自动调用,给成员变量进行初始化的。

2.构造方法的种类?

​ 无参构造方法:初始化对象时,成员变量的数据均采用默认值。

有参构造方法:在初始化对象时,同时可以为对象进行赋值。

3.构造方法注意事项

​ 任何类定义出来,默认自带无参数构造器,写不写都有。

一旦定义了有参数构造器,无参数构造器就没有了,此时就需要自己写无参数构造器。

建议在任何时候都要手动写上空参和带全部参数的构造方法。

4.构造方法概述

创建对象时,虚拟机会自动调用构造方法,作用是给成员变量进行初始化的。

6.5 标准的Javabean类

1.标准的JavaBean类

类名需要见名知意;成员变量需要使用private修饰;提供至少两个构造方法;成员方法:提供每一个成员变量对应的Set()和get()方法。

生成构造方法的快捷键:alt+insert,alt+fn+insert,ptg插件。

6.6 Java内存分配介绍

1.对象的内存分配图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6HW0ASnN-1675244616287)(C:\Users\18508\Desktop\java学习\笔记\image-20221230104356421.png)]

2.this的内存原理图

this的本质:代表方法调用者的地址值。

在这里插入图片描述

6.7 对象实例联系

1.文字格斗游戏

//补充的%s

public class test10 {
  /*  两部分参数:
        第一部分参数:要输出的内容%s(占位)
        第二部分参数:填充的数据*/
    public static void main(String[] args) {
        System.out.printf("%s你好啊张三%s","你好","我也好");
    }
}
package Subject.test5;

import java.util.Random;

/**
 * @Author: Guojiang
 * @Date: 2022/12/30/12:12
 * @Description:
 */
public class Role {
    private String name;
    private int blood;

    public Role() {
    }

    public Role(String name, int blood) {
        this.name = name;
        this.blood = blood;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return blood
     */
    public int getBlood() {
        return blood;
    }

    /**
     * 设置
     * @param blood
     */
    public void setBlood(int blood) {
        this.blood = blood;
    }

    public void attack(Role role)
    {
        //计算造成的伤害
        Random r=new Random();
        int hurt=r.nextInt(20)+1;
        int remindBlood=role.getBlood()-hurt;
        //对血量进行验证,如果为负数则等于0;
        remindBlood=remindBlood>0? remindBlood:0;
        //重新设置角色的血量
        role.setBlood(remindBlood);
        //this表示方法的调用者
        System.out.println(this.getName()+"举起拳头,打了"+role.getName()+"一下,"+"造成了"+hurt+"点伤害,"+role.getName()+"还剩下了"+role.getBlood()+"点血");


    }
}
package Subject.test5;

/**
 * @Author: Guojiang
 * @Date: 2022/12/30/12:22
 * @Description:
 */
public class RoleTest {
    public static void main(String[] args) {
        Role role1=new Role("乔峰",100);
        Role role2=new Role("鸠摩智",100);
        while(true)
        {
            role1.attack(role2);//乔峰攻击了鸠摩智
            //如果鸠摩智的血量为0,则跳出循环
            if(role2.getBlood()==0)
            { System.out.println(role2.getName()+"已经被打死");
            break;
            }
        }
        while(true)
        {
            role2.attack(role1);//乔峰攻击了鸠摩智
            //如果鸠摩智的血量为0,则跳出循环
            if(role1.getBlood()==0) {
                System.out.println(role1.getName() + "已经被打死");
                break;
            }
        }
    }
}

6.8 API和API的帮助文档

七、字符串

7.1 String概述

1.String是一个定义好的类,定义在Java.lang包中,所以使用的时候不用导包。

2.java程序中的所有字符串文字(例如“发哈时间发货”)都被实为此类的对象。

3.字符串不可变,他们的值在创建后不可改变。

7.2 创建String对象

package Basement;

/**
 * @Author: Guojiang
 * @Date: 2023/01/06/14:48
 * @Description:
 */
public class test12 {
    public static void main(String[] args) {
        //采用直接赋值的方法,获取一个字符串对象
        String name="abcd";
        System.out.println(name);

        //使用new的方法获取一个字符串对象
        //空参构造:可以获取一个空白的字符串对象
        String s2=new String();
        System.out.println("@"+s2+"!");

        //传递一个字符串,根据字符串内容再创建一个新的字符串对象
        String s3=new String("abcd");
        System.out.println(s3);

        //传递一个字符数组,根据字符数组的内容再创建一个新的字符串对象
        char[] chars={'a','b','c','d'};
        String s4=new String(chars);
        System.out.println(s4);

        //传递一个字节数组,根据字节数组在创建一个新的字符串对象
        byte[] bytes={97,98,99,100};
        String s5=new String(bytes);
        System.out.println(s5);
    }
}

注意:

当使用双引号进行赋值时,系统会检查该字符串在串池中是否存在。不存在的时候,创建新的;存在,进行复用。

7.3 字符串的比较

1.基本数据类型比较的是:数值;基本引用类型比较的是:地址值;

package String;

import java.util.Scanner;

/**
 * @Author: Guojiang
 * @Date: 2023/01/06/17:02
 * @Description:
 */
public class test1 {
    public static void main(String[] args) {
        String str1 = "abc";
        String str2 = "ab";
        System.out.println(str1 == str2);
        //如果两个字符串的地址相同,则字符串指向同一个地址;若不相同,指向不同的地址,则为False

        String s1 = new String("abc");
        String s2 = "abc";
        System.out.println(s1 == s2);//new的地址不相同,所以比较结果为False

        //3.比较字符串对象中的内容是否相等
        boolean result = str1.equals(str2);
        System.out.println(result);

        //4.比较字符串对象中的内容是否相等,忽略大小
        boolean result1 = s1.equalsIgnoreCase(s2);
        System.out.println(result1);

        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String string=scanner.next();//这是输入的是new一个对象,所以单纯的字符串比较并不可以相同
        boolean re=string.equals(s2);
        System.out.println(re);
    }
}
    

2.实现简单的登录

package String;

import java.util.Scanner;

/**
 * @Author: Guojiang
 * @Date: 2023/01/06/21:27
 * @Description:
 */
public class test {
    public static void main(String[] args) {
        String userBName="abc";
        String password="123456";
        Scanner scanner=new Scanner(System.in);
        for (int i = 0; i < 3; i++) {
            System.out.println("请输入账号");
            String user=scanner.next();
            System.out.println("请输入密码");
            String pass=scanner.next();
            if(user.equals(userBName)&&pass.equals(password))
            {
                System.out.println("登录成功");
                break;
            }
            else{
                if(i==2){
                    System.out.println("账号已经被锁定,联系客服");
                }
               else System.out.println("账号或密码错误!请重新输入,您还有"+(2-i)+"次机会");
            }
        }
    }
}

7.4 遍历字符串

ASCII码详细介绍

package String;

import java.util.Scanner;

/**
 * @Author: Guojiang
 * @Date: 2023/01/06/21:41
 * @Description:
 */
public class test2 {
    public static void main(String[] args) {
        //键盘输入一个字符串
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str=scanner.next();
        //进行遍历
        int Big=0;
        int small=0;
        int number=0;
        for (int i = 0; i < str.length(); i++) {
            //i表示字符串的每一个索引
            char c=str.charAt(i);
            //if(c>=65&&c<=90)
            if(c>='a'&&c<='z')
                Big++;
            else if(c>=48&&c<=57)
                number++;
            else
                small++;
        }
        System.out.println("字符串的长度为"+str.length());
        System.out.println("大写字母的个数为"+Big);
        System.out.println("数字的个数为"+number);
        System.out.println("小写字母的个数为"+small);
    }
}

7.5 StringBuilder

1.StringBuilder可以看作是一个容器,创建之后里面的内容那个是可以变化的。作用:提高了字符串的操作效率。

2.StringBuilder一般用作字符的反转,拼接。但是StringBuilder的对象是一个容器,使用后要使用to.String()转化为String类型

public class test10 {
    public static void main(String[] args) {
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(123).append(123);
       

        System.out.println(stringBuilder);//这时候输出的stringBuilder并不是字符串类型,所以要更改为字符串类型
        String str=stringBuilder.toString();
        System.out.println(str);
    }
}
package String;

import java.util.Scanner;

/**
 * @Author: Guojiang
 * @Date: 2023/01/08/17:56
 * @Description:
 */
public class test10 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入一个字符串");
        String str=scanner.next();

        //反转输入的字符串
       /* StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(str);
        stringBuilder.reverse();
        String newStr=stringBuilder.toString();*/
        
        String newStr= new StringBuilder().append(str).reverse().toString();
        if(str.equals(newStr))
        {
            System.out.println("字符串是对称的");
        }
        else
        {
            System.out.println("该字符串非对称");
        }
    }
}

7.6 StringJoiner

1.JDK8出现的一个可变的操作字符串的容器,可以高效的,方便的拼接字符串。在拼接的时候,可以指定间隔符号,开始符号和结束符号。

    • Modifier and TypeMethod and Description
      StringJoineradd(CharSequence newElement) 将给定的副本 CharSequence值作为下一个元素 StringJoiner值。
      intlength() 返回此 StringJoinerString表示的长度。
      StringJoinermerge(StringJoiner other) 添加给定的 StringJoiner的内容,没有前缀和后缀作为下一个元素,如果它是非空的。
      StringJoinersetEmptyValue(CharSequence emptyValue) 设置序列的字符时要使用确定的字符串表示的这个 StringJoiner ,而没有单元已被添加然而,就是当它是空的。
      StringtoString() 返回当前值,由的 prefix ,值添加由迄今分离 delimitersuffix ,除非没有元素已经在这种情况下,被添加 prefix + suffixemptyValue被返回的字符

7.4 字符串原理

1.字符串存储的原理:直接赋值会复用字符串常量池中的;new出来不会复用,而是开辟一个新空间。

2.“==”比较的是什么?基本数据类型比较的是数值;基本引用类型比较的是地址值。

3.字符串拼接的底层原理?

​ 如果没有变量参与,都是字符串直接相加,编译之后就是拼接的结果,会复用串池中的字符串。

4.StringBuilder的底层原理

​ 所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存。

5.StringBuilder的源码分析?

​ 默认创建一个长度为16的字节数组;添加的内容长度小于16,直接存储;若添加的北荣大于16还会扩容(原来容量的*2+2);弱国扩容之后还不够,则以实际长度为准。

7.5 字符串练习

7.5.1字符串旋转校验
package String;

/**
 * @Author: Guojiang
 * @Date: 2023/01/10/16:55
 * @Description:
 */
public class test14 {
    public static void main(String[] args) {
        String strA="abcde";
        /*String strB="cdeab";*/
        String strB="bcdea";

        boolean result=checkString(strA,strB);
        System.out.println(result);

    }
    //对旋转后的字符串进行校验
    public static boolean checkString(String strA,String strB)
    {
        for (int i = 0; i < strA.length(); i++) {
            strA=rotate(strA);
            if(strA.equals(strB))
            {
                return true;
            }
        }
        return false;
    }

    //方法一:采用SubString()对字符串进行截取之后旋转
    public static String rotate(String str)
    {
       char first=str.charAt(0);//截取首字符
       String end=str.substring(1);//截取首字符以外的字符
       return  end+first;
    }
    //方法二:将字符串转化为字符型数组,然后岁数组操作,进行对字符串进行旋转
    /*public static String rotate(String str)
    {
        char[] arr=str.toCharArray();
        //拿到0索引上的字符
        char first=arr[0];
        for (int i = 1; i < arr.length; i++) {
            arr[i-1]=arr[i];
        }
        arr[arr.length-1]=first;

        //利用数组创建一个字符串对象
        String result=new String(arr);
        return result;
    }*/

}
7.5.2.数字字符串相乘

提示:数字转化为字符串的方法

​ 方法一:直接强制转换。如:String str= (String)123;

​ 方法二:直接通过空字符串+数字的形式转换为字符串(前后都可以用)。如:String str= “”+123;

​ 方法三:直接通过包装类来实现。如:String str = String.valueOf(1231);

package String;

/**
 * @Author: Guojiang
 * @Date: 2023/01/11/12:06
 * @Description:将两个定义的字符串类型的数字串相乘,乘积以字符串的类型返回
 */
public class test16 {
    public static void main(String[] args) {
        String num1="12345";
        String num2="123456";
        String string=MulString(num1,num2);
        System.out.println("字符串相乘后的结果字符串为:"+string);
    }

    //字符串类型相乘,并返回字符串
    public static String MulString(String num1,String num2)
    {
        int number1=0,number2=0,mul=0;
        //字符串转化为数字的核心方法
        for (int i = 0; i < num1.length(); i++) {
            int c= (num1.charAt(i)-48);
           number1=c+number1*10;
        }
        for (int i = 0; i < num2.length(); i++) {
            int c= (num2.charAt(i)-48);
            number2=c+number2*10;
        }
        mul=number1*number2;
        /*方法一:直接强制转换。如:String str= (String)123;
        方法二:直接通过空字符串+数字的形式转换为字符串(前后都可以用)。如:String str= ""+123;
        方法三:直接通过包装类来实现。如:String str = String.valueOf(1231);*/
        String string=""+mul;
       // String string=String.valueOf(mul);
        return string;
    }
}

八、ArrayList

8.1 集合的基本使用
8.1.1集合和数组的对比

1.长度和存储类型

(1)长度:数组的长度固定,集合的长度可变。

(2)存储类型:数组可以存基本数据类型和引用数据类型;集合可以存放引用数据类型和基本数据类型(必须包装类)。

8.2 基本操作
    • booleanadd(E e) 将指定的元素追加到此列表的末尾。
      voidadd(int index, E element) 在此列表中的指定位置插入指定的元素。
      booleanaddAll(Collection<? extends E> c) 按指定集合的Iterator返回的顺序将指定集合中的所有元素追加到此列表的末尾。
      booleanaddAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入到此列表中,从指定的位置开始。
      voidclear() 从列表中删除所有元素。
      Objectclone() 返回此 ArrayList实例的浅拷贝。
      booleancontains(Object o) 如果此列表包含指定的元素,则返回 true
      voidensureCapacity(int minCapacity) 如果需要,增加此 ArrayList实例的容量,以确保它可以至少保存最小容量参数指定的元素数。
      voidforEach(Consumer<? super E> action)Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。
      Eget(int index) 返回此列表中指定位置的元素。
      intindexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
      booleanisEmpty() 如果此列表不包含元素,则返回 true
      Iterator<E>iterator() 以正确的顺序返回该列表中的元素的迭代器。
      intlastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
      ListIterator<E>listIterator() 返回列表中的列表迭代器(按适当的顺序)。
      ListIterator<E>listIterator(int index) 从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。
      Eremove(int index) 删除该列表中指定位置的元素。
      booleanremove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。
      booleanremoveAll(Collection<?> c) 从此列表中删除指定集合中包含的所有元素。
      booleanremoveIf(Predicate<? super E> filter) 删除满足给定谓词的此集合的所有元素。
      protected voidremoveRange(int fromIndex, int toIndex) 从这个列表中删除所有索引在 fromIndex (含)和 toIndex之间的元素。
      voidreplaceAll(UnaryOperator<E> operator) 将该列表的每个元素替换为将该运算符应用于该元素的结果。
      booleanretainAll(Collection<?> c) 仅保留此列表中包含在指定集合中的元素。
      Eset(int index, E element) 用指定的元素替换此列表中指定位置的元素。
      intsize() 返回此列表中的元素数。
      voidsort(Comparator<? super E> c) 使用提供的 Comparator对此列表进行排序以比较元素。
      Spliterator<E>spliterator() 在此列表中的元素上创建*late-binding故障快速* Spliterator
      List<E>subList(int fromIndex, int toIndex) 返回此列表中指定的 fromIndex (包括)和 toIndex之间的独占视图。
      Object[]toArray() 以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组。
      <T> T[]toArray(T[] a) 以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素); 返回的数组的运行时类型是指定数组的运行时类型。
      voidtrimToSize() 修改这个 ArrayList实例的容量是列表的当前大小。
8.3 集合练习
package ArrayListTest;

/**
 * @Author: Guojiang
 * @Date: 2023/01/12/9:59
 * @Description:手机的Javablei
 */
public class Phone {
    private String brand;
    private double price;

    public Phone() {
    }

    public Phone(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
package ArrayListTest;

import java.util.ArrayList;

/**
 * @Author: Guojiang
 * @Date: 2023/01/12/10:03
 * @Description:定义一个方法,返回低于3000元的手机信息
 */
public class PhoneTest {
    public static void main(String[] args) {
        //创建集合
        ArrayList<Phone> arrayList=new ArrayList<>();
        //声明对象
        Phone phone1=new Phone("小米",1199.00);
        Phone phone2=new Phone("苹果",8000.00);
        Phone phone3=new Phone("苹果",8000.00);
        //插入集合
        arrayList.add(phone1);
        arrayList.add(phone2);
        arrayList.add(phone3);
        //查询价格低于3000的手机信息
        Phone phone=Select_less(arrayList);
        if(phone==null)
        {
            System.out.println("不存在低于3000元以下的手机");
        }
        else
        {
            System.out.println(phone.getBrand());
        }
    }
    public static Phone Select_less(ArrayList<Phone> arrayList)
    {
        for (int i = 0; i < arrayList.size(); i++) {
            Phone phone=arrayList.get(i);
            double money=phone.getPrice();
            if(money<3000)
            {
                return phone;
            }
        }
        return null;
    }
}

九、面向对象进阶

9.1static-静态变量

1.static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量,被static修饰的成员变量,叫做静态变量;被static修饰的成员方法,称作静态方法,多用在测试类和工具类中;javaBean类很少使用。

2.静态变量特点:被该类所有对象共享,不属于对象,属于类。调用方式:类名调用(推荐),对象名调用。

3.静态变量是随着类的加载而加载的,优于对象存在的,静态变量存储在堆内存中。

4.javaBean类:用来描述一些事物的类,比如,Student,Teacher,Dog,Cat等。

5.测试类:用来检查其他类是否书写正确,带有main方法的类,是程序的入口。

6.工具类:不是用来描述一类事物的,而是帮助我们做一些事情的类。

类名要见名知意,私有化构造方法。

7.私有构造的作用: 私有构造可以保证类不会被外部调用。如果想要创建此类的对象,只需在本类new自己的私有构造来创建一个对象,对外暴露此方法。

9.2static的注意事项

1.静态的变量只能访问静态的方法和静态的变量。

2.非静态方法可以访问静态变量或者静态方法,也可以访问非静态的成员变量和非静态的成员方法。

3.静态方法中没有this关键字。

总结:静态方法中,只能访问静态;非静态方法可以访问所有;静态方法中没有this关键字;

9.3继承概述

1.什么是继承?

​ 继承是面向对象的三大特征之一,可以让类跟类之间产生子父的关系。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。

2.什么时候用继承?

​ 当类与类之间,存在相同的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码。

3.继承的格式?

 public class 子类 extends 父类{ }

4.继承后子类的特点?

​ 子类可以得到父类的属性和行为,子类可以使用;子类可以在父类的基础上增加新的功能,子类更加强大。

9.4继承的特点
9.4.1综述

1.Java只支持单继承,不支持多继承,但支持多层继承。

2.多层继承:子类A继承父类B,子类B继承父类C,子类C为子类A的间接父类,子类B为子类A的直接父类。

9.4.2子类继承内容
继承内容
构造方法非私有 不可继承私有 不可继承
成员变量非私有 可以继承私有 可以继承(使用get(),set())
成员方法虚方法 可以继承否则 不可继承

1.如果一个类中没有构造方法,那么虚拟机会自动给你添加一个默认的空参构造方法。

2.成员方法继承采用虚方法表(非private,非static,非final),在最小子类的虚方法表上加上上层父类的虚方法。通过查询虚方法表确定方法在哪个父类中,进而进行快速定位。

9.4.3成员变量

1.成员变量访问特点代码

package extendsDemo.demo1;

/**
 * @Author: Guojiang
 * @Date: 2023/01/28/14:36
 * @Description:成员变量继承测试
 */
public class Test {
    public static void main(String[] args) {
        Zi zi=new Zi();
        zi.show();
    }
}
//父类
class Fu
{
    String name="Fu";
    String hobby="喝奶茶";
}
class Zi extends Fu
{
    String name="zi";
    String game="吃鸡";
    //就近原则打印
    public void show(){
        String name="张三";
        //打印本类中的成员变量的信息
        System.out.println(name);
        //打印本类中成员信息
        System.out.println(this.name);
        //打印父类成员变量的信息
        System.out.println(super.name);
        //打印的信息都为喝奶茶
        System.out.println(super.hobby);
        System.out.println(this.hobby);
        System.out.println(hobby);
        //打印game
        System.out.println(this.game);
        System.out.println(game);
    }
}

2.成员变量的访问总结

遵循就近原则:现在局部位置找,本类成员位置找,父类成员位置找,逐级往上找。

3.如果出现重复的成员变量怎么办?

System.out.println(name);//从局部位置往上找
System.out.println(this.name);//从本类成员位置往上找
System.out.println(super.name);//从父类成员位置网上找
9.4.4成员方法

1.调用原则

​ 直接就近原则:谁离我近,就直接用谁。super调用直接访问父类。

2.方法重写

[1] 当父类的方法无法满足子类的现在的需求时,需要进行方法的重写。

[2] 书写格式:在继承体系中,子类出现了和父类一模一样的方法声明,我们称子类这个方法是重写的方法。

[3] @override重写注解:是放在重写后的方法上,检验子类重写时语法是否正确。

3.方法重写注意事项和要求

[1] 重写的方法的名称、形参列表必须与父类中的保持一致。

[2] 子类重写父类方法时,访问权限子类必须大于等于父类(暂时了解:空着不写<protected<public)

[3] 子类重写父类方法时,返回值类型子类必须小于等于父类。

[4] 建议:重写的方法尽量和父类保持一致。

[5] 只有被添加到虚方法表中的方法才可以被重写。

注意事项 this调用:就近原则;super调用:直接找父类。

9.4.5构造方法

1.构造方法的访问特点

[1] 父类中的构造方法不会被子类继承。

[2] 子类中的所有构造方法默认先访问父类中的无参构造,再执行自己。

[3] 为什么?

​ 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。

​ 子类在初始化之前,一定调用父类构造方法先完成父类数据空间的初始化。

[4] 怎么调用父类构造方法?

​ 子类构造方法的第一行语句默认都是:super(),不写也存在,且必须在第一行。

2.访问特点总结

[1] 子类不能继承父类的构造方法,但是可以通过super调用。

[2] 子类构造方法的第一行,有一个默认的super();

[3] 默认先访问父类中无参的构造,再执行自己。

[4] 如果想要方法文父类有参构造,必须手写书写。

9.4.6this和super关键字

1.this:理解为一个变量,表示当前方法调用者的地址值。

2.super:代表父类的存储空间。

关键字访问成员变量访问成员方法访问构造方法
thisthis.成员变量;访问本类成员变量this.成员方法(…);访问本类成员方法this(…);访问本类构造方法
supersiper.成员变量;访问父类成员变量super.成员方法(…);访问父类成员方法super(…);访问父类构造方法
9.5多态
9.5.1概念

1.多态

指为不同数据类型的实体提供统一的接口,同类型对象的多种形态。

2.多态的前提

[1]有继承/实现关系

[2]有父类引用指向子类对象。

[3]有方法的重写

3.多态的好处

使用父类型作为参数,接收所有子类对象,体现多态的扩展性与便利。

9.5.2调用成员特点

1.调用成员变量的特点:编译看左边,运行也看左边;

调用成员方法的特点:编译看左边,运行看右边;

package polymorphism.demo2;
/**
 * @Author: Guojiang
 * @Date: 2023/01/29/10:32
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        Animal animal=new Dog();
        //调用成员变量的特点:编译看左边,运行也看左边
        //先看父类的成员变量是否存在,不存在则编译失败
        System.out.println(animal.name);
        //调用成员方法的特点:编译看左边,运行看右边
        //方法如果子类存在会覆盖掉原来父类的方法,进而调用层级,从本类依次往上
        animal.show();
    }
}
class Animal{
    String name="动物";
    public void show()
    {
        System.out.println("Dog---show方法");
    }
}
class Dog extends Animal
{
    String name="狗";
    public void show()
    {
        System.out.println("Dog-----show方法");
    }
}
9.5.3优势和弊端

1.多态的优势

方法中,使用父类型作为参数,可以接收所有子类对象。

2.多态的弊端

不能使用子类的特有功能

3.引用数据类型的类型转换,有几种方式?

自动类型转换,强制类型转换

4.强制类型转换能解决什么问题?

[1]可以转换成真正的子类类型,从而调用子类独有的功能。

[2]转换类型与真实对象类型不一致会报错。

9.6 包和final
9.6.1包

1.包的作用?

​ 包就是文件夹,用来管理各种不同功能的Java类。

2.包名书写的规则?

​ 公司域名反写+包的作用,需要全部英文小写,见名知意。

3.什么是全类名?

​ 包名+类名

4.什么时候需要导包?什么时候不需要导包?

​ [1]使用同一个包中的类时,不需要导包。

​ [2]使用java.lang包中的类时,不需要导包。

​ [3]其他情况都需要导包。

​ [4]如果同时使用两个包中的同名类时,需要使用全类名。

9.6.2final

1.final修饰的方法:表明该方法是最终方法,不能被重写。

2.final修饰的类,表明是最终类,不能被继承。

3.final修饰的变量叫做常量,只能被赋值一次。

4.常量

[1]实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性。

[2]常量的命名规范

​ 单个单词:全部大写;多个单词:全部大写,单词之间用下划线隔开。

5.final细节

[1]final修饰的变量是基本类型:那么存储的数据值不能发生改变。

[2]final修饰的变量是引用类型,那么变量存储的地址值不能发生改变,对象内部的可以改变。

9.7权限修饰符和代码块
9.7.1权限修饰符

1.权限修饰符的分类

​ 作用范围:private<默认(空着不写)<protected<public

修饰符同一个类中同一个包中的其他类不同包下的子类不同包下的无关类
private
默认
protected
public

2.使用规则

​ [1]实际开发中,一般只用private和public.

​ [2]成员变量私有,方法公开。

特例:如果方法中的代码是抽取其他方法中的共性代码,这个方法一般也私有。

9.7.2代码块

1.代码块的分类

​ 局部代码块,构造代码块,静态代码块

2.局部代码块的作用?

提前结束变量的声明周期(已淘汰)。

3.构造代码块的作用?

抽取构造方法中的重复代码(不够灵活),可以通过定义方法调用解决重复代码。

4.静态代码块的作用?

数据的初始化。

9.8 抽象类和抽象方法

1.抽象类概念

​ 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

2.抽象方法概念

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

3.抽象类和抽象方法注意事项

[1]抽象类不能实例化(不能创建对象)

[2]抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。

[3]可以有构造方法

[4]抽象类的子类

​ 要么重写抽象类中的所有抽象方法(常用),要么是抽象方法。

4.抽象类是怎么样的?

[1]抽取共性时,无法确定方法体,就把方法定义为抽象的。

[2]强制让子类按照某种格式重写。

[3]抽象方法所在的类,必须是抽象类。

5.抽象类和抽象方法的格式?

   `public abstract 返回值类型 方法名(参数列表)`
   `public abstract class 类名{}`
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值