Java学习记录(三)

目录

  • 面向对象基础
  • 字符串
  • 集合基础
  • 继承

面向对象基础

(1) 类和对象

  • 对象:万物皆对象(说话跟放屁一样)
  • 面向对象
  • 类:类是对现实生活中一类具有共同属性行为的事物的抽象
  • 特点:
    • 类是对象的数据类型
    • 类是具有相同属性和行为的一组对象的集合
  • 属性:对象具有的各种特征,每个对象的每个属性都拥有特定的值
  • 行为:对象能够执行的操作
  • 类和对象的关系:类是对象的抽象,对象是类的实体

(2) 类的定义

  • 类的重要性:是Java程序的基本组成单位
  • 类的组成:属性行为
    • 属性:在类中通过成员变量来体现(类中方法外的变量)

    • 行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)

    • public class 类名{ //成员变量 变量1的数据类型 变量1; 变量2的数据类型 变量2; …… //成员方法 方法1; 方法2; …… }

    • 示例:

image-79-1024x542

(3) 对象的使用

  • 创建对象:
    • 格式:类名 对象名 = new 类名();
  • 使用对象:
    • 使用成员变量
      • 格式:对象名.变量名
    • 使用成员方法
      • 格式:对象名.方法名()
  • 示例:

image-80-1024x543

  • 案例:
    • 需求:首先定义一个学生类,然后定义一个学生测试类,在学生测试类中通过对象完成成员变量和成员方法的使用
    • 示例:

image-82-1024x541

(4) 成员变量和局部变量

  • 成员变量:类中方法外的变量
  • 局部变量:方法中的变量
  • 成员变量和局部变量的区别:
区别 成员变量 局部变量
类中位置不同 类中方法外 方法内或者方法声明上
内存中位置不同 堆内存 栈内存
生命周期不同 随着对象的存在而存在,随着对象的消失而消失 随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同 有默认的初始值 没有默认的初始化值,必须先定义,赋值,才能使用

(5) 封装——private关键字

  • private关键字
    • 是一个权限修饰符
    • 可以修饰成员(成员变量和成员方法)
    • 作用是保护成员不背别的类使用,被private修饰的成员只在本类中才能访问
  • 针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
    • 提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰
    • 提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰

index-2-766x1024

index-3-956x1024

  • private关键字的使用
    • 一个标准类的编写:
      • 把成员变量用private修饰
      • 提供对应的getXxx()/setXxx()方法
    • 示例:

index-4-727x1024

index-5-1024x890

(6) 封装——this关键字

  • this修饰的变量用于指代成员变量
    • 方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
    • 方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量
  • 什么时候使用this呢?解决局部变量隐藏成员变量
  • this:代表所在类的对象引用
    • 方法被哪个对象调用,this就代表哪个对象

(7) 封装

  • 封装概述:是面向对象的三大特征之一(封装,继承,多态
  • 封装原则:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的getXxx()/setXxx()方法
  • 封装的好处:
    • 通过方法来控制成员变量的操作,提高了代码的安全性
    • 把代码用方法进行封装,提高了代码的复用性

(8) 构造方法

  • 构造方法概述:构造方法是一种特殊的方法,作用是创建对象

  • 格式:
    public class 类名{ 修饰符 类名(参数){ } }

  • 功能:主要是完成对象数据的初始化

image-83-1024x540

  • 注意事项
    • 构造方法的创建
      • 如果没有定义构造方法,系统将给出一个默认无参数构造方法
      • 如果定义了构造方法,系统将不再提供默认的构造方法
    • 构造方法的重载
      • 如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法
    • 推荐的使用方式
      • 无论是否使用,都手工写无参数构造方法

(9) 标准类的制作

  • 成员变量
    • 使用private修饰
  • 构造方法
    • 提供一个无参构造方法
    • 提供一个带多个参数的构造方法
  • 成员方法
    • 提供每一个成员变量对应的setXxx()/getXxx()
    • 提供一个显示对象信息的show()
  • 创建对象并为其成员变量赋值的两种方式
    • 无参构造方法创建对象后使用setXxx()赋值
    • 使用带参构造方法直接创建带有属性值的对象
  • 示例:

image-84-1024x543

index-6-619x1024

字符串

(1) API

  • 应用程序编程接口
  • Java API:指的就是jdk中提供的各种功能的Java类。

(2) String

  • String类代表字符串。
  • Java程序中所有的双引号字符串,都是String类的对象。
  • String类在java.lang包下,所以使用的时候不需要导包。
  • 特点:
    • 字符串不可变,他们的值在创建后不能被更改
    • 虽然String的值是不可变的,但是他们可以被共享
    • 字符串效果上相当于字符串数组(char[]注:JDK8及以前是字符数组,JDK9及以后是字节数组,但是底层原理是字节数组(byte[]

(3) String构造方法

方法名 说明
public String() 创建一个空白字符串对象,不含有任何内容
public String(char[] chs) 根据字符数组的内容,来创建字符串对象
public String(byte[] bys) 根据字节数组的内容,来创建字符串对象
String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc
  • 示例:

image-85-1024x544

  • 推荐使用直接赋值的方式得到字符串对象

(4) String对象的特点

  • 通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同
  • 一“”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String对象,并在字符串池中维护

(5) 字符串的比较

  • 使用==做比较
    • 基本类型:比较的是数据值是否相同
    • 引用类型:比较的是地址值是否相同
  • 字符串是对象,他比较内容是否相同是通过一个方法实现的,这个方法是:equals()
  • public boolean equals(Object anObject):将字符串与指定对象进行比较。由于我们比较的是字符串对象,所以参数直接传递一个字符串。

(6) 案例:遍历字符串

  • 需求:键盘输入一个字符串,使用程序实现在控制台遍历该字符串

  • 遍历字符串的通用格式:
    for (int i = 0;i < s.length;i++) { s.charAt(i); // 就是指定索引处的字符串 }

  • 示例:

image-102-1024x543

(7) StringBuilder

  • StringBuilder概述:StringBuilder是一个可变的字符串类,我们可以把他看成一个容器,这里的可变指的是StringBuilder对象中的内容是可变的。
  • String和StringBuilder的区别:String内容是不可变的,StringBuilder内容是可变的。
  • StringBuilder构造方法:
方法名 说明
public StringBuilder() 创建一个空白可变字符对象,不含有任何内容
public StringBuilder(String str) 根据字符串的内容,来创建可变字符串对象
  • StringBuilder的添加和反转方法
方法名 说明
public StringBuilder append(任意类型) 添加数据,并返回对象本身
public StringBuilder reverse() 返回相反的字符串序列
  • StringBuilder和String的相互转换
    • StringBuilder转换为String:
      • public String toString():通过toString()就可以实现把StringBuilder转换为String
    • String转换为StringBuilder:
      • public StringBuilder(String s):通过构造方法就可以实现把String转换为StringBuilder

image-103-1024x545

集合基础

(1) 集合基础

  • 集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以发生改变
  • ArrayList
    • 可调整大小的数组实现
    • :是一种特殊的数据类型,泛型。
  • 使用:
    • 在出现E的地方我们使用引用数据类型替换即可
    • 例如:ArrayList,ArrayList

(2) ArrayList构造方法和添加方法

方法名 说明
public ArrayList() 创建一个空的集合对象
public boolean add(E e) 将指定的元素追加到此集合的末尾
public void add(int index,E element) 在此集合中的指定位置插入指定的元素
  • 示例:

image-104-1024x541

(3) ArrayList集合常用方法

方法名 说明
public boolean remove(Object o) 删除指定的元素,返回删除是否成功
public E remove(int index) 删除指定索引处的元素,返回被删除的元素
public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
public E get(int index) 返回指定索引处的元素
public int size() 返回集合中的元素的个数
index-748x1024

(4) ArrayList存储字符串并遍历

案例一:存储字符串并遍历

需求:创建一个存储字符串的集合,存储3个字符串元素,使用程序实现在控制台遍历该集合

image-1024x547

案例二:存储学生对象并遍历

需求:创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合

index-1-950x1024

index-2-687x1024

(5) 案例:学生管理系统

Student.java

package project;

//学生类
public class Student {
    //学号
    private String sid;
    //姓名
    private String name;
    //年龄
    private String age;
    //居住地
    private String address;

    public Student() {
    }

    public Student(String sid, String name, String age, String address) {
        this.sid = sid;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

StudentManager.java

package project;

import java.util.ArrayList;
import java.util.Scanner;

public class StudentManager {
    public static void main(String[] args) {        //创建集合对象,用于存储学生数据
        ArrayList<Student> array = new ArrayList<Student>();
        while (true) {
            //用输出语句完成主界面的编写
            System.out.println("--------欢迎来到学生管理系统--------");
            System.out.println("1 添加学生");
            System.out.println("2 删除学生");
            System.out.println("3 修改学生");
            System.out.println("4 查看所有学生");
            System.out.println("5 退出");
            System.out.println("请输入你的选择:");
            //用Scanner实现键盘录入数据
            Scanner sc = new Scanner(System.in);
            String line = sc.nextLine();
            //用switch语句完成操作的选择
            switch (line) {
                case "1":
                    System.out.println("添加学生");
                    addStudent(array);
                    break;
                case "2":
                    System.out.println("删除学生");
                    deleteStudent(array);
                    break;
                case "3":
                    System.out.println("修改学生");
                    updateStudent(array);
                    break;
                case "4":
                    System.out.println("查看所有学生");
                    findAllStudent(array);
                    break;
                case "5":
                    System.out.println("谢谢使用");
                    break;
                System.exit(0);
                //JVM退出
            }
        }
    }

    //定义一个方法,用于添加学生信息
    public static void addStudent(ArrayList<Student> array) {
        //键盘录入学生对象所需要的数据,显示提示信息,提示要输入何种信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生学号:");
        String sid = sc.nextLine();
        System.out.println("请输入学生姓名:");
        String name = sc.nextLine();
        System.out.println("请输入学生年龄:");
        String age = sc.nextLine();
        System.out.println("请输入学生地址:");
        String address = sc.nextLine();
        //创建学生对象,把键盘录入的数据赋值给学生对象的成员变量
        Student s = new Student();
        s.setSid(sid);
        s.setName(name);
        s.setAge(age);
        s.setAddress(address);
        //将学生对象添加到集合中
        array.add(s);        //给出添加成功提示
        System.out.println("添加学生成功");
    }    //定义一个方法,用于查看学生信息

    public static void findAllStudent(ArrayList<Student> array) {
        //判断集合中是否有数据,如果没有显示提示信息
        if (array.size() == 0) {
            System.out.println("无信息,请先添加信息再查询");
            //为了让程序不再往下执行,给出return;
            return;
        }
        //显示表头信息
        // \t就是tab键
        System.out.println("学号\t\t\t姓名\t\t年龄\t\t地址");
        //将集合中数据取出按照对应格式显示学生信息,年龄补充岁字
        for (int i = 0; i < array.size(); i++) {
            Student s = array.get(i);
            System.out.println(s.getSid() + "\t" + s.getName() + "\t" + s.getAge() + "岁" + "\t" + s.getAddress());
        }
    }

    //定义一个方法,用于删除学生信息
    public static void deleteStudent(ArrayList<Student> array) {
        //键盘录入要删除的学生学号,显示提示信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你要的删除的学生的学号:");
        String sid = sc.nextLine();
        //遍历集合将对应学生对象从集合中删除
        for (int i = 0; i < array.size(); i++) {
            Student s = array.get(i);
            if (s.getSid().equals(sid)) {
                array.remove(i);
                break;
            }
        }
        //给出删除成功的提示
        System.out.println("删除学生成功");
    }

    //定义一个方法,用于修改学生信息    
    public static void updateStudent(ArrayList<Student> array) {
        //键盘录入要修改的学生学号,显示提示信息       
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你要修改的学生的学号:");
        String sid = sc.nextLine();
        //键盘录入要修改的学生信息        
        System.out.println("请输入学生新姓名:");
        String name = sc.nextLine();
        System.out.println("请输入学生新年龄:");
        String age = sc.nextLine();
        System.out.println("请输入学生新地址:");
        String address = sc.nextLine();
        //创建学生对象        
        Student s = new Student();
        s.setSid(sid);
        s.setName(name);
        s.setAge(age);
        s.setAddress(address);
        //遍历集合修改对应的学生信息        
        for (int i = 0; i < array.size(); i++) {
            Student student = array.get(i);
            if (student.getSid().equals(sid)) {
                array.set(i, s);
                break;
            }
        }
        //给出修改成功的提示        
        System.out.println("修改学生信息成功");
    }
}

继承

(1) 继承概述

  • 继承概述:继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
  • 继承的格式:public class 子类名 extends 父类名{}
    • 父类:也被称为基类或超类
  • 继承中子类的特点:
    • 子类可以有父类的内容
    • 子类还可以有自己特有的内容

(2) 继承的好处和弊端

继承好处:

  • 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
  • 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)

继承弊端:

  • 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性

(3) 继承中变量的访问特点

在子类方法中访问一个变量:

  • 子类局部范围找
  • 子类成员范围找
  • 父类成员范围找
  • 如果都没有就报错

(4) super

  • super关键字的用法和this关键字的用法相似
  • this:代表本类对象的引用
  • super:代表父类存储空间的标识(可以理解为父类对象引用)
关键字 访问成员变量 访问构造方法 访问成员方法
this this.成员变量
访问本类成员变量 this(…)
访问本类构造方法 this.成员方法(…)
访问本类成员方法
super super.成员变量
访问父类成员变量 super(…)
访问父类构造方法 super.成员方法(…)
访问父类成员方法

(5) 继承中构造方法的访问特点

子类中所有的构造方法默认都会访问父类中无参的构造方法

  • 因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
  • 每一个子类构造方法的第一条语句默认都是:super()

当父类中没有无参构造方法,只有带参构造方法时:

  • 通过使用super关键字去显示的调用父类的带参构造方法
  • 在父类中自己提供一个无参构造方法

(6) 继承中成员方法的访问特点

通过子类对象访问一个方法

  • 子类成员范围找
  • 父类成员范围找
  • 如果都没有就报错

(7) 方法重写

方法重写概述:

  • 子类中出现了和父类中一模一样的方法声明

方法重写的应用:

  • 当子类需要父类的功能,而功能主体子类有自己特有的内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
  • 练习:手机类和新手机类

图片-23-631x1024

@Override

  • 是一个注解
  • 可以帮助我们检查重写方法的方法声明的正确性

(8) 方法重写注意事项

  • 私有方法不能被重写(父类私有成员子类是不能继承的)
  • 子类方法访问权限不能更低(public>默认>私有)

(9) Java继承中的注意事项

  • Java中类只支持单继承,不支持多继承
  • Java中类支持多层继承