##抽象类##
- 概述
在继承和多态时,讲到了父类的方法多数时候,是要被子类们重写,且各自的实现不尽相同。那么对于父类来说,其方法声明还有用,方法体就没用了,这样在父类中,就只保留方法的声明和空的方法体。这种没有方法体的方法称为抽象方法。java语言规定,包含抽象方法的类就是抽象类。
- abstract关键字
使用abstract关键字修饰抽象类以及抽象方法,例如:
public abstract class Animal {
public abstract void run();
}
- 抽象类的使用规定
继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父
类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。
1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。
这些也好理解,首先定义抽象类,目的就是不想让创建该类对象,只需要对子类创建对象即可,而子类在创建对象的时候,要先初始化父类,所以抽象类是可以有构造方法的,子类是可以生成对象的,所以就不能包含抽象方法,所以类中要对父类的抽象方法全部进行重写覆盖。
# 继承的综合案例 #
- 需求分析:
群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则:
1. 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
2. 成员领取红包后,保存到成员余额中。
请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。
-案例分析
![adc7decaa3bf422c0db7f6a7970f002d.png](https://img-blog.csdnimg.cn/img_convert/adc7decaa3bf422c0db7f6a7970f002d.png)
一个父类user,两个成员变量username与money,一个成员方法show;子类一群主,自定义方法发红包;子类二成员类,自定义方法收红包;
-案例实现
定义用户类
public class User{
private String suername;
private double money;
public User(){}
public User(String username,double money){
this.username = username;
this.money = money;
}
public String getUsername(){
return username;
}
public String setUsername(String username){
this.username = username;
}
public String getMoney(){
return money;
}
public String setMoney(double money){
this.money = money;
}
public void show(){
System.out,println("用户名:"+username+",余额为:"+money+"元");
}
}
定义群主类
public class QunZhu extenmds User{
public QunZhu(){}
public QunZhu(String username,double money){
super(username, leftMoney);
}
/*
群主发红包,就是把一个整数的金额,分层若干等份。
1.获取群主余额,是否够发红包.
不能则返回null,并提示.
能则继续.
2.修改群主余额.
3.拆分红包.
3.1.如果能整除,那么就平均分。
3.2.如果不能整除,那么就把余数分给最后一份。
*/
public ArrayList<Double> send(jint money,int count){
double leftMoney = getMoney();
if(money>leftMoney){
return null;
}
setMoney(leftMoney - money);
ArrayList<Double> list = new ArrayList<>();
money = money * 100;
// 每份的金额
int m = money / count;
// 不能整除的余数
int l = money % count;
// 无论是否整除,n‐1份,都是每份的等额金额
for(inti=0;i<count‐1;i++){
// 缩小100倍,折算成 '元'
list.add(m/100.0);
}
// 判断是否整除
if(l==0){
// 能整除, 最后一份金额,与之前每份金额一致
list.add(m/100.0);
}else{
// 不能整除, 最后一份的金额,是之前每份金额+余数金额
list.add((m+l)/100.00);
}
// 返回集合
return list;
}
}
定义成员类
public class Member extends User {
public Member() {
}
public Member(String username, double leftMoney) {
super(username, leftMoney);
}
// 打开红包,就是从集合中,随机取出一份,保存到自己的余额中
public void openHongbao(ArrayList<Double> list) {
// 创建Random对象
Random r = new Random();
// 随机生成一个角标
int index = r.nextInt(list.size());
// 移除一个金额
Double money = list.remove(index);
// 直接调用父类方法,设置到余额
setMoney(money);
}
}
定义测试类:
public class Test {
public static void main(String[] args) {
// 创建一个群主对象
QunZhu qz = new QunZhu("群主" , 200);
// 创建一个键盘录入
Scanner sc = new Scanner();
System.out.println("请输入金额:");
int money = sc.nextInt();
System.out.println("请输入个数:");
int count = sc.nextInt();
// 发送红包
ArrayList<Double> sendList = qz.send(money,count);
// 判断,如果余额不足
if(sendList == null){
System.out.println(" 余额不足...");
return;
}
// 创建三个成员
Member m = new Member();
Member m2 = new Member();
Member m3 = new Member();
// 打开红包
m.openHongbao(sendList);
m2.openHongbao(sendList);
m3.openHongbao(sendList);
// 展示信息
qz.show();
m.show();
m2.show();
m3.show();
}
}