Java基础-继承、super、this、抽象类(群主发红包案例附代码)

一、继承

1.1 概述

由来多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要 继承那一个类即可。如图所示:
在这里插入图片描述

定义

继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接 访问父类中的非私有的属性和行为。
在这里插入图片描述

1.2 继承的格式

通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:
在这里插入图片描述
继承演示,代码如下:

package extendsDemo;
/**
 * 定义一个父类:员工类
 */

class Employee {
    //一个类中包含属性和行为
    String name;//定义属性
    //定义行为:员工的工作方法
    public void work(){
        System.out.println("全身心地投入到工作中");
    } 
}
/*定义一个子类:讲师类,继承员工类*/
class Teacher extends Employee{
    //子类会继承父类的属性和行为
    public void printname(){
        System.out.println("name="+name);
    }
}
/**定义测试类 */
class extendsTest{
    public static void main(String[] args) {
        //创建一个讲师类对象
        Teacher teacher=new Teacher();
        //为员工类的name属性进行赋值
        teacher.name="张三";
        //调用该员工的printname()方法
        teacher.printname();
        //调用teacher继承来的work()方法
        teacher.work();
    }

}

运行结果:
在这里插入图片描述

1.3 继承后的特点——成员变量

在这里插入图片描述

package extendsDemo;

class Fu {
    //定义父类中的成员变量
    int num=5;
}
class Zi extends Fu{
    //子类中的成员方法及成员方法
    int num2=6;
    public void show(){
        System.out.println("Fu num="+num);//继承过来,直接访问
        System.out.println("Zi num="+num2);
    }
}
class extendsDemo02{
    public static void main(String[] args) {
        //创建一个子类对象
        Zi zi=new Zi();
        //调用子类中的方法
        zi.show();
    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述

package extendsDemo;

class Fu {
    //定义父类中的成员变量
    int num=5;
}
class Zi extends Fu{
    //子类中的成员方法及成员方法
    int num=6;
    public void show(){
        System.out.println("Fu num="+num);//继承过来,直接访问
        System.out.println("Zi num="+num);
    }
}
class extendsDemo02{
    public static void main(String[] args) {
        //创建一个子类对象
        Zi zi=new Zi();
        //调用子类中的方法
        zi.show();
    }
}

运行结果:
在这里插入图片描述
子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用 super 关键字,修饰 父类成员变量,类似于之前学过的 this 。
使用格式:

super.父类成员变量名

子类方法需要修改,代码如下:

class Zi extends Fu { 
// Zi中的成员变量 
int num = 6; 
public void show() { 
//访问父类中的num 
System.out.println("Fu num=" + super.num); //访问子类中的num System.out.println("Zi num=" + this.num); 
   } 
}
演示结果: 
Fu num = 5 
Zi num = 6

在这里插入图片描述

1.4 继承后的特点——成员方法

成员方法不重名

如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对 应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。代码如下:

class Fu{ 
    public void show(){
       System.out.println("Fu类中的show方法执行"); 
   } 
}
 class Zi extends Fu{ 
    public void show2(){ 
        System.out.println("Zi类中的show2方法执行"); 
    } 
 }
 public class ExtendsDemo04{ 
    public static void main(String[] args) { 
      Zi z = new Zi(); //子类中没有show方法,但是可以找到父类方法去执行 z.show();
      z.show();
      z.show2();
  } 
 }

成员方法重名——重写(Override)

如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。 方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效 果,也称为重写或者复写。声明不变,重新实现。 代码如下:

class Fu {  
   public void show() { 
      System.out.println("Fu show"); 
   }
}
class Zi extends Fu { 
//子类重写了父类的show方法 
    public void show() { 
        System.out.println("Zi show"); 
     } 
}
public class ExtendsDemo05{ 
      public static void main(String[] args) { 
          Zi z = new Zi(); // 子类中有show方法,只执行重写后的show方法 
          z.show(); // Zi show 
      } 
}

重写的应用

子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从 而进行扩展增强。比如新的手机增加来电显示头像的功能,代码如下:

class Phone { 
     public void sendMessage(){ 
        System.out.println("发短信"); 
     }
    public void call(){ 
       System.out.println("打电话"); 
    }
    public void showNum(){ 
      System.out.println("来电显示号码"); 
   } 
}
//智能手机类 
class NewPhone extends Phone { 
//重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能 
      public void showNum(){ 
         //调用父类已经存在的功能使用
        super super.showNum(); 
       //增加自己特有显示姓名和图片功能 
       System.out.println("显示来电姓名"); 
       System.out.println("显示头像"); 
      } 
}
public class ExtendsDemo06 { 
      public static void main(String[] args) { 
      // 创建子类对象 
      NewPhone np = new NewPhone()// 调用父类继承而来的方法 
      np.call(); // 调用子类重写的方法 
      np.showNum(); 
     } 
}

在这里插入图片描述

1.6 super和this

在这里插入图片描述
在这里插入图片描述

super和this的用法

  1. 访问成员
    在这里插入图片描述
    用法演示,代码如下:
class Animal { 
  public void eat() { 
    System.out.println("animal : eat"); 
 } 
}
class Cat extends Animal {
  public void eat() { 
    System.out.println("cat : eat"); 
  }
  public void eatTest() { 
    this.eat(); // this 调用本类的方法 
    super.eat(); // super 调用父类的方法 
  } 
}
 public class ExtendsDemo08 { 
    public static void main(String[] args) { 
      Animal a = new Animal(); 
      a.eat(); 
      Cat c = new Cat(); 
      c.eatTest(); 
   } 
 }
 输出结果为: 
 animal : eat 
 cat : eat 
 animal : eat
  1. 访问构造方法
    在这里插入图片描述

1.7 继承的特点

  1. Java只支持单继承,不支持多继承。
    在这里插入图片描述

  2. Java支持多层继承(继承体系)。
    在这里插入图片描述

  3. 子类和父类是一种相对的概念。

二、抽象类

2.1 概述

由来
父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有 意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法 的类就是抽象类。 定义
抽象方法 : 没有方法体的方法。 抽象类:包含抽象方法的类。

2.2 abstract使用格式

抽象方法

使用 abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。 定义格式:

修饰符 abstract 返回值类型 方法名 (参数列表)

代码举例:

public abstract void run()

抽象类

如果一个类包含抽象方法,那么该类必须是抽象类。
定义格式:

abstract class 类名字 { }

代码实例:

public abstract class Animal {
 public abstract void run()}

抽象的使用

继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父 类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。
代码举例:
在这里插入图片描述
此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法。

2.3 注意事项

关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。 理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。
  2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。 理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。
  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
    理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设 计。
  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象 类。理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有 意义。

三、继承的综合案例

3.1 综合案例:群主发普通红包

群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则:

  1. 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
  2. 成员领取红包后,保存到成员余额中。 请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。

3.2 案例分析

在这里插入图片描述

3.3 案例实现

1、User类

package javawork;

public class User {
	private String userName;
	private int surplus;
	
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	public User(String userName, int surplus) {
		super();
		this.userName = userName;
		this.surplus = surplus;
	}
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public int getSurplus() {
		return surplus;
	}
	public void setSurplus(int surplus) {
		this.surplus = surplus;
	}
	
	// 展示当前用户余额
	public void show() {
		System.out.println("用户名:" + userName + ",剩余钱数:" + surplus + "元");
	}
}

2、Master类

package javawork;

import java.util.ArrayList;

public class Master extends User{
	public Master() {
		
	}
    public Master(String userName,int surplus) {
    	super(userName,surplus);
    }
    public ArrayList<Integer> send(int totalMoney, int count) {
		//初始化红包集合
		ArrayList<Integer> redList = new ArrayList<>();
		int leftMoney = super.getSurplus();
		if (totalMoney > leftMoney) {
			System.out.println("余额不足!");
			return redList;
		}
		super.setSurplus(leftMoney - totalMoney);
		int avg = totalMoney / count;
		int mod = totalMoney % count;
		// 剩下的零头包在最后的红包当中
		// 将红包金额放入集合中
		for (int i = 0; i < count; i++) {
			redList.add(avg);
		}
		int last = avg + mod;
		redList.add(last);
		return redList;
	}
}

3、Members类

package javawork;

import java.util.ArrayList;
import java.util.Random;

public class Members extends User {
	public Members() {
		super();
	}
    public Members(String userName,int surplus) {
    	super(userName,surplus);
    }
    public void receive(ArrayList<Integer> list) {
		// 从多个红包当中随便抽取一个,给自己
		int index = new Random().nextInt(list.size());
		// 根据索引,从集合中删除,并且得到被删除的红包,给我自己
		int delta = list.remove(index);
		// 获取成员余额
		int money = super.getSurplus();
		// 更新成员余额
		super.setSurplus(delta + money);
	}
}

4、SendMoney类

package main;

import java.util.ArrayList;

import javawork.Master;
import javawork.Members;

public class SendMoney {
	

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Master manager = new Master("群主", 100);
		Members one = new Members("成员1", 0);
		Members two = new Members("成员2", 0);
		Members three = new Members("成员3", 0);
		// 获取用户余额
		manager.show();
		one.show();
		two.show();
		three.show();
		// 发红包,红包送额,红包数
		ArrayList<Integer> redList = manager.send(10, 3);
		one.receive(redList);
		two.receive(redList);
		three.receive(redList);
		// 发第一次红包后的个人余额
		one.show();
		two.show();
		three.show();
		manager.show();
		// 发第二次红包,红包送额,红包数
		ArrayList<Integer> redList1 = manager.send(20, 3);
		one.receive(redList1);
		two.receive(redList1);
		three.receive(redList1);
		// 发第二次红包后的余额;
		one.show();
		two.show();
		three.show();
		manager.show();

	}

}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小辉在线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值