摘要:以群主发红包为例,带你深入了解继承和super、this关键字。

本文分享自华为云社区《群主发红包带你深入了解继承和super、this关键字》,作者:共饮一杯无 。

需求

群主发随机红包或者普通红包。某群有多名成员,群主给成员发普通红包。

随机红包规则:

  1. 群主的一笔金额,从群主余额中扣除,随机分成n等份,让成员领取。
  2. 成员领取红包后,保存到成员余额中。

普通红包的规则:

  1. 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
  2. 成员领取红包后,保存到成员余额中。

案例分析

案例分析,可以得出如下继承关系:

案例代码实现

定义用户类

/**
* 用户类
* @author zjq
*/
public class User {
/**
* 姓名
*/
private String name;
/**
* 余额,也就是当前用户拥有的钱数
*/
private Integer money;
public User() {
}
public User(String name, Integer money) {
this.name = name;
this.money = money;
}
// 展示一下当前用户有多少钱
public void show() {
System.out.println("我是" + name + ",我有多少钱:" + this.fenToYuan(String.valueOf(money))+"元");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getMoney() {
return money;
}
public void setMoney(Integer money) {
this.money = money;
}
/**
* 分转元
* @param amount
* @return
*/
public String fenToYuan(String amount){
NumberFormat format = NumberFormat.getInstance();
try{
Number number = format.parse(amount);
double temp = number.doubleValue() / 100.0;
format.setGroupingUsed(false);
format.setMaximumFractionDigits(2);
amount = format.format(temp);
} catch (ParseException e){
e.printStackTrace();
}
return amount;
}
}

定义群主类

package com.zjq.javabase.base09.demo14;
import org.apache.commons.lang3.RandomUtils;
import java.util.ArrayList;
/**
* 群主的类
* @author zjq
*/
public class Manager extends User {
/**
* 收到单个红包最大值
*/
private static final int MAX_AMOUNT = 20000;
public Manager() {
}
public Manager(String name, int money) {
// 通过super 调用父类构造方法
super(name, money);
}
/**
* 发红包
* @param totalMoney 红包总金额(单位分)
* @param count 发包个数
* @param type 发包类型(0、随机红包,1、定额红包)
* @return 红包集合
* @throws Exception
*/
public ArrayList<Integer> send(Integer totalMoney, int count,int type) throws Exception {
// 首先需要一个集合,用来存储若干个红包的金额
ArrayList<Integer> redList = new ArrayList<>(count);
// 首先看一下群主自己有多少钱
Integer leftMoney = super.getMoney(); // 群主当前余额
if (totalMoney > leftMoney) {
System.out.println("余额不足");
return redList; // 返回空集合
}
// 扣钱,其实就是重新设置余额
super.setMoney(leftMoney - totalMoney);
if (count == 1) {
redList.add(totalMoney);
return redList;
}
switch (type) {
case 0:
// 默认分配1分至每一位
for (int i = 0; i < count; i++) {
redList.add(1);
}
int surplus_currency = totalMoney - redList.size(),// 剩余金额数
surplus_number = redList.size();// 剩余需追加的数量
for (int i = 0; i < redList.size(); i++) {
// 没值可以追加了
if (new Integer(0).equals(surplus_currency)) {
break;
}
// (总数-(总包-i)*最小值) / (总包 - i) 随机安全值算法
int safe_total = (int)Math.floor((totalMoney - (count - i)) / (count - i));
if (new Integer(0).equals(safe_total)) {// 随机值不能为0
safe_total = 1;
}
// 该次随机值
int randomint = surplus_currency >= safe_total - 1 ? safe_total : surplus_currency + 1;
// 下次可能最大能剩余值
int nextMax_currency = (MAX_AMOUNT - 1) * (surplus_number - 1);
// 最小的随机数 剩余金额-剩余最大随机的总数(不含这一次)
int minRandom = surplus_currency - nextMax_currency;
if (minRandom < 0) {
minRandom = 0;
}
// 规避一些特殊情况,每个接近2000或1时会发生
boolean must = (surplus_currency - count * MAX_AMOUNT <= 2 && surplus_currency - count * MAX_AMOUNT >= 0)
/*|| surplus_currency < packet_number * 2*/;
// 控制安全随机值 随机安全值不能大于最大限制,并且不能小于最小限 制
if (safe_total < minRandom || safe_total > MAX_AMOUNT || must) {
safe_total = MAX_AMOUNT;
// 该次随机值
randomint = surplus_currency >= safe_total - 1 ? safe_total : surplus_currency + 1;
// 下次可能最大能剩余值
nextMax_currency = (randomint - 1) * (surplus_number - 1);
// 最小的随机数 剩余金额-剩余最大随机的总数(不含这一次)
minRandom = surplus_currency - nextMax_currency;
if (minRandom < 0) {
minRandom = 0;
}
}
// 下一次最大的随机值
int nextMaxRandomInt = nextMax_currency - (surplus_currency - (randomint - 1));
Integer maxRandom = nextMaxRandomInt <= 0 ? nextMaxRandomInt + randomint: null;
// 能随机 剩余的金额 - 最大随机数 > 最大随机数 * 剩余数量
boolean canRandom = surplus_currency - (randomint - 1) > nextMax_currency ||
nextMaxRandomInt > (randomint - 1)
|| !new Integer(0).equals(minRandom);
int addNumber; // 追加的金额
if (canRandom && !new Integer(randomint).equals(minRandom+1) && !(new Integer(randomint).equals(minRandom) && new Integer(safe_total).equals(minRandom)) ) {
addNumber = myRandom(minRandom, maxRandom == null ? randomint : maxRandom- 1);
}else {
addNumber = randomint - 1;
}
redList.set(i,redList.get(i) + addNumber);
surplus_currency -= addNumber;
surplus_number--;
}
break;
case 1:
// 定额红包校验
redList = new ArrayList<>(count);
for (int i = 0; i <count; i++) {
//定额红包要是不能整除会有问题,正常实现应该是输入单个红包金额和总数直接就能计算
redList.add(totalMoney/count);
}
break;
default:
throw new Exception("类型错误!");
}
System.out.println("我是" + this.getName() + "我发了"+fenToYuan(String.valueOf(totalMoney))+"元红包"+",我现在有多少钱:" + fenToYuan(String.valueOf(this.getMoney()))+"元");
return redList;
}
/**
* 生成随机金额
* @param min
* @param randomint
* @return
*/
public static int myRandom(int min,int randomint) {
if (min == 0) {
return RandomUtils.nextInt(0,randomint);
}else {
int nextInt = RandomUtils.nextInt(min,randomint - min);
return nextInt + min;
}
}
}

定义成员类

/**
* 普通成员
* @author zjq
*/
public class Member extends User {
public Member() {
}
public Member(String name, Integer money) {
super(name, money);
}
public void receive(ArrayList<Integer> list) {
// 从多个红包当中随便抽取一个,给我自己。
// 随机获取一个集合当中的索引编号
int index = new Random().nextInt(list.size());
// 根据索引,从集合当中删除,并且得到被删除的红包,给我自己
Integer delta = list.remove(index);
// 当前成员自己本来有多少钱:
Integer money = super.getMoney();
// 加法,并且重新设置回去
super.setMoney(money + delta);
System.out.println("我是" + this.getName() + ",我抢到了"+fenToYuan(String.valueOf(delta))+"元红包"+",我现在有多少钱:" + fenToYuan(String.valueOf(this.getMoney()))+"元");
}
}

定义测试类

public class MainRedPacket {
public static void main(String[] args) throws Exception {
Manager manager = new Manager("群主", 10000);
Member member1 = new Member("张三", 1000);
Member member2 = new Member("李四", 1000);
Member member3 = new Member("王五", 1000);
Member member4 = new Member("赵六", 1000);
Member member5 = new Member("孙七", 1000);
Member member6 = new Member("小詹", 1000);
Member member7 = new Member("小明", 1000);
Member member8 = new Member("小红", 1000);
manager.show(); // 100
member1.show(); // 10
member2.show(); // 10
member3.show(); // 10
member4.show(); // 10
member5.show(); // 10
member6.show(); // 10
member7.show(); // 10
member8.show(); // 10
System.out.println("============================");
// 群主总共发20块钱,分成8个红包
ArrayList<Integer> redList = manager.send(2000, 8,0);
// 八个普通成员收红包
member1.receive(redList);
member2.receive(redList);
member3.receive(redList);
member4.receive(redList);
member5.receive(redList);
member6.receive(redList);
member7.receive(redList);
member8.receive(redList);
}
}

结果输出如下:

点击关注,第一时间了解华为云新鲜技术~

为了讲明白继承和super、this关键字,群主发了20块钱群红包的更多相关文章

  1. oop面向对象【继承、super、this、抽象类】

    今日内容 1.三大特性——继承 2.方法重写 3.super关键字 4.this关键字 5.抽象类 教学目标 1.能够解释类名作为参数和返回值类型 2.能够写出类的继承格式 3.能够说出继承的特点 4 ...

  2. Java(152-170)【继承、super、this、抽象类】

    1.继承的概述 继承是多态的前提 继承主要解决的问题是共性抽取 2.继承的格式 在继承的关系中,子类可以当做父类看待 代码复用的效果 package cn.itcast.day09.demo01; / ...

  3. java基础11 继承(super、extends关键字和重写,这三个要素出现的前提:必须存在继承关系)

    面向对象的三大特征: 1.封装   (将一类属性封装起来,并提供set()和get()方法给其他对象设置和获取值.或者是将一个运算方法封装起来,其他对象需要此种做运算时,给此对象调用) 2.继承   ...

  4. 【ZZ】终于有人把云计算、大数据和人工智能讲明白了!

    终于有人把云计算.大数据和人工智能讲明白了! https://mp.weixin.qq.com/s/MqBP0xziJO-lPm23Bjjh9w 很不错的文章把几个概念讲明白了...图片拷不过来... ...

  5. Java 学习(11): 面向对象编程—继承(super,this)

    Java 继承 what: 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为.子类从它的父类中继承可访问的数据域和方法,也 ...

  6. Python大神必须掌握的技能:多继承、super和MRO算法

    本文主要以Python3.x为例讲解Python多继承.super以及MRO算法. 1. Python中的继承 任何面向对象编程语言都会支持继承,Python也不例外.但Python语言却是少数几个支 ...

  7. 01 语言基础+高级:1-4 接口与多态_day09【继承、super、this、抽象类】

    day09[继承.super.this.抽象类] 三大特性——继承方法重写super关键字this关键字抽象类 教学目标能够解释类名作为参数和返回值类型能够写出类的继承格式能够说出继承的特点能够说出子 ...

  8. 继承 派生 super()经典类 新式类

    '''1什么是继承? 继承一种新建类的方式,在python中支持一个儿子继承多个爹 新建的类称为子类的或者派生类 父类有可以称为基类或者超类 子类会‘遗传’父类的属性 2 为什么要用继承 减少代码冗余 ...

  9. 没讲明白的水题orz

    有一道解释程序的水题没给非计算机专业的同学讲明白orz,在这里再练一下.. 源代码完全没有缩进真是难以忍受.. p.s.懂递归就不用看了#include <stdio.h> int n = ...

随机推荐

  1. 手把手教你springboot集成微信支付

    20220727 最近要做一个微信小程序,需要微信支付,所以研究了下怎么在 java 上集成微信支付功能,特此记录下. 本文完整代码:点击跳转 准备工作 小程序开通微信支付 首先需要在微信支付的官网点 ...

  2. Luogu1919 【模板】A*B Problem升级版(FFT)

    简单的\(A*B\) \(Problem\),卡精度卡到想女装 #include <iostream> #include <cstdio> #include <cstri ...

  3. 10种有用的Linux Bash_Completion 命令示例

    摘要:我们可以对这个 bash 补全进行加速,并使用 complete 命令将其提升到一个新的水平. 本文分享自华为云社区<有用的 Linux Bash_Completion 命令示例(Ster ...

  4. 3-14 Python处理XML文件

    xml文件处理 什么是xml文件? xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. 从结构上,很像HTML超文本标记语言.但他们被设计的目的 ...

  5. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  6. 「题解报告」SP16185 Mining your own business

    题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...

  7. 在Linux下配置RealVNC和TigerVNC

    作者:alittlemc | 更新中 | 原创文章,可能有技术理解错误,欢迎指正,请与我联系,谢谢! 命令和快速总结 realvnc创建# :会话id -name 取名字 -depth 色深 -geo ...

  8. PostgreSQL 大对象导出报错问题分析

    1.前言 在处理用户问题过程遇到一个问题.用户通过pg_dump导出 bytea 对象时,当行的大小超过 1G时,会报错: [v8r6c5b41@dbhost01 ~]$ sys_dump -t t1 ...

  9. maven执行跳过测试

    -Dmaven.test.skip=true 例子 mvn clean install -Dmaven.test.skip=true

  10. 手把手教你用Java获取IP归属地

    前几个月微信公众号上线了IP归属地的功能,后续知乎.抖音等平台纷纷添加了该功能.如果是国内的用户精确到省份,国外用户精确到国家.本文就使用Java实现获取IP归属地. ! 主要讲解几个步骤: Java ...