Java继承和抽象类

时间:2013-08-03 17:53:05

标签: java inheritance abstract-class

有点新意,请告诉我是否格式错误。完全披露这是针对java类的介绍。想要一些关于概念或一些替代例子的一般推动。让我试着尽可能地打破这种局面。我们已经在java中构建了Yahtzee型骰子游戏的基础。我们目前的说明如下:创建一个名为Yahtzee的类。 Yahtzee级别持有游戏的五个骰子。添加以下方法:

锁定:保持骰子的方法(即,不包括下一卷中的骰子)。提示:向die类添加一个lock变量。 解锁:释放模具的方法(即在下一卷中包含模具) UnlockAll:释放手中所有骰子的方法。 Roll:仅滚动释放的骰子的方法。提示:如果模具已解锁,则将模具类中的roll方法更改为仅滚动。 显示:显示当前骰子值的方法。

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

玩:一种玩圆形的方法(最多三卷) 选择:一种抽象方法来决定要保留或释放哪个骰子(从Play方法调用) 名称:设置玩家姓名的方法。该类的构造函数调用该方法来设置Player的名称。

为Player创建一个名为Human的子类。人类玩家要求键盘上的人应该保留或释放骰子。当调用设置的Player名称方法时,它还会询问键盘上的人员。

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

我应该使用扩展方法而不是在播放器类中创建一个新的对象“hand”吗?这是继承和创建这个类的重点吗?

 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”参数来选择锁定解锁的骰子。但它不喜欢我的哪个参数,但它不介意Yahtzee类/锁解锁方法中的这个参数。有什么想法吗?此外,我试图重读并了解如何使用抽象类。是否有人对如何在人类或计算机子类中实现我的抽象类有一些提示或建议。我开始研究这些部分,这只是一团糟。

2 个答案:

答案 0 :(得分: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");
}

这个问题让我很困惑:

  

我应该使用扩展方法而不是在播放器类中创建一个新的对象“hand”吗?这是继承和创建这个类的重点吗?

请澄清。

答案 1 :(得分:2)

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