Java超类如何访问子类成员变量:Pistol超类调用Player子类money与name字段的实现方法
Hey there! Let's tackle your problem where the Pistol superclass needs to access the money and name fields from its Player subclass. First, let's clarify why your current code won't work, then go through the best solutions.
Why Your Current Code Fails
In Java, a superclass doesn't have direct access to subclass-specific fields by default. When you try to use money or name directly in Pistol's getBullet() method, the compiler can't find those variables because they're only defined in the Player subclass, not in Pistol.
Solution 1: Move Shared Fields to the Superclass (Recommended)
Since your Pistol class needs name and money to implement the getBullet() functionality, these fields are actually part of the shared state between the superclass and subclass. Moving them to Pistol (using protected access so subclasses can access them) is the cleanest, most OOP-compliant approach.
Here's the revised code:
Pistol Class
public class Pistol { int bullets = 20; protected String name; // Protected allows subclass access protected int money; // Superclass can directly use these public Pistol() {} // Constructor to initialize shared fields public Pistol(String name, int money) { this.name = name; this.money = money; } public void getBullet() { if ((20 - bullets) * 5 <= money && bullets != 20) { money -= (20 - bullets) * 5; bullets = 20; System.out.println("Success! The real war begins now!"); System.out.println("INFO : " + name + " has 20 bullets in his/her pistol"); System.out.println("INFO : " + name + " has " + money + "$"); } else { System.out.println("Player can not afford it now."); } } }
Player Class
public class Player extends Pistol { Player borrower; Player target; int amount; boolean terrorist; int health; public Player() {} public Player(String name, boolean terrorist, int money, int health) { super(name, money); // Call superclass constructor to initialize shared fields this.terrorist = terrorist; this.health = health; } }
Solution 2: Downcast to the Subclass (Not Recommended for Most Cases)
If you can't move the fields to the superclass for some reason, you can check if the current Pistol instance is actually a Player, then downcast it to access the subclass fields. This adds coupling and isn't ideal for scalable code, but it works in a pinch.
Modify the getBullet() method in Pistol:
public void getBullet() { // Check if this instance is a Player if (this instanceof Player) { Player player = (Player) this; int playerMoney = player.money; String playerName = player.name; if ((20 - bullets) * 5 <= playerMoney && bullets != 20) { player.money -= (20 - bullets) * 5; bullets = 20; System.out.println("Success! The real war begins now!"); System.out.println("INFO : " + playerName + " has 20 bullets in his/her pistol"); System.out.println("INFO : " + playerName + " has " + player.money + "$"); } else { System.out.println("Player can not afford it now."); } } else { System.out.println("This method only works for Player instances."); } }
Key Notes:
- Solution 1 is better because it follows the "Don't Repeat Yourself" (DRY) principle and keeps related state and behavior together in the superclass.
- Downcasting (Solution 2) should be avoided unless necessary, as it makes your code less flexible—if you add another subclass of
Pistollater, this method won't work for it without additional checks.
内容的提问来源于stack exchange,提问作者Samet Koca

