【面向对象课程项目:纸牌】Java实例学习(一):优秀源码的分析

本文通过分析一个Java实现的纸牌游戏项目,探讨了其面向对象的设计思路。文章首先介绍了项目的基本框架,强调了清晰的类结构和继承的使用。接着详细讲解了`Card`类和`CardPile`抽象类的设计,展示了如何利用OO思想简化代码。`DeckPile`、`DiscardPile`、`SuitPile`和`TablePile`类的实现展示了代码复用和特定功能的覆盖。最后,作者提到了`MainGame`类和`MainWindow`类在整合组件和用户交互中的作用。文章指出,虽然部分抽象方法可能在某些子类中多余,但整体设计仍体现了良好的代码组织和OO原则。
摘要由CSDN通过智能技术生成

前言:

十月份中旬的时候,面向对象的课程项目出来了.3个题目,个人认为都不是很难
  1. 一个是 Java排序包的实现<要求体现 OO的编程思想,必做>
  1. 面向对象的纸牌
  1. 面向对象的音乐播放器(要求有波形图和界面)
2.3是选做其中一个,当时为了早些交上(其实真实目的是为了装X...=  =|),所以选择了前两个.看了一下有关纸牌的游戏规则,连思路都没想好就开始写,3天以后就交了,本来以为自己写的还不错,最后交上去了还是最早的.当时很是得瑟了一阵...可是最后看了一眼别人交上去的代码,不仅仅在代码的质量,复用度,还是实现思路上,都有比自己优秀的多的地方.细活出精品啊,自己还是没有理解为什么要把这个项目的时间放宽,就是为了让我们更好地,有更充裕的时间去写出更好,更优秀的代码.这个系列的3篇文章主要是记录两个版本的纸牌(一个是自己的渣渣版本,另个是学姐写的让我看了以后内牛满面的优秀作品...唉,稍稍对比一下就会发现自己的差距),以备以后查阅 以及 加深对Swing技术与 面向对象 OO的理解.这里是第一篇,对优秀版本代码的解读.


一.整体框架的阅读:

    1. 不多说,先上整体的结构组织图:实际运行的效果与布局图 首先看看CardMethod(实际为model)中的类Card:
    2. package CardMethod;
      
      public class Card
      {
      	private int suit;//1-4
      	private int rank;//1-13
      	private boolean isRed;
      	private boolean faceUp;
      	private int num;//1-52
      	
      	public Card(int n)
      	{
      		num=n;
      		if(n%13==0)
      		{
      			suit=n/13;
      			rank=13;
      		}
      		else
      		{
      			suit=n/13+1;
      			rank=n%13;
      		}
      		if(suit%2==1)
      			isRed=true;
      		else
      			isRed=false;
      		faceUp=false;
      	}
      	
      	public boolean isFaceUp()
      	{
      		return faceUp;
      	}
      	
      	public void setFaceUp(boolean on)
      	{
      		faceUp=on;
      	}
      	
      	public int getSuit()
      	{
      		return suit;
      	}
      	
      	public boolean isRed()
      	{
      		return isRed;
      	}
      	
      	public int getNum()
      	{
      		return num;
      	}
      	
      	public int getRank()
      	{
      		return rank;
      	}
      }
      
      组织结构十分清晰明了,为了后面判断的方便,这里加入了一个isRed的属性,在后面判断牌堆是否异色,移动是否合法的时候会用到此冗余属性.但是个人这里有个缺点,在没有定义 颜色 与 号码的对应情况下,52张牌用取余来决定于判断花色,让人有不直观的感觉,个人觉得应该在这个类里面定义static final 常量,这样才能够更直接的反映花色. 
    3. 作者十分精明的观察到了整个游戏内的几个组件都有共同的特性(这一点在和自己源码的对比中还会说到).这也是我在第一次的实际中看到Abstract Class的运用,一个ArrayList<Card>的组织划分,让所有的组件对自己区域内的卡片有了统一的操作规范.这是非常重要的,另外,这里使用了继承,极大的减轻了设计不同模块的代码冗余的负担.自己以前在书本上看到过那种"没有使用继承而带来的垃圾代码过多的现象"在实际项目开发的时候,就这样不知不觉的发生在了我的身上,这对于自诩为"对OO思想了解透彻的"我来讲是不可想象的.代码虽然没有注释,但是结构清晰合理,让人一看便知:
      package CardMethod;
      import java.util.ArrayList;
      
      
      
      public abstract class CardPile 
      {
      	public ArrayList<Card> pokers;
      	
      	public CardPile()
      	{
      		pokers=new ArrayList<Card>();
      	}
      	
      	public int getSize()
      	{
      		return pokers.size();
      	}
      	
      	public Card getTop()//获得牌堆顶牌
      	{
      		if(pokers.size()>0)
      			return pokers.get(pokers.size()-1);
      		return null;
      	}
      	
      	public Card getCard(int index)
      	{
      		return pokers.get(index);
      	}
      	
      	
      	public boolean isEmpty()
      	{
      		if(pokers.size()>0)
      			return false;
      		return true;
      	}
      	
      	public  void addCard(CardPile pile,int index)
      	{
      		for(int i=index;i<pile.getSize();i++)
      			pokers.add(pile.getCard(i));
      	}
      	
      	public void removeCard(int index)//从顶牌开始删除size-index张牌
      	{
      		int size=getSize();
      		for(int i=size-1;i>=index;i--)
      			pokers.remove(i);
      	}
      	
      	public abstract int getCardIndex(int suit,int rank);//对于suitPiles获得应该放入suit的                            位置public abstract int getCardIndex(boolean isRed,int rank);//获得第一张颜色相反的牌,用于同时移动几张已排好的牌}
      	
    4. 接下来其他的几个模型(如 deck pile ,discard pile ,table piles ,suit piles ),都是用了继承自以上的 CardPile.代码复用效果非常好,但是有的组件,如deckpile是用不到这里的两个abstract方法的,也必须实现.这个在设计中是否有规避的办法?值得思考
      package CardMethod;
      
      public class DeckPile extends CardPile
      {
      	public void initadd(Card card)
      	{
      		pokers.add(card);
      	}
      
      	@Override
      	public void addCard(CardPile pile, int index) // 增加牌。
      	{
      		// TODO Auto-generated method stub
      		for (int i = index; i >= 0; i--)
      		{
      			pokers.add(pile.getCard(i));
      		}
      		pile.getTop().setFaceUp(false);
      	}
      
      	@Override
      	public int getCardIndex(int suit, int rank)
      	{
      		// TODO Auto-generated method stub
      		return -1;
      	}
      
      	@Override
      	public int getCardIndex(boolean isRed, int rank)
      	{
      		// TODO Auto-generated method stub
      		return -1;
      	}
      
      }
      

      package CardMethod;
      
      //丢弃堆
      public class DiscardPile extends CardPile
      {
      
      	public void clear()
      	{
      		pokers.clear();
      	}
      
      	public void addCard(CardPile pile, int index)
      	{
      		// TODO Auto-generated method stub
      		super.addCard(pile, index);
      		if (!isEmpty())		this.getTop().setFaceUp(true);
      	}
      
      	public void removeCard(int index)
      	{
      		// TODO Auto-generated method stub
      		super.removeCard(index);
      		if (!isEmpty())
      			this.getTop().setFaceUp(true);
      	}
      
      	public int getCardIndex(int suit, int rank)
      	{
      		// TODO Auto-generated method stub
      		if (!this.isEmpty() && this.getTop().getSuit() == suit
      				&& this.getTop().getRank() == rank)
      			return this.getSize() - 1;
      		return -1;
      	}
      
      	@Override
      	public int getCardIndex(boolean isRed, int rank)
      	{
      		// TODO Auto-generated method stub
      		if (!this.isEmpty() && this.getTop().isRed() != isRed
      		
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值