Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

面向对象编程(中级)

笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html)

lntelliJ IDEA

●IDEA介绍(内容仅需了解)

  1. IDEA全称Intelli IDEA
  2. 在业界被公认为最好的Java开发工具
  3. IDEA是JetBrains公司的产品,总部位于捷克的首都布拉格
  4. 除了支持Java开发,还支持HTML,CSS,PHP,MySQL,Python等

●Eclipse介绍

  1. Eclipse是一个开放源代码的、基于Java的可扩展开发平台。
  2. 最初是由IBM公司耗资3000万美金开发的下一代lD开发环境
  3. 2001年11月贡献给开源社区
  4. Eclipse是目前最优秀的Java开发IDE之一

IDEA的安装

官网:https://www.jetbrains.com/ IDEA下载后,就可以开始安装。

本人笔记中使用的 IDEA 2020.2

IDEA的基本介绍和使用
使用IDEA创建Java项目(project),看看IDEA是如何使用的,IDEA 是以项目的概念,来管理我们的java源码的

IDEA常用快捷键

  1. 删除当前行,自己配置ctrl + y
  2. 复制当前行,自己配置ctrl + d
  3. 补全代码alt +/
  4. 添加注释和取消注释ctrl +/【第一次是添加注释,第二次是取消注释】
  5. 快速格式化代码ctrl + alt +L
  6. 快速运行程序自己定义shift+f10
  7. 生成构造器等alt + insert , 选择constructor
  8. 查看一个类的层级关系ctrl+H[学习继承后,非常有用]
  9. 将光标放在一个方法上,输入ctrl +B(或ctrl+鼠标左键) ,可以选择定位到哪个类的方法【学继承后,/非常有用】
  10. 自动的分配变量名,通过在后面加 .var

●模板/自定义模板

file -> settings -> editor-> Live templates ->

查看有哪些模板快捷键/可以自己增加模板

public class TestTemplate {
    //main就是一个模板的快捷键.

    public static void main(String[] args) {
        //sout模板快捷键
        System.out.println("hello ,world");
        //foni模板快捷键
        for (int i = o; i

●看一个应用场景
现在有两个程序员共同开发一个java项目,程序员xiaoming希望定义一个类取名Dog ,程序员xiaoqiang也想定义一个类也叫 Dog。两个程序员为此还吵了起来,怎么办?

●包的三大作用

  1. 区分相同名字的类
  2. 当类很多时,可以很好的管理类[看Java API文档]
  3. 控制访问范围

●包基本语法

package com.hspedu;

●说明:

  1. package关键字,表示打包.

  2. com.hspedu:表示包名

●包的本质分析(原理)

包的本质实际上就是创建不同的文件夹来保存类文件。

//当出现多个包中的同class需要在同一个java文件中调用时
package com.use;
import com.xiaoqiang. Dog;

public class Test {
    public static void main(String[] args){
        Dog dog = new Dog();
        System.out.println(dog) ;//com.xiaoqiang. Dog@1540e19d
        com.xiaoming.Dog dog1 = new com.xiaoming.Dog();
        System.out.println(dog1);//com.xiaoming. Dog@677327b6
    }
}

●包的命名

✔命名规则:
只能包含数字、字母、下划线、小圆点.,但不能用数字开头,不能是关键字或保留字

✔命名规范
一般是小写字母+小圆点一般是
com.公司名.项目名.业务模块名
比如:com.hspedu.oa.model; com.hspedu.oa.controller;

举例:
com.sina.crm.user //用户模块
com.sina.crm.order //订单模块
com.sina.crm.utils //工具类

●常用的包
一个包下,包含很多的类,java中常用的包有:

java.lang.* //lang包是基本包,默认引入,不需要再引入.

java.util. //util 包,系统提供的工具包,工具类,使用Scanner
java.net.
//网络包,网络开发
java.awt.* //是做java的界面开发,GUI

●如何引入包

com.hspedu.pkg : Import01.java
语法: import 包;
我们引入一个包的主要目的是要使用该包下的类
比如import java.util.Scanner;就只是引入一个类Scanner
import java.util.*;//表示将java.util包所有都引入
案例:使用系统提供 Arrays完成数组排序

●注意事项和使用细节

  1. package的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有一句package
  2. import指令位置放在package的下面,在类定义前面,可以有多句且没有顺序要求。

访问修饰符

基本介绍
java提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):

  1. 公开级别:用public修饰,对外公开
  2. 受保护级别:用protected修饰,对子类和同一个包中的类公开
  3. 默认级别:没有修饰符号,向同一个包的类公开.

  4. 私有级别:用private修饰,只有类本身可以访问,不对外公开.

4种访问修饰符的访问范围

访问级别 修饰符 当前类 同一包内 子类(不同包) 其他包 公开 public

Y Y Y Y 受保护 protected

Y Y Y N 默认 无 Y Y N N 私有 private

Y N N N

●使用的注意事项

  1. 修饰符可以用来修饰类中的属性,成员方法以及类
  2. 只有默认的和public才能修饰类!,并且遵循上述访问权限的特点。
  3. 因为没有学习继承,因此关于在子类中的访问权限,我们讲完子类后,在回头讲解
  4. 成员方法的访问规则和属性完全一样.

⭐封装

面向对象编程三大特征

基本介绍
面向对象编程有三大特征:封装、继承和多态。

封装介绍
封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。

封装的理解和好处

  1. 隐藏实现细节
  2. 可以对数据进行验证,保证安全合理

封装的实现步骤

  1. 将属性进行私有化private【不能直接修改属性】
  2. 提供一个公共的set方法,用于对属性判断并赋值 public void setXxx(类型参数名){
    //加入数据验证的业务逻辑(判断数据是否合理)
    属性=参数名;
    }
  3. 提供一个公共的get方法,用于获取属性的值 public XX getXxx(){//权限判断
    return xx;
    }

●快速入门案例

看一个案例
那么在java中如何实现这种类似的控制呢?

请大家看一个小程序,不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。年龄合理就设置,否则给默认年龄,必须在1-120,年龄,工资不能直接查看,name的长度在2-6字符之间

public class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.setAge(126);
        System.out.println(person.getAge());
    }
}

class Person {
    public String name;
    private int age;
    private double salary;

    //alt+insert ,再选Getter and Setter,选择需要创建的
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 120 && age > 0) {
            this.age = age;
        } else {
            System.out.println("年龄范围错误,默认设置18");
            this.age = 18;
        }

    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

●将构造器和setXxx结合

public class Test {
    public static void main(String[] args) {
       ......

    }
}

class Person {
    public String name;
    private int age;
    private double salary;

    public Person() {
    }

    public Person(String name, int age, double salary) {
        //this.name = name;
        //this.age = age;
        //this.salary = salary;

        setName(name);
        setAge(age);
        setSalary(salary);
    }
    ......

}

⭐继承

●为什么需要继承

我们编写了两个类,一个是Pupil类(小学生),一个是Graduate(研究生).问题:两个类的属性和方法有很多是相同的,怎么办?

●继承基本介绍和示意图

继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。

画出继承的示意图

●继承的基本语法

class 子类 extends 父类{
}

  1. 子类就会自动拥有父类定义的属性和方法
  2. 父类又叫超类,基类。
  3. 子类又叫派生类。

Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)
class 父类 {
    //共有属性
    public String name;
    public int age;
    private double score;//成绩//共有的方法
    public void setScore(double score) {
        this.score = score;
    }
}

class 子类 extends 父类 {
    public void teting() {
        System.out.println("小学生" +name + "正在考小学数学..");
    }
}

●继承的深入讨论/细节问题

  1. 子类继承了所有的属性和方法,但是私有属性和方法不能在子类直接访问,要通过公共的方法去访问
  2. 子类必须调用父类的构造器,完成父类的初始化
  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下(默认有super())总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
  4. 如果希望指定去调用父类的某个构造器,则显式的调用一下: super(参数列表)
  5. super在使用时,必须放在构造器第一行
  6. super()和this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
  7. java所有类都是Object类的子类, Object是所有类的基类.

  8. 父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(顶级父类)

  9. 子类最多只能继承一个父类(指直接继承),即java中是单继承机制。
    思考:如何让A类继承B类和C类?【A继承B,B继承C】
  10. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系

●继承的本质分析(内存分析)(重要)

√案例
我们看一个案例来分析当子类继承父类,创建子类对象时,内存中到底发生了什么?

提示:当子类对象创建好后,建立查找的关系

public class ArrayTest {
    public static void main(String[] args) {
        Son son = new Son();//内存的布局
        //?->这时请大家注意,要按照查找关系来返回信息
        //(1)首先看子类是否有该属性
        //(2)如果子类有这个属性,并且可以访问,则返回信息
        //(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
        //(4〕如果父类没有就按照(3)的规则,继续找上级父类,直到0bject...

        System.out.println(son.name);
        System.out.println(son.hobby);
    }
}
class GrandPa {
    String name = "大头爷爷";
    String hobby = "旅游";
}
class Father extends GrandPa {//父类
    String name = "大头爸爸";
    int age = 39;
}
class Son extends Father {//子类
    String name = "大头儿子";
}

Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

super关键字

基本介绍

super代表父类的引用,用于访问父类的属性、方法、构造器

基本语法

  1. 访问父类的属性,但不能访问父类的private属性
    super.属性名;
  2. 访问父类的方法,不能访问父类的private方法
    super.方法名(参数列表);
  3. 访问父类的构造器(这点前面用过):
    super(参数列表);只能放在构造器的第一句,只能出现一句!

super给编程带来的便利/细节

  1. 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
  2. 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果!

  3. super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C。当然也需要遵守访问权限的相关规则

super和this的比较

区别点 this super 访问属性 访问本类中的属性,如果本类没有此属性则从父类中继续查找 从父类开始查找属性 调用方法 访问本类中的方法,如果本类没有此方法则从父类继续查找. 从父类开始查找方法 调用构造器 调用本类构造器,必须放在构造器的首行 调用父类构造器,必须放在子类构造器的首行 特殊 表示当前对象 子类中访问父类对象

方法重写/覆盖(override)

基本介绍

简单的说:方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法

注意事项和使用细节

方法重写也叫方法覆盖,需要满足下面的条件

  1. 子类的方法的形参列表,方法名称,要和父类方法的参数,方法名称完全一样。【演示】
  2. 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
    比如父类返回类型是Object,子类方法返回类型是String
    public Object getInfo(){ 和 public String getInfo(){ 构成方法重写
  3. 子类方法不能缩小父类方法的访问权限 public > protected >默认>private
    例:父类中方法为public void sayok(){ ,子类中方法为void sayok(){会报错

重写和重载比较

名称 发生范围 方法 形参列表 返回类型 修饰符 重载(overload) 本类 必须一样 类型,个数或者顺序至少有一个不同 无要求 无要求 重写(override) 父子类 必须一样 相同 子类重写的方法,返回的类型和父类返回的类型一致,或者是其子类 子类方法不能缩小父类方法的访问范围

⭐多态

先看一个问题

问题描述:请编写一个程序,Master类中有一个 feed(喂食)方法,可以完成主人给动物喂食物的信息。

Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

传统的方法带来的问题是什么?如何解决?

问题是:每次都要创建新的方法存放动物种类。代码的复用性不高,而且不利于代码维护

解决方案:引出我们要讲解的多态

多[多种]态[状态]基本介绍

方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

多态的具体体现

  1. 方法的多态 重写和重载就体现多态
  2. 对象的多态(核心,困难,重点)老韩重要的几句话(记住):
    (1)一个对象的编译类型和运行类型可以不一致
    (2)编译类型在定义对象时,就确定了,不能改变
    (3)运行类型是可以变化的.

(4)编译类型看定义时=号的左边,运行类型看=号的右边

案例:
Animal animal = new Dog();【animal编译类型是Animal,运行类型Dog】
animal = new Cat();【animal的运行类型变成了Cat,编译类型仍然是Animal】

一个父类的对象引用可以指向其子类对象

多态快速入门案例

使用多态的机制来解决主人喂食物的问题,走代码。

传入的实参是 cat和fish,对应形参可以为animal和food

Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

多态注意事项和细节讨论

✔多态的前提是:两个对象(类)存在线承关系
✔多态的向上转型

  1. 本质:父类的引用指向了子类的对象
  2. 语法:父类类型引用名= new子类类型0;
  3. 特点:编译类型看左边,运行类型看右边。
    可以调用父类中的所有成员(需遵守访问权限),不能调用子类中特有成员;
    最终运行效果看子类的具体实现!

向上转型调用方法的规则如下:

  1. 可以调用父类中的所有成员(需遵守访问权限)
  2. 但是不能调用子类的特有的成员
  3. 因为在编译阶段,能调用哪些成员,是由编译类型来决定的
  4. 最终运行效果看子类(运行类型)的具体实现,即调用方法时,按照从子类(运行类型)开始查找方法 然后调用,规则我前面我们讲的方法调用规则一致。

多态注意事项和细节讨论

多态的向下转型

  1. 语法:子类类型 引用名 = (子类类型) 父类引用;【例:Cat cat=(Cat) animal】
  2. 只能强转父类的引用,不能强转父类的对象
  3. 要求父类的引用必须指向的是当前目标类型的对象
  4. 可以调用子类类型中所有的成员

多态注意事项和细节

  1. 属性没有重写之说!属性的值看编译类型(运行调用属性时认准编译类型,在方法中调用属性则是调用该方法所在类中的属性)
  2. instanceof比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型
packapublic class Poly2 {
    public static void main(String[] args) {
        Base base=new Sub();
        base.Aa();//111111
        System.out.println(base.count);//10
        Sub sub=(Sub) base;
        System.out.println(sub.count);//20

        System.out.println(base instanceof Base);//true
        System.out.println(base instanceof Sub);//true
        Object obj = new Object();
        System.out.println(obj instanceof Base); //false
    }
}
class Base {//父类
    int count = 10;//属性
    public void Aa(){
        System.out.println("00000");
    }
}
class Sub extends Base {//子类
    int count = 20;//属性
    public void Aa(){
        System.out.println("111111");
    }
}

java的动态绑定机制(非常非常重要.)

  1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
  2. 当调用对象属性时,没有动态绑定机制,哪里声明,那里使用

多态的应用

  1. 多态数组(Person[] persons = new Person[5];类似于创建数组;其中有persons[0]到person[4]五个对象)
    数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
  2. 多态参数
    方法定义的形参类型为父类类型,实参类型允许为子类类型

Object类详解

equals方法

“==” 和 “equals” 的对比[面试题]

  1. ==:既可以判断基本类型,又可以判断引用类型
  2. ==:如果判断基本类型,判断的是值是否相等。示例: int i=10; double d=10.0;
  3. ==:如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象。
  4. equals:是Object类中的方法,只能判断引用类型(如何看Jdk源码:在对应方法位置ctrl+鼠标左键)
  5. 默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。比如Integer,String【看看String和 Integer的equals源代码】

hashCode方法

  1. 提高具有哈希结构的容器的效率!、
  2. 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!

  3. 两个引用,如果指向的是不同对象,则哈希值是不一样的

  4. 哈希值主要根据地址号来的!,不能完全将哈希值等价于地址。
  5. 案例演示[HashCode_,java]: obj.hashCode()【测试: A obj1 = new A(); A obj2 = new AO);A
    obj3 = obj1】
  6. 后面在集合,中hashCode 如果需要的话,也会重写

toString方法

基本介绍

  1. 默认返回:全类名+@+哈希值的十六进制,【查看Object的toString方法】子类往往重写toString方法,用于返回对象的属性信息
  2. 重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式.案例演示: Monster [name, job, sal]案例:ToString .java
  3. 当直接输出一个对象时,toString方法会被默认的调用,比如System.out.println(monster).

finalize方法

  1. 当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作【演示】
  2. 什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法。
  3. 垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制,测试:Car [name]

提示:我们在实际开发中,几乎不会运用finalize,所以更多就是为了应付面试.

断点调试(debug)

一个实际需求

  1. 在开发中,新手程序员在查找错误时,这时老程序员就会温馨提示,可以用断点调试,一步一步的看源码执行的过程,从而发现错误所在。
  2. 重要提示:在断点调试过程中,是运行状态,是以对象的运行类型来执行的.

断点调试介绍

  1. 断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。进行分析从而找到这个Bug
  2. 断点调试是程序员必须掌握的技能。
  3. 断点调试也能帮助我们查看java底层源代码的执行过程,提高程序员的Java水平。

断点调试的快捷键:

F7(跳入) F8(跳过) shift+F8(跳出) F9(resume,执行到下一个断点)

F7:跳入方法内
F8:逐行执行代码.

shift+F8:跳出方法

Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

小技巧:将光标放在某个变量上,可以看到最新的数据。

Alt+Shift+F7强制跳入(可以用来看数据在源码中的情况)

项目-零钱通

项目需求说明
使用Java 开发零钱通项目,可以完成收益入账,消费,查看明细,退出系统等功能.

项目界面

Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

项目的界面

化繁为简.

  1. 先完成显示菜单,并可以选择
import java.util.Scanner;

public class SmallChangeSys {
    public static void main(String[] args) {
        boolean loop=true;
        Scanner scanner = new Scanner(System.in);
        String key="";
        do {
            System.out.println("==========零钱通菜单===========");
            System.out.println("\t\t1 零钱通明细");
            System.out.println("\t\t2 收益入账");
            System.out.println("\t\t3 消费");
            System.out.println("\t\t4 退   出");

            System.out.println("请选择(1-4):");
            key=scanner.next();

            switch (key){
                case "1":
                    System.out.println("1 零钱通");
                    break;
                case "2":
                    System.out.println("2 收益入账");
                    break;
                case "3":
                    System.out.println("3 消费");
                    break;
                case "4":
                    System.out.println("4 退    出");
                    loop=false;
                    break;
                default:
                    System.out.println("选择有误");
            }
        }while (loop);
        System.out.println("---退出了零钱通---");
    }
}
  1. 完成零钱通明细
  2. 完成收益入账
  3. 完成消费
  4. 完成退出功能
  5. 加入简单的逻辑判断
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class SmallChangeSys {
    public static void main(String[] args) {
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        String key = "";

        String details = "----------------零钱通明细------------------";

        //3.完成收益入账完成功能驱动程序员增加新的变化和代码/老韩思路,定义新的变量
        double money = 0;
        double balance = 0;
        Date date = null; // date 是 java.util.Date类型,表示日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");//可以用于日期格式化的

        String note = "";
        do {
            System.out.println("\n==========零钱通菜单===========");
            System.out.println("\t\t1 零钱通明细");
            System.out.println("\t\t2 收益入账");
            System.out.println("\t\t3 消费");
            System.out.println("\t\t4 退   出");

            System.out.println("请选择(1-4):");
            key = scanner.next();

            switch (key) {
                case "1":
                    System.out.println(details);
                    break;
                case "2":
                    System.out.print("收益入账金额:");
                    money = scanner.nextDouble();// money的值范围应该校验-》一会在完善
                    if (money  balance) {
                        System.out.printf("消费金额应该在0-" + balance + "范围内");
                    }
                    //money 的值范围应该校验-》一会在完善
                    System.out.print("消费说明:");
                    note = scanner.next();
                    balance -= money;
                    //拼接消费信息到details
                    date = new Date();//获取当前日期
                    details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t" + balance;
                    break;
                case "4":
                    String choice = "";
                    while (true) {
                        System.out.printf("确定退出?y/n");
                        choice = scanner.next();
                        if ("y".equals(choice) || "n".equals(choice)) {
                            break;
                        }
                    }
                    if (choice.equals("y")) {
                        loop = false;
                    }
                    break;
                default:
                    System.out.println("选择有误");
            }
        } while (loop);

        System.out.println("---退出了零钱通---");
    }
}
  1. 再将程序改成OOP版本,自行体会OOP编程带来的好处(将各个功能封装到不同方法)
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class SmallChangeSysOOP {
    boolean loop = true;
    Scanner scanner = new Scanner(System.in);
    String key = "";

    String details = "----------------零钱通明细------------------";

    //3.完成收益入账完成功能驱动程序员增加新的变化和代码/老韩思路,定义新的变量
    double money = 0;
    double balance = 0;
    Date date = null; // date 是 java.util.Date类型,表示日期
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");//可以用于日期格式化的
    String note = "";

    //先完成显示菜单,并可以选择
    public void mainMenu() {
        do {
            System.out.println("\n==========零钱通菜单===========");
            System.out.println("\t\t1 零钱通明细");
            System.out.println("\t\t2 收益入账");
            System.out.println("\t\t3 消费");
            System.out.println("\t\t4 退   出");

            System.out.println("请选择(1-4):");
            key = scanner.next();

            switch (key) {
                case "1":
                    this.detail();
                    break;
                case "2":
                    this.income();
                    break;
                case "3":
                    this.pay();
                    break;
                case "4":
                    this.exit();
                    break;
                default:
                    System.out.println("选择有误");
            }
        } while (loop);
    }

    //完成零钱通明细
    public void detail() {
        System.out.println(details);
    }
    public void income(){
        System.out.print("收益入账金额:");
        money = scanner.nextDouble();// money的值范围应该校验-》一会在完善
        if (money  balance) {
            System.out.printf("消费金额应该在0-" + balance + "范围内");
        }
        //money 的值范围应该校验-》一会在完善
        System.out.print("消费说明:");
        note = scanner.next();
        balance -= money;
        //拼接消费信息到details
        date = new Date();//获取当前日期
        details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t" + balance;
    }
    public void exit(){
        String choice = "";
        while (true) {
            System.out.printf("确定退出?y/n");
            choice = scanner.next();
            if ("y".equals(choice) || "n".equals(choice)) {
                break;
            }
        }
        if (choice.equals("y")) {
            loop = false;
        }
    }
}
class SmallChangeSysApp{
    public static void main(String[] args) {
        SmallChangeSysOOP smallChangeSysOOP = new SmallChangeSysOOP();
        smallChangeSysOOP.mainMenu();
    }
}

Original: https://www.cnblogs.com/wenjie2000/p/16479421.html
Author: 文杰2000
Title: Java学习-第一部分-第一阶段-第七节:面向对象编程(中级)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/598872/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • element-ui 提示框 确认按钮在左 取消按钮在右

    添加 //&#x53D6;&#x6D88;&#x6309;&#x94AE; &#x6837;&#x5F0F; cancelButto…

    数据库 2023年6月16日
    076
  • 数据库性能优化八大方案,你知道几个

    前言 毫不夸张的说咱们后端工程师,无论在哪家公司,呆在哪个团队,做哪个系统,遇到的第一个让人头疼的问题绝对是数据库性能问题。 如果我们有一套成熟的方法论,能让大家快速、准确的去选择…

    数据库 2023年6月14日
    078
  • mysql解压版简洁式本地配置方式

    1. 设置全局变量 解压mysql压缩包到指定位置, 然后配置全局变量, 在 path 中添加全局变量, 值为 mysql 根目录下 bin 目录路径, 比如: D:\code_s…

    数据库 2023年5月24日
    0130
  • tomcat

    tomcat 一.简介 二.部署tomcat 一.简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场…

    数据库 2023年6月14日
    087
  • Java 线程是如何启动的?

    Java启动线程的代码: 根据以上代码分析,并从源码了解启动线程发生了以下事件来完成启动线程: 1、Java 创建线程和启动 2、调用本地方法 start0(); 3、JVM 中 …

    数据库 2023年6月16日
    086
  • 5 float f = 3.4,是否正确

    不正确,赋值运算符 “=” 左右两边的精度类型不匹配。 Java中,有小数点的默认被存储为double类型,即双精度;而float类型的变量为单精度。 可以…

    数据库 2023年6月6日
    076
  • MySQL 视图简介

    对数据库中数据的查询有时是非常复杂的,如表连接、子查询等。这种查询很难写,而且容易出错。此外,当您专门操作表时,有时只需要操作部分字段。 [En] The query about …

    数据库 2023年5月24日
    0109
  • centos8 安装python

    镜像:CentOS Linux release 8.5.0-13 python下载地址:Python Source Releases | Python.org 选择所需要的版本,我…

    数据库 2023年6月11日
    0108
  • 小姐姐用动画图解Git命令,一看就懂!

    无论是开发、运维,还是测试,大家都知道Git在日常工作中的地位。所以,也是大家的必学、必备技能之一。之前公众号也发过很多git相关的文章: 但是呢,民工哥,也经常在后台看到读者说,…

    数据库 2023年6月9日
    095
  • springcloud~nacos通过@refreshScope进行配置热更新

    配置类 @Data @ConfigurationProperties("auth") public class AuthProperties { private…

    数据库 2023年6月6日
    087
  • MySQL让人又爱又恨的多表查询

    前言 在SQL开发当中,多表联查是绝对绕不开的一种技能。同样的查询结果不同的写法其运行效率也是千差万别。 在实际开发当中,我见过(好像还写过~)不少又长又臭的查询SQL,数据量一上…

    数据库 2023年5月24日
    080
  • Java 函数式编程

    有且仅有一个未实现的非静态方法的接口叫做”函数式接口” interface IFactory<t> { T create(); } </t…

    数据库 2023年6月6日
    0120
  • null和空字符串对于查询where条件语句的影响

    在数据库中我们进行数据处理的过程中,对于null值或者空字符串的情况对于这种数据我们进行计算平均值以及查询过程中如何进行对于这类数据的处理呢? step1:建表:create ta…

    数据库 2023年6月6日
    099
  • tomcat加载启动过程

    流程图 posted @2022-08-19 17:43 默念x 阅读(9 ) 评论() 编辑 Original: https://www.cnblogs.com/monianxd…

    数据库 2023年6月16日
    089
  • 第十六章:接口

    本篇翻译自《Practical Go Lessons》 Chapter 16: Interfaces 1 你将在本章学到什么? 什么是类型接口? 如何定义接口。 “实现…

    数据库 2023年6月6日
    098
  • MySQL 关于 only_full_group_by 限制

    先上结论 如果 only_full_group_by 被启用,那么在查询时,如果某个列不在group by 列表中,此时如果不对该列进行聚合处理,则该列不能出现在 select 列…

    数据库 2023年6月16日
    0100
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球