2013-08-03 198 views
-3

有點新,所以讓我知道如果我格式化的東西不正確。充分披露這是一個Java類的介紹。希望對概念或其他示例進行一些普遍推理。讓我儘可能簡單地把它打破。我們已經在java中建立了Yahtzee型骰子游戲的基礎。我們目前的指示如下:創建一個名爲Yahtzee的課程。 Yahtzee課程持有遊戲的五個骰子。添加以下方法:Jave繼承和抽象類

鎖定:一種保留骰子的方法(也就是說,不要將骰子包含在下一個卷中)。提示:爲模具類添加一個鎖定變量。解鎖:釋放骰子的方法(即在下一個骰子中包含骰子) UnlockAll:釋放手中所有骰子的方法。 卷軸:一種只能發佈釋放的骰子的方法。提示:將模具類中的滾動方法更改爲僅在模具解鎖時滾動。顯示:顯示當前骰子值的方法。

創建一個名爲Player的抽象類。添加以下方法:

玩:一種方法,以打圓(最多3卷) 選擇:一種抽象方法,來決定要保留的骰子或釋放(從Play方法調用) 名稱:一種方法來設置玩家的名字。此類的構造函數調用設置播放器名稱的方法。

創建一個名爲Human的播放器的子類。人類玩家在鍵盤上詢問人應該保留或釋放骰子。當設置的玩家姓名方法被調用時,它也會向鍵盤上的人詢問他的名字。

創建一個名爲Computer的播放器的子類。計算機播放器保持具有大部分相同值的骰子並釋放其餘部分。當被問及名字時,它稱自己爲「鮑里斯」。

您的主程序建立了一個人類和計算機播放器。然後它會告訴每個玩家回合並顯示他們回合的結果。然後它會詢問是否應該進行另一輪比賽。

public class OneDice {// class for an individual dice 
    private int die; 
    int lock = 0; 

     public OneDice() { 
     die = (int)(Math.random()*6) + 1; 
     } 

     public void roll() {// random 
      if(lock != 1){ 
      die = (int)(Math.random()*6) + 1; 
      } 
     } 


     public int value() { 
       // return the value of the die variable 
      return die; 
     } 

     public void lockDice(){ 
     lock = 1; 
     } 

     public void unlockDice(){ 
     lock = 0; 
     } 


} 

public class Yahtzee extends OneDice {   

    OneDice dice1 = new OneDice(); 
    OneDice dice2 = new OneDice(); 
    OneDice dice3 = new OneDice(); 
    OneDice dice4 = new OneDice(); 
    OneDice dice5 = new OneDice(); 

    public Yahtzee(){ 
     yahtzeeRoll(); //constructor 
    } 
    public void yahtzeeRoll(){   
    dice1.roll(); 
    dice2.roll(); 
    dice3.roll(); 
    dice4.roll(); 
    dice5.roll(); 
    } 

//這裏是我的鎖定和解鎖的Yahtzee類

public void lock(int which){ 


      switch (which){ 

      case 1: dice1.lockDice(); 
       break; 
      case 2: dice2.lockDice(); 
       break; 
      case 3: dice3.lockDice(); 
       break; 
      case 4: dice4.lockDice(); 
       break; 
      case 5: dice5.lockDice(); 
       break;  
      } 

     } 

     public void unlock(int which){ 
      switch (which){ 

      case 1: dice1.unlockDice(); 
       break; 
      case 2: dice2.unlockDice(); 
       break; 
      case 3: dice3.unlockDice(); 
       break; 
      case 4: dice4.unlockDice(); 
       break; 
      case 5: dice5.unlockDice(); 
       break;  
      } 
     } 

     public void unlockAll(){ 
      dice1.unlockDice(); 
      dice2.unlockDice(); 
      dice3.unlockDice(); 
      dice4.unlockDice(); 
      dice5.unlockDice(); 
     } 
     public void printYahtzee(){ //prints the dice 
     System.out.println("dice 1 comes up= " + dice1.value()); 
     System.out.println("dice 2 comes up= " + dice2.value()); 
     System.out.println("dice 3 comes up= " + dice3.value()); 
     System.out.println("Dice 4 comes up= " + dice4.value()); 
     System.out.println("Dice 5 comes up= " + dice5.value()); 

     } 
} 

So the instructor helped me all the previous code so more of less that should be solid. Here is my Player class. 

public abstract class Player extends Yahtzee { 

private String name; 
String choice; 
Yahtzee hand = new Yahtzee(); 

    public Player(){ 
     getName(); 
    }  




    public void play(int which){ 

     while(i <3){ 
     hand.yahtzeeRoll(); 
     hand.printYahtzee(); 
     choose(which); 
     }  
    } 

的方法,我應該使用擴展的方法,而不是在播放器類創建一個新的對象以「手」?這是繼承和創建這個類的全部點嗎?

abstract public void choose(int which);{ 
    System.out.println("which would you like to go hold (1), unlock (2), or unlock all(3)"); 
    int choice = sc.nextInt(); 

     switch (choice){ 

      case 1: hand.lock(which); 
       break; 
      case 2: hand.unlock(which); 
       break; 
      case 3: hand.unlockAll(); 
       break; 
      } 

    } 

    public void getName(){ 
    System.out.println("What is your name?: "); 
    name = sc.nextLine();  
    } 

    public void setName(){ 
    System.out.println("Player " + name);  
    } 
} 

我試圖使我的抽象類傳遞一個「int which」參數從主選擇哪個骰子鎖定解鎖。但它不喜歡我的哪個參數,但它不介意Yahtzee類/ lock解鎖方法中的這個參數。有什麼想法嗎?此外,我試圖重讀和理解如何使用抽象類。任何人都會有關於如何在人類或計算機子類中實現我的抽象類的一些提示或建議。我開始研究這些部分,這只是一團糟。

+1

你的風格是嘮叨的方式。完全專注的專注可能需要將近半小時的時間,通讀所有這些內容並制定答案。這不是StackOverflow的工作方式;我們每個問題的關注時間約爲5分鐘。你需要適應你的問題。 –

+0

完全明白。我不想成爲社區的負擔,因爲我似乎有一些downvotes:/只是尋求幫助除了從stackoverflow的任何建議?我試圖看看教程和指南,但我仍然有麻煩,但只是想從一個人的實際幫助。再次感謝。 – landres

回答

2

在@ Hovercraft的要點上展開,並且如討論的here,請注意,抽象類可以同時具有具體方法和抽象方法。前者可以被所有子類訪問,而後者必須爲每個子類實現。在這個遊戲中,HumanComputer都可以使用play(),但每個使用choose()的不同實現。在下面的示例中,請注意Play如何調用抽象player.play(),該抽象又調用屬於給定具體子類的正確choose()方法。同樣,Computer構造函數始終指定名稱「Boris」,而構造函數則提示用戶輸入名稱。

import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

/** 
* @see http://stackoverflow.com/a/18040085/230513 
*/ 
public class Test { 

    private abstract class Player { 

     private String name; 

     public Player(String name) { 
      this.name = name; 
     } 

     public void play() { 
      choose(); 
     } 

     abstract public void choose(); 

     public void setName(String name) { 
      this.name = name; 
     } 

     public String getName() { 
      return name; 
     } 
    } 

    private class Human extends Player { 

     public Human() { 
      super(JOptionPane.showInputDialog(null, "Name")); 
     } 

     @Override 
     public void choose() { 
      System.out.println(getName() + " choosing."); 
      // check user selection 
     } 

     @Override 
     public void setName(String name) { 
      super.setName(name); 
     } 
    } 

    private class Computer extends Player { 

     public Computer() { 
      super("Boris"); 
     } 

     @Override 
     public void choose() { 
      System.out.println(getName() + " choosing."); 
      // select majority 
     } 
    } 

    private JPanel createPlayerPanel(final Player player) { 
     JPanel panel = new JPanel(); 
     panel.add(new JLabel(player.getName(), JLabel.CENTER)); 
     panel.add(new JButton(new AbstractAction("Play") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       player.play(); 
      } 
     })); 
     return panel; 
    } 

    private void display() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new GridLayout(0, 1)); 
     f.add(createPlayerPanel(new Human())); 
     f.add(createPlayerPanel(new Computer())); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test().display(); 
      } 
     }); 
    } 
} 
+0

另請參閱此相關的[示例](http://stackoverflow.com/a/15756352/230513)。 – trashgod

2

幾點建議:

  • Player類不應該Yahtzee的繼承,因爲它沒有通過「是一個」測試:一個Player對象的概念,並不代表一個Yahtzee的對象的專用版本。您在這裏使用繼承不會起作用,而只會導致問題。
  • 抽象方法不應該有「主體」。

換句話說,如果你聲明一個方法abstract那麼就聲明它。例如,這是確定:

public abstract void someMethod(); 

但是,這並不:

public abstract void someMethod() { 
    System.out.println("hello world"); 
} 

而且這絕對是不允許的:

public abstract void someMethod(); { 
    System.out.println("hello world"); 
} 

這個問題讓我困惑:

我應該使用擴展方法而不是在播放器類中創建一個新的「手形」對象嗎?這是繼承和創建這個類的全部點嗎?

請說明。

+1

我感謝你的時間看我的雜亂的代碼。關於你的問題。在我的抽象類中,我在遊戲方法手中創建了一個Yahtzee的新對象.YahtzeeRoll()和hand.YahtzeePrint.I很好奇,如果調用我的Yahtzee類的方法而不是創建一個新對象會更有意義。說實話,我認爲我只需要對抽象類和方法的目的做更多的研究。感謝您澄清抽象方法沒有內容。 – landres

+1

另外我的教官寫道創建「選擇:一個抽象的方法來決定保留或釋放哪些骰子(從Play方法中調用)」我的理解是把我的抽象方法中的play方法中的某些東西打個電話......但是這並不似乎是這樣。 – landres

+0

@landres:我推斷具體的'play()'是爲了調用抽象'choose()',正如建議的[這裏](http://stackoverflow.com/a/18040085/230513)。 – trashgod