Java:从2个不同的类传递2个对象并访问它们的所有变量

Java:从2个不同的类传递2个对象并访问它们的所有变量,java,Java,我只想创建一个简单的程序,教我如何正确地将对象从不同的类传递到函数。我有两个类,玩家和敌人,每个都有一个可变的“速度”,然后我有一个战斗类,它接受这两个对象,然后找出付款人是否更快,但我不确定如何访问我传递的对象的变量 球员级别 public class Player { int speed = 0; public Player(){ setSpeed(5); } public void setSpeed(int speed) { thi

我只想创建一个简单的程序,教我如何正确地将对象从不同的类传递到函数。我有两个类,玩家和敌人,每个都有一个可变的“速度”,然后我有一个战斗类,它接受这两个对象,然后找出付款人是否更快,但我不确定如何访问我传递的对象的变量

球员级别

public class Player {

   int speed = 0;

   public Player(){
       setSpeed(5);
   }

   public void setSpeed(int speed) {
       this.speed = speed;
       }
   }
敌级

public class Enemy {

   int speed = 0;

   public Enemy(){
       setSpeed(3);
   }

   public void setSpeed(int speed) {
       this.speed = speed;
       }
   }
战斗级

public class Battle {

public Battle(Object a, Object b){
    if (faster(a.speed, b.speed)){    //This is where the problem is
        System.out.println("Faster");
    }
    else{
        System.out.println("Slower");
    }

}

Boolean faster(int speed1, int speed2){
    if (speed1 > speed2){
        return true;
    }
    else{
        return false;
    }
}
}

主类

public class Main {
   public static void main(String[] args) {
       Player player = new Player();
       Enemy enemy = new Enemy();
       Battle battle = new Battle(player, enemy);

   }

}

下面是代码的简要版本,但这应该会开始,您也可以使用两个不同的类来完成

public class Player {
    private int speed;

       public Player(int speed){
           this.speed=speed;
       }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }      
}




public class Battle {

    Player player;

    static void battle(Player obj1, Player obj2){
        if (obj1.getSpeed() > obj2.getSpeed()){
            System.out.println("Faster");
        }
        else{
            System.out.println("Slower");
        }
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Player player1 =new Player(5);

        Player player2 = new Player(3);

        battle(player1,player2);


    }

}
问题的解决办法 要使您的程序编译,您需要将
Battle
的构造函数的参数声明为
Player
foreign
,以便Java查找
speed
字段:

public class Battle {
    public Battle(Player a, Player b) {
        if (faster(a.speed, b.speed)) {
            System.out.println("Faster");
        } else {
            System.out.println("Slower");
        }

    }
    // ...
}
但是,这确实会阻止敌人进入
实例。但是,您可以提供更好的解决方案,即为
玩家
敌人
使用()基类进行继承,或者为他们使用()基类进行实现

使用抽象基类 使基类抽象并不是绝对必要的,但是它确实阻止了它被实例化,我们只希望允许子类
Player
buy
。它还强调了类是子类化的,而不是自己使用

// Character.java
public abstract class Character {
    private int speed;

    public Character(int speed) {
        this.speed = speed;
    }

    public int getSpeed() {
        return speed;
    }
}

// Player.java
public class Player extends Character {
    public Player() {
        super(5);
    }
}

// Enemy.java
public class Enemy extends Character {
    public Enemy() {
        super(3);
    }
}
有了它,
战斗
的构造器可以被修改以适应:

// ...
    public Battle(Character a, Character b) {
        if (faster(a.getSpeed(), b.getSpeed())) {
            System.out.println("Faster");
        } else {
            System.out.println("Slower");
        }
    }
// ...
使用接口 与(抽象)类不同,接口通常描述实现接口的对象支持的某些操作

// HasSpeed.java
public interface HasSpeed {
    int getSpeed();  // interface methods are public and abstract by default
}

// Player.java
public class Player implements HasSpeed {
    @Override
    public int getSpeed() {
        return 5;
    }
}

// Enemy.java
public class Enemy implements HasSpeed {
    @Override
    public int getSpeed() {
        return 3;
    }
}
这里,
Battle
的构造函数将修改如下:

// ...
    public Battle(HasSpeed a, HasSpeed b) {
        if (faster(a.getSpeed(), b.getSpeed())) {
            System.out.println("Faster");
        } else {
            System.out.println("Slower");
        }
    }
// ...
为什么要这样 您遇到的问题是,您试图访问声明为
对象的变量上的
播放器
敌人
类的字段。这在大多数动态类型的语言(如Python或JavaScript)中都适用,但在静态类型的语言(如Java)中则不适用

动态类型 在动态类型语言中,任何变量和/或字段的类型都是在运行时确定和检查的。这意味着在大多数语言中,任何对象都可以为任何参数传递。在检索某个字段的值时,将检查该对象是否拥有该字段

这种方法使最初编写代码变得更容易,但也增加了丢失错误的可能性,因为只有在运行时出现错误时才会报告错误

例如,如果Java是动态键入的,则程序将正常运行,直到将
玩家
敌人
以外的内容传递给
战斗
的构造函数,并且未找到
速度
字段

静态类型 在静态类型语言中,类型及其字段以及方法都是在编译时检查的,因此需要在声明中提供参数和变量的类型。然后只能将这些类型及其子类型分配给它们。这可以确保对象具有您期望的所有字段和方法,尽管在子类型的情况下,它可能具有更多字段和方法

正如您已经了解到的,当分配了声明类型以外的内容时,在编译程序时会出现一个错误。可以抑制这些错误,例如通过强制转换,但仍会发出警告

这虽然有些限制,但可以确保,除非采取特殊操作,否则不会因为缺少字段或方法而出现运行时错误。在编译过程中,这些错误总是会被捕获

进一步阅读 似乎为静态类型语言和动态类型语言之间的差异提供了一个很好的概述

在我上面的示例中,可以看到这一点,但您可能希望研究封装,以编写更符合Java约定的代码。我不会在这里讨论这个问题,因为它打破了这个答案的范围,不过还有一些进一步的信息


我还发现,对于学习新的编程语言、框架或原则,书籍是一个很好的来源。特别是如果你每天乘坐公共交通工具上下班,这是一个消磨时间和学习的好方法。给我介绍Java的那本书是O'Reilly写的。我发现它写得很好,但是还有很多其他选择。

总体思路是:创建一个类,然后创建这些类的实例。您可以通过调用它们的方法来处理这些实例:instanceOfClass.method()。如果我是您,我将使用初始化播放器对象的构造函数创建一个总体播放器类。在这种情况下,两个玩家都有速度,所以速度将进入你的构造器。然后创建一个敌人和一个好人类,这是玩家类固有的。然后你可以创建一个battle类,它接受两个玩家对象作为参数,你的命令是:battle.playerBattle(p1,p2)或者类似的东西。但是,同样的问题不会发生在我不能访问任何一个对象的速度。我更关注的是如何传递整个对象并访问它的变量。我现在明白你的意思了。总的来说,如果好的和坏的玩家都有相似的特征,那么为什么要重复你自己呢?最重要的是,学习构造函数如何工作将消除访问对象变量的问题。让您的程序完成创建对象和实例化其变量的工作。另外,让战斗完成访问这些对象属性的工作,您只需要说:letsFight(p1,p2)。