阿里Java学习路线:阶段 1:Java语言基础-Java面向对象编程:第30章:链表的定义与使用:课时145:综合实战:超市购物车(含完整代码)

使用面向对象的概念表示出下面的生活场景:小明去超市买东西,所有买到的东西都放在了购物车之中,最后到收银台一起结账。
在这里插入图片描述
在这里插入图片描述
(用购物车标准来降低耦合)

1.定义出一个商品的标准

interface IGoods { // 定义商品标准
	public String getName() ;
	public double getPrice() ;
}

2.定义购物车处理标准

interface IShopCar { // 购物车
	public void add(IGoods goods) ; // 添加商品信息
	public void delete(IGoods goods) ; // 删除商品
	public Object[] getAll() ; // 获得购物车中的全部商品信息
}

3.定义一个购物车的实现类

class ShopCarImpl implements IShopCar { // 购物车
	private ILink<IGoods> allGoodses = new LinkImpl<IGoods>() ;
	public void add(IGoods goods) {
		this.allGoodses.add(goods);
	}
	public void delete(IGoods goods) {
		this.allGoodses.remove(goods);
	}
	public Object [] getAll() {
		return this.allGoodses.toArray() ;
	}
}

4.定义收银台

class Cashier { // 收银台
	private IShopCar shopcar ;
	public Cashier(IShopCar shopcar) {
		this.shopcar = shopcar ;
	}
	public double allPrice() { // 计算总价
		double all = 0.0 ;
		Object result [] = this.shopcar.getAll() ;
		for (Object obj : result) {
			IGoods goods = (IGoods) obj ;
			all += goods.getPrice() ;
		}
		return all ;
	}
	public int allCount() { // 商品数量
		return this.shopcar.getAll().length ;		
	}
}

5.定义商品信息
图书:

class Book implements IGoods {
	private String name ;
	private double price ;
	public Book(String name,double price) {
		this.name = name;
		this.price = price ;
	}
	public String getName() {
		return this.name ;
	}
	public double getPrice() {
		return this.price ;
	}
	public boolean equals(Object obj) {
		if (obj == null) {
			return false ;
		}
		if (this == obj) {
			return true ;
		}
		if (!(obj instanceof Book)) {
			return false ;
		}
		Book book = (Book) obj ;
		return this.name.equals(book.name) && this.price == book.price;
	}
	public String toString() {
		return "[图书信息]名称:" + this.name + "、价格:" + this.price ;
	}
}

背包:

class Bag implements IGoods {
	private String name ;
	private double price ;
	public Bag(String name,double price) {
		this.name = name;
		this.price = price ;
	}
	public String getName() {
		return this.name ;
	}
	public double getPrice() {
		return this.price ;
	}
	public boolean equals(Object obj) {
		if (obj == null) {
			return false ;
		}
		if (this == obj) {
			return true ;
		}
		if (!(obj instanceof Bag)) {
			return false ;
		}
		Bag bag = (Bag) obj ;
		return this.name.equals(bag.name) && this.price == bag.price;
	}
	public String toString() {
		return "[背包信息]名称:" + this.name + "、价格:" + this.price ;
	}
}

6.进行代码测试的编写

public class JavaDemo {
	public static void main(String args[]) {
		IShopCar car = new ShopCarImpl() ;
		car.add(new Book("Java开发",79.8));
		car.add(new Book("Oracle开发",89.8));
		car.add(new Bag("小强背包",889.8));
		Cashier cas = new Cashier(car) ;
		System.out.println("总价格:" + cas.allPrice() + "、购买总数量:" + cas.allCount());
	}
}

整体的代码都是基于链表的功能实现的。

超市购物车完整代码:

interface ILink<E> { // 设置泛型避免安全隐患
	public void add(E e) ; // 增加数据
	public int size() ; // 获取数据的个数
	public boolean isEmpty() ; // 判断是否空集合
	public Object [] toArray() ; // 将集合元素以数组的形式返回
	public E get(int index) ; // 根据索引获取数据
	public void set(int index, E data) ; // 修改索引数据
	public boolean contains(E data) ; // 判断数据是否存在
	public void remove(E e) ; // 数据删除
	public void clean() ; // 清空集合
}
class LinkImpl<E> implements ILink<E> {
	private class Node { // 保存节点的数据关系
		private E data ; // 保存数据
		private Node next ; // 保存下一个引用
		public Node(E data) { // 有数据的情况下才有意义
			this.data = data ;
		}
		// 第一次调用:this = LinkImpl.root;
		// 第二次调用:this = LinkImpl.root.next;
		// 第三次调用:this = LinkImpl.root.next.next;
		public void addNode(Node newNode) { // 保存新的Node数据
			if (this.next == null) { // 当前节点的下一个节点为null
				this.next = newNode ; // 保存当前节点
			} else {
				this.next.addNode(newNode) ;
			}
		}
		// 第一次调用:this = LinkImpl.root
		// 第二次调用:this = LinkImpl.root.next
		// 第三次调用:this = LinkImpl.root.next.next
		public void toArrayNode() {
			LinkImpl.this.returnData [LinkImpl.this.foot ++] = this.data ;
			if (this.next != null) { // 还有下一个数据
				this.next.toArrayNode() ;
			}
		}
		public E getNode(int index) {
			if (LinkImpl.this.foot ++ == index) { // 索引相同
				return this.data ; // 返回当前数据
			} else {
				return this.next.getNode(index) ;
			}
		}
		public void setNode(int index, E data) {
			if (LinkImpl.this.foot ++ == index) { // 索引相同
				this.data = data ; // 修改数据
			} else {
				this.next.setNode(index,data) ;
			}
		}
		public boolean containsNode(E data) {
			if (data.equals(this.data)) { // 对象比较
				return true ;
			} else {
				if (this.next == null) { // 没有后续节点了
					return false ; // 找不到
				} else {
					return this.next.containsNode(data) ; // 向后继续判断
				}
			}
		}
		public void removeNode(Node previous,E data) {
			if (this.data.equals(data)) {
				previous.next = this.next ; // 空出当前节点
			} else {
				if (this.next != null) { // 有后续节点
					this.next.removeNode(this,data) ;  // 向后继续删除
				}
			}
		}
	}
	// ----------------- 以下为Link类中定义的成员 -----------------
	private Node root ; // 保存根元素
	private int count ; // 保存数据个数
	private int foot ; // 描述的是操作数组的脚标
	private Object [] returnData ; // 返回的数组保存
	// ----------------- 以下为Link类中定义的方法 -----------------
	public void add(E e) {
		if (e == null) { // 保存的数据为null
			return ; // 方法调用直接结束
		}
		// 数据本身是不具有关联特性的,只有Node类有,那么要想实现关联处理就必须将数据包装在Node类之中
		Node newNode = new Node(e) ; // 创建一个新的节点
		if (this.root == null) { // 现在没有根节点
			this.root = newNode ; // 第一个节点作为根节点
		} else { // 根节点存在
			this.root.addNode(newNode) ; // 将新节点保存在合适的位置
		}
		this.count ++ ;
	}
	public int size() {
		return this.count ;
	}
	public boolean isEmpty() {
		// return this.root == null ;
		return this.count == 0 ;
	}
	public Object [] toArray() {
		if (this.isEmpty()) { // 空集合
			return null ; // 现在没有数据
		}
		this.foot = 0 ; // 脚标清零
		this.returnData = new Object [this.count] ; // 根据已有的长度开辟数组
		this.root.toArrayNode() ;// 利用Node类进行递归数据获取
		return this.returnData ;
	}
	public E get(int index) {
		if (index >= this.count) { // 索引应该在指定的范围之内
			return null ;
		} // 索引数据的获取应该由Node类完成
		this.foot = 0 ; // 重置索引的下标
		return this.root.getNode(index) ;
	}
	public void set(int index,E data) {
		if (index >= this.count) { // 索引应该在指定的范围之内
			return ; // 方法结束
		} // 索引数据的获取应该由Node类完成
		this.foot = 0 ; // 重置索引的下标
		this.root.setNode(index,data) ; // 修改数据
	}
	public boolean contains(E data) {
		if (data == null) {
			return false ; // 没有数据
		}
		return this.root.containsNode(data) ; // 交给Node类判断
	}
	public void remove(E data) {
		if (this.contains(data)) { // 判断数据是否存在
			if (this.root.data.equals(data)) { // 根节点为要删除节点
				this.root = this.root.next ; // 根的下一个节点
			} else { // 交由Node类负责删除
				this.root.next.removeNode(this.root,data);
			}
			this.count -- ;
		}
	}
	public void clean() {
		this.root = null ; // 后续的所有节点都没了
		this.count = 0 ; // 个数清零
	}
}
interface IGoods { // 定义商品标准
	public String getName() ;
	public double getPrice() ;
}
interface IShopCar { // 购物车
	public void add(IGoods goods) ; // 添加商品信息
	public void delete(IGoods goods) ; // 删除商品
	public Object [] getAll() ; // 获得购物车中的全部商品信息
}
class ShopCarImpl implements IShopCar { // 购物车
	private ILink<IGoods> allGoodses = new LinkImpl<IGoods>() ;
	public void add(IGoods goods) {
		this.allGoodses.add(goods);
	}
	public void delete(IGoods goods) {
		this.allGoodses.remove(goods);
	}
	public Object [] getAll() {
		return this.allGoodses.toArray() ;
	}
}
class Cashier { // 收银台
	private IShopCar shopcar ;
	public Cashier(IShopCar shopcar) {
		this.shopcar = shopcar ;
	}
	public double allPrice() { // 计算总价
		double all = 0.0 ;
		Object result [] = this.shopcar.getAll() ;
		for (Object obj : result) {
			IGoods goods = (IGoods) obj ;
			all += goods.getPrice() ;
		}
		return all ;
	}
	public int allCount() { // 商品数量
		return this.shopcar.getAll().length ;		
	}
}
class Book implements IGoods {
	private String name ;
	private double price ;
	public Book(String name,double price) {
		this.name = name;
		this.price = price ;
	}
	public String getName() {
		return this.name ;
	}
	public double getPrice() {
		return this.price ;
	}
	public boolean equals(Object obj) {
		if (obj == null) {
			return false ;
		}
		if (this == obj) {
			return true ;
		}
		if (!(obj instanceof Book)) {
			return false ;
		}
		Book book = (Book) obj ;
		return this.name.equals(book.name) && this.price == book.price;
	}
	public String toString() {
		return "[图书信息]名称:" + this.name + "、价格:" + this.price ;
	}
}
class Bag implements IGoods {
	private String name ;
	private double price ;
	public Bag(String name,double price) {
		this.name = name;
		this.price = price ;
	}
	public String getName() {
		return this.name ;
	}
	public double getPrice() {
		return this.price ;
	}
	public boolean equals(Object obj) {
		if (obj == null) {
			return false ;
		}
		if (this == obj) {
			return true ;
		}
		if (!(obj instanceof Bag)) {
			return false ;
		}
		Bag bag = (Bag) obj ;
		return this.name.equals(bag.name) && this.price == bag.price;
	}
	public String toString() {
		return "[背包信息]名称:" + this.name + "、价格:" + this.price ;
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		IShopCar car = new ShopCarImpl() ;
		car.add(new Book("Java开发",79.8));
		car.add(new Book("Oracle开发",89.8));
		car.add(new Bag("小强背包",889.8));
		Cashier cas = new Cashier(car) ;
		System.out.println("总价格:" + cas.allPrice() + "、购买总数量:" + cas.allCount());
	}
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值