• 欢迎光临~

20220719 第二小组 罗大禹 学习笔记

开发技术 开发技术 2022-07-19 次浏览

20220719 第二小组 罗大禹 学习笔记

Java面向对象

学习重点

1.this关键字
2. 面向对象的特征:封装

学习心得

今天老师上课讲的东西没有昨天讲的抽象,我能更好的去理解,上课做的练习也很好的帮助我去熟悉知识的运用。

Java

前情提要(理解)

什么时候用构造器赋值
看创建对象是为了干什么?
如果说创建对象仅仅是为了调用这个类的方法,建议使用无参构造器
如果说创建对象的时候需要使用到对象的某个属性,可以使用有参构造器

this关键字(理解)

this代表的是当前类的对象,this代表的是当前方法的调用者
this既然是代表方法的调用者,它实际上是和对象的作用是一样的
    既可以调属性,也可以调方法
一个类中可以有什么?
属性,方法,构造器

开发中this通常用在什么位置?

通常用来赋值,尤其是构造器赋值

this调用构造器的要求
  1. 必须在构造器中使用this调用构造器
  2. 必须是第一句话(第一行代码)
注意

this不能用在static修饰的方法中

练习一(理解)

需求:

​  有一个Person类,有name,age属性
  有一个Debit类,有cardId,password,balance(余额)属性
​  Person类有一个开户的方法,openAccount,in(存款,余额增加),out(取款,余额减少,取款时要判断余额)
  Debit类中有一个显示银行卡信息的方法。
赋值的方式:

  ​1. 构造器(建议)
  ​2. 直接通过.属性的方式赋值

分析:

​ 开户:给Person类的Debit属性赋值,Debit初始化时需要给cardId,password,balance赋值

​ 最终在Demo类中测试相关功能

实现功能
Debit类
public class Debit {

    String cardId;
    int password;
    double balance;

    public Debit(){}

    public Debit(String cardId, int password, double balance) {
        this.cardId = cardId;
        this.password = password;
        this.balance = balance;
    }

    public void show() {
        System.out.println("卡号:" + cardId + ",余额:" + balance);
    }
}
Person类:
public class Person {

    String name;
    int age;

    Debit debit;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void openAccount(Debit debit) {
        this.debit = debit;
        // 开户成功,显示一下开户信息
        debit.show();
        show();
    }

    public void in(double money) {
        // 存款:修改余额并且重新赋值
        debit.balance += money;
        System.out.println("存款成功!余额为:" + debit.balance);
    }

    public void out(double money) {
        // 取款:修改余额并且重新赋值
        if(money <= debit.balance){
            debit.balance -= money;
            System.out.println("取款成功!余额为:" + debit.balance);
        }else {
            System.out.println("余额不足!余额为:" + debit.balance);
        }
    }

    public void show() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }

    public boolean valid(int pass){
        if(pass == debit.password){
            return true;
        }
        return false;
    }
}
Demo类
import java.util.Scanner;

public class Demo {

    public static void main(String[] args) {
        Person person = new Person("张三",25);
        Debit debit = new Debit("665544998877",123456,100);
        person.openAccount(debit);
        person.in(151);
        person.out(200);
        person.out(100);
    }
 
}

进阶

在此基础上增加功能:
  键盘输入,存款和取款需要比对密码。
  哪些地方是需要我们来输入的?

  1. 密码,余额
  2. 存多少钱
  3. 取多少钱

在哪里写键盘输入Scanner写在哪里?
  Scanner应该出现在main里

Demo类
import java.util.Scanner;

public class Demo {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Person person = new Person("张三",25);
        for(;;){
            System.out.println("请选择功能:1.开户  2.存款  3.取款");
            String flag = sc.next();

            switch (flag) {
                case "1":
                    System.out.println("请输入账户密码:");
                    int password = sc.nextInt();
                    System.out.println("请输入余额:");
                    double balance = sc.nextDouble();
                    Debit debit = new Debit("654987",password,balance);
                    person.openAccount(debit);
                    break;
                case "2":
                    System.out.println("请输入密码:");
                    int pass = sc.nextInt();
                    // 接下来要去比对密码。
                    // 存款的时候需要比对密码
                    // 取款也需要比对密码
                    // 既然两个地方都需要比对密码,那我们可以把类似功能的代码封装成一个方法
                    // 如果说许多方法都需要重复使用,我们还可以把一堆的方法封装成一个类
                    boolean b = person.valid(pass);
                    if(b){
                        System.out.println("请输入存款金额:");
                        double money = sc.nextDouble();
                        person.in(money);
                    } else {
                        System.out.println("密码有误,无法存款!");
                    }
                    break;
                case "3":
                    System.out.println("请输入密码:");
                    int pass1 = sc.nextInt();
                    boolean b1 = person.valid(pass1);
                    if(b1){
                        System.out.println("请输入取款金额:");
                        double money = sc.nextDouble();
                        person.out(money);
                    } else {
                        System.out.println("密码有误,无法取款!");
                    }
                    break;
            }
        }
    }
}

面向对象的特征:封装(理解)

1.代码层面
(1)属性私有化

  所有的属性都要使用private封装

(2)提供一个公有的set,get方法。

​  getter方法能够按照客户的期望返回格式化的数据(需要有返回值)
​  setter方法可以限制和检验setter方法传入的参数是否合法(不需要有返回值)
  隐藏对象的内部结构

正确定义一个类:

​ (1)所有的属性私有化
​ (2)每个属性都有对应的setter、getter方法
  这是规矩,需要遵守。

2.思想层面

    把一堆重复执行的代码封装成方法。把一堆重复执行的方法封装成一个类。

举例说明
Dog类:
public class Dog {
	//属性的私有化
    private String color;
    private int age;
	//公有的get方法(取出,需要有返回值)
    public String getColor() {
        return color;
    }
	//公有的set方法(存入,不需要有返回值)
    public void setColor(String color) {
        this.color = color;
    }

    public int getAge() {
        return age;
    }

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

    public Dog(){}

    public Dog(String color,int age){
        this.color = color;
        this.age = age;
    }

    public void show() {
        System.out.println(color + "," + age);
    }

}
Ch01类:
public class Ch01 {

    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setAge(20);
        int age = dog.getAge();
        System.out.println(age);

    }
}

练习二(理解)

需求
注册和登录!

  封装:属性一定要私有化,提供公有的set、get方法
  1、创建一个User类,username和password
  2、创建一个Employee类,id和name
  3、Demo类。

登录:

  输入账号和密码,然后去数组中比对,
  遍历数组,分别比对账号和面,如果比对成功,则输出登录成功,则输入账号或密码错误!

注册:

  用户名不能重复!
  遍历,用户名和数组中的用户名比对一下

可能出现的错误

  空指针异常NullPointerException

目前遇到的3个异常:
  1. 数组下标越界
  2. 内存溢出(错误)
  3. 空指针异常
空指针异常

  什么情况下会出现空指针异常:
  引用数据类型的默认值(初始值是null,空引用)
  若数组存储的内容为对象,调用未储存对象的下标,就会出现空指针异常

实现功能:
User类:
public class User {
    int name;
    int password;

    public int getName() {
        return name;
    }

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

    public int getPassword() {
        return password;
    }

    public void setPassword(int password) {
        this.password = password;
    }

    public User() {
    }

    public User(int name, int password) {
        this.name = name;
        this.password = password;
    }
}
Demo类:
import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        //users数组中保存的是一个一个的user对象
        //User []users=new User[2];
        Scanner sc=new Scanner(System.in);
        User []users = new User[2];
        int index=0;
        one:
        for (;;){
            System.out.println("请选择功能: 1、注册 2、登录");
            String flag=sc.next();
            switch (flag){
                case "1":
                    if(index==users.length){
                        User [] temp=new User[users.length+1];
                        for (int i = 0; i < users.length; i++) {
                            temp[i]=users[i];
                        }
                        users=temp;
                    }
                    two:
                    for (;;) {
                        System.out.println("请输入账号:");
                        int userName = sc.nextInt();
                        for (User u : users) {
                            if (u != null) {
                                if (u.getName() == userName) {
                                    System.out.println("用户名已被占用,请重新输入用户名");
                                    continue two;
                                }
                            }
                        }
                        System.out.println("请输入密码:");
                        int password = sc.nextInt();
                        //保存账号密码,实际上保存的是user对象
                        //构建User对象
                        User user = new User(userName, password);
                        users[index] = user;
                        System.out.println("注册成功! 账号:" + users[index].getName() + "密码为:" + users[index].getPassword());
                        index++;
                        continue one ;
                    }
                case "2":
                    in:
                    while(true){
                        System.out.println("请输入账号:");
                        int userName1 = sc.nextInt();
                        System.out.println("请输入密码:");
                        int password1 = sc.nextInt();
                        boolean b= false;
                        for (User u : users) {
                            if(u!=null){
                                if(u.getName()==userName1&& u.getPassword()==password1){
                                    b=true;
                                    break ;
                                }
                            }

                        }
                        if(b){
                            System.out.println("登陆成功");
                            continue one;
                        }else {
                            System.out.println("账户名或密码错误!! 请重新输入");
                            continue in;
                        }

                    }
            }

        }
    }

}


总结:(理解)

  1. this
    代表当前类的对象,代表方法的调用者,通常用在构造器赋值,
    set方法赋值。当形参名和成员变量的名相同时,赋值操作。
  2. 封装,思想封装
    把一堆重复执行的代码封装成方法。把一堆重复执行的方法封装成一个类。
  3. 封装,代码层次的封装
    所有的属性私有化。private,每个属性提供对应的setter和getter方法。
以后我们的赋值操作:

​  1.不再使用对象.属性的方式
​  2.使用构造器
  3.setter方法

需要养成的习惯:

  如果一个类我们手写了构造器
​  就会导致原来的无参构造器失效
  我们养成的一个习惯:保证每个类都有无参构造器

程序员灯塔
转载请注明原文链接:20220719 第二小组 罗大禹 学习笔记
喜欢 (0)