【问题标题】:Jave inheritence and abstract classes [closed]Java继承和抽象类[关闭]
【发布时间】:2013-08-04 19:57:39
【问题描述】:

这方面有点新,所以如果我的格式不正确,请告诉我。完全公开这是对 java 类的介绍。希望对概念或一些替代示例进行一些一般性的推动。让我尽可能简单地分解它。我们已经在java中构建了Yahtzee类型骰子游戏的基础。我们当前的指令如下:创建一个名为 Yahtzee 的类。 Yahtzee 类拥有游戏的五个骰子。添加以下方法:

锁定:一种保留骰子的方法(即不将骰子包含在下一掷中)。提示:在 die 类中添加一个 lock 变量。 解锁:一种释放骰子的方法(即在下一次掷骰中包含一个骰子) UnlockAll:释放手中所有骰子的方法。 掷骰:一种只掷骰子的方法。提示:将骰子类中的滚动方法更改为仅在骰子解锁时滚动。 Show:显示当前骰子值的方法。

创建一个名为 Player 的抽象类。添加以下方法:

Play:玩一轮的方法(最多三轮) 选择:决定保留或释放哪个骰子的抽象方法(从 Play 方法调用) 名称:设置播放器名称的方法。该类的构造函数调用该方法来设置播放器的名称。

为 Player 创建一个名为 Human 的子类。人类玩家询问键盘上的人应该保留或释放哪个骰子。当调用 set Player's name 方法时,它还会询问键盘上的人他的名字。

为 Player 创建一个名为 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 );    
    }
}

我试图让我的抽象类从 main 传递一个“int which”参数来选择哪个骰子在解锁时锁定。但它不喜欢我的 which 参数,但它不介意 Yahtzee 类/锁定解锁方法中的这个参数。有什么想法吗?我还尝试重新阅读并了解如何使用抽象类。有人会对如何在人类或计算机子类中实现我的抽象类有一些提示或建议吗?我开始研究这些部分,结果一团糟。

【问题讨论】:

  • 你的风格很健谈。通读所有这些并制定答案可能需要将近半个小时的全神贯注。这不是 StackOverflow 的工作方式。我们每个问题的注意力跨度约为 5 分钟。你需要调整你的问题。
  • 完全明白。我不想成为社区的负担,因为我似乎有一些反对意见:/ 只是寻求帮助除了 stackoverflow 之外的任何建议?我试图查看教程和指南,但我仍然遇到问题,但只是想得到一个人的实际帮助。再次感谢。

标签: java inheritance abstract-class


【解决方案1】:

扩展@Hovercraft 的观点,正如here 所讨论的,请注意抽象类可以同时具有具体方法和抽象方法。前者可供所有子类访问,而后者必须为每个子类实现。在这个游戏中,HumanComputer 都可以play(),但每个都使用choose() 的不同实现。在下面的示例中,请注意按下 Play 是如何调用抽象 player.play() 的,后者又调用属于给定具体子类的正确 choose() 方法。同样,Computer 构造函数始终指定名称“Boris”,而Human 构造函数会提示用户输入名称。

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();
            }
        });
    }
}

【讨论】:

【解决方案2】:

一些建议:

  • Player 类不应该从 Yahtzee 继承,因为它没有通过“is-a”测试: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");
}

这个问题让我很困惑:

我应该使用扩展方法而不是在播放器类中创建一个新对象“手”吗?这就是继承和创建这个类的全部意义吗?

请澄清。

【讨论】:

  • 感谢您花时间浏览我凌乱的代码。关于你的问题。在我的抽象类中,我在 play 方法 hand.YahtzeeRoll() 和 hand.YahtzeePrint 中创建了一个新的 Yahtzee 对象。我很好奇只调用 Yahtzee 类的方法而不是创建一个新对象是否更有意义。老实说,我认为我只需要对抽象类和方法的目的进行更多研究。感谢您澄清抽象方法没有主体。
  • 我的导师还写了 create "Choose: An abstract method to determine which dice to keep or release (从 Play 方法调用)" 我的理解是从 play 方法中调用一些东西到我的抽象方法中...但事实并非如此。
  • @landres:我推断具体的play() 是为了调用抽象的choose(),正如here 所建议的那样。
猜你喜欢
  • 2016-07-02
  • 1970-01-01
  • 2017-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多