如何使子类的字段和方法对通过另一个类仅使用超类的类可用。

huangapple go评论72阅读模式
英文:

How can i make fields and methods of a sub class usable to a class which only uses the super class through another class

问题

好的,以下是您提供的内容的翻译部分:

因此,在浏览论坛寻找我正在寻找的答案几个小时后,我没有找到任何有助于我的东西,所以我继续寻找。

我正在尝试制作一个类似于大富翁的游戏,我正在制作游戏引擎类。
我有一个“Board”类和一个“抽象Card”类,我用它来制作其他几个类,如“HouseCard”,“Decision Card”,“AirportCard”等。
如您所见,每个卡片类都有不同的方法和字段。
我现在正在尝试制作游戏引擎类,我需要访问其中一些类的字段和方法,但我不能。唯一可能的解决方案是在“Abstract Card”类中编写方法,然后在子类中进行@override,但这是不正确的,因为我必须在所有其他类中实现这些方法,所以最终每个类中都会有大约30个方法,这是错误的。
我提供了一些代码以查看我是什么意思,因为我已经对两种抽象布尔方法和一个整数使用了这个解决方案,现在感觉不对。

这是Card类:

public abstract class Card {
    
    public Card() {
    }
    
    public void stringCard() {
    }
    
    public void setHolder(int holderID) {
    }
    
    public abstract Boolean hasOwner();
    public abstract Boolean buyable();
    public abstract int getBuyCost();
}

这是我使用的Card子类之一的“HouseCard”类:

public class HouseCard extends Card{
    
    public String cardName;
    public int buycost, rent, h1, h2, h3, h4, hotel, mortgage, hcost;
    public int holderID = -1;
    
    public HouseCard(String cardName, int buycost, int rent, int h1, int h2, int h3, int h4, int hotel, int mortgage, int hcost) {
        this.cardName = cardName;
        this.buycost = buycost;
        this.rent = rent;
        this.h1 = h1;
        this.h2 = h2;
        this.h3 = h3;
        this.h4 = h4;
        this.hotel = hotel;
        this.mortgage = mortgage;
        this.hcost= hcost;
    }
    
    @Override
    public void setHolder(int holderID) {
        this.holderID = holderID;
    }

    @Override
    public Boolean buyable() {
        if (this.holderID == -1) {
            return true;
        }
        else {
            return false;
        }
    }
    
    @Override
    public Boolean hasOwner() {
        if (this.holderID == -1) {
            return false;
        }
        else {
            return true;
        }
    }
    
    @Override
    public int getBuyCost() {
        return buycost;
    }
    
    @Override
    public void stringCard() {
        System.out.println("      " + cardName + " (" + buycost + "$)");
        System.out.println("");
        System.out.println("Rent Pay    -> " + rent + "$");
        System.out.println("1st House   -> " + h1 + "$");
        System.out.println("2nd House   -> " + h2 + "$");
        System.out.println("3rd house   -> " + h3 + "$");
        System.out.println("4th house   -> " + h4 + "$");
        System.out.println("");
        System.out.println("Hotel       -> " + hotel + "$");
        System.out.println("");
        System.out.println("Mortgage    -> " + mortgage + "$");
        System.out.println("");
    }
    
    public String getCardName() {
        return cardName;
    }
}

这是我用来使用不同卡片的不同方法存储我的游戏中的每个方块的Board类:

public class Board {
    
    public ArrayList<Card> Cards;
    public int numberBoard = 0;
    
    public Board(){
        this.Cards = new ArrayList<Card>();
    }
    
    public void addCard(String cardName, String cardDesc) {
        Card card = new GeneralCard(cardName, cardDesc);
        Cards.add(card);
        numberBoard++;
    }
    
    public void addCard(String cardName, String cardDesc, Action action) {
        Card card = new GeneralCard(cardName, cardDesc, action);
        Cards.add(card);
        numberBoard++;
    }
    
    public void addCardMulti(String cardName, int buycost, int pay1, int pay2, int mortgage) {
        Card card = new MultiCard(cardName, buycost, pay1, pay2, mortgage);
        Cards.add(card);
        numberBoard++;
    }
    
    public void addCardAirport(String cardName, int buycost, int air1, int air2, int air3, int air4, int mortgage) {
        Card card = new AirportCard(cardName, buycost, air1, air2, air3, air4, mortgage);
        Cards.add(card);
        numberBoard++;
    }
    
    public void addCardHouse(String cardName, int buycost, int rent, int h1, int h2, int h3, int h4, int hotel, int mortgage, int hcost) {
        Card card = new HouseCard(cardName, buycost, rent, h1, h2, h3, h4, hotel, mortgage, hcost);
        Cards.add(card);
        numberBoard++;
    }
}

以下是使用子类Cards的字段和方法的一些行。正如您在第一行中使用抽象方法getBuyCost()的方式一样,它可以正常工作,但在第二行中使用getCardName()时,它是一个仅在子类中使用而不在Card超类中的方法,它无法正常工作。

dashboard.Cards.get(Players.get(i).getSquare()).getBuyCost();

System.out.println(Players.get(i).getName() + " bought " + dashboard.getCard(Players.get(i).getSquare()).getCardName() + " successfully.");

如何解决这个问题?

英文:

So, after some hours searching through the forum for the answer i am searching for i couldn't find anything that helps me so here i go.

I am trying to make a Monopoly style game and i am making the Game Engine class.
I have a 'Board' class and an 'abstract Card' class which i use to make several other classes such as 'HouseCard', 'Decision Card', 'AirportCard' etc.
As you can see every card class has different methods and fields.
I am trying to make the game engine class right now and i need to access some of the fields and some of the methods of some of those classes but i can't. The only possible solution Eclipse gives me is to make the methods inside the 'Abstract Card' class and the do an @Override in the sub classes but this is not right because i will have to implement those methods inside all other classes so in the end i will have like 30 methods in every class which is wrong.
I am providing some code to see what i mean because i have done this solution to two abstract Boolean methods and one int and already it feels wrong.

This is the Card class:

public abstract class Card {
public Card() {
}
public void stringCard() {
}
public void setHolder(int holderID) {
}
public abstract Boolean hasOwner();
public abstract Boolean buyable();
public abstract int getBuyCost();
}

This is the one of the card sub classes i use 'HouseCard' class:

public class HouseCard extends Card{
public String cardName;
public int buycost, rent, h1, h2, h3, h4, hotel, mortgage, hcost;
public int holderID = -1;
public HouseCard(String cardName, int buycost, int rent, int h1, int h2, int h3, int h4, int hotel, int mortgage, int hcost) {
this.cardName = cardName;
this.buycost = buycost;
this.rent = rent;
this.h1 = h1;
this.h2 = h2;
this.h3 = h3;
this.h4 = h4;
this.hotel = hotel;
this.mortgage = mortgage;
this.hcost= hcost;
}
@Override
public void setHolder(int holderID) {
this.holderID = holderID;
}
@Override
public Boolean buyable() {
if (this.holderID == -1) {
return true;
}
else {
return false;
}
}
@Override
public Boolean hasOwner() {
if (this.holderID == -1) {
return false;
}
else {
return true;
}
}
@Override
public int getBuyCost() {
return buycost;
}
@Override
public void stringCard() {
System.out.println(&quot;      &quot; + cardName + &quot; (&quot; + buycost + &quot;$)&quot;);
System.out.println(&quot;&quot;);
System.out.println(&quot;Rent Pay    -&gt; &quot; + rent + &quot;$&quot;);
System.out.println(&quot;1st House   -&gt; &quot; + h1 + &quot;$&quot;);
System.out.println(&quot;2nd House   -&gt; &quot; + h2 + &quot;$&quot;);
System.out.println(&quot;3rd house   -&gt; &quot; + h3 + &quot;$&quot;);
System.out.println(&quot;4th house   -&gt; &quot; + h4 + &quot;$&quot;);
System.out.println(&quot;&quot;);
System.out.println(&quot;Hotel       -&gt; &quot; + hotel + &quot;$&quot;);
System.out.println(&quot;&quot;);
System.out.println(&quot;Mortgage    -&gt; &quot; + mortgage + &quot;$&quot;);
System.out.println(&quot;&quot;);
}
public String getCardName() {
return cardName;
}
}

And this is the board class i use to store every square in my game using different methods for different cards:

public class Board {
public ArrayList&lt;Card&gt; Cards;
public int numberBoard = 0;
public Board(){
this.Cards = new ArrayList&lt;Card&gt;();
}
public void addCard(String cardName, String cardDesc) {
Card card = new GeneralCard(cardName, cardDesc);
Cards.add(card);
numberBoard++;
}
public void addCard(String cardName, String cardDesc, Action action) {
Card card = new GeneralCard(cardName, cardDesc, action);
Cards.add(card);
numberBoard++;
}
public void addCardMulti(String cardName, int buycost, int pay1, int pay2, int mortgage) {
Card card = new MultiCard(cardName, buycost, pay1, pay2, mortgage);
Cards.add(card);
numberBoard++;
}
public void addCardAirport(String cardName, int buycost, int air1, int air2, int air3, int air4, int mortgage) {
Card card = new AirportCard(cardName, buycost, air1, air2, air3, air4, mortgage);
Cards.add(card);
numberBoard++;
}
public void addCardHouse(String cardName, int buycost, int rent, int h1, int h2, int h3, int h4, int hotel, int mortgage, int hcost) {
Card card = new HouseCard(cardName, buycost, rent, h1, h2, h3, h4, hotel, mortgage, hcost);
Cards.add(card);
numberBoard++;
}
}

And here are some lines i have to use fields and methods from the sub classes Cards. As you can see in the first line where i use the abstract method getBuyCost() it works fine but at the second line where i use getCardName(), which is a method used in the sub class only without having it in the Card super class it doesn't work.

dashboard.Cards.get(Players.get(i).getSquare()).getBuyCost();
System.out.println(Players.get(i).getName() + &quot; bought &quot; + dashboard.getCard(Players.get(i).getSquare()).getCardName() + &quot; successfully.&quot;);

How can i fix this?

答案1

得分: 1

首先,如果您想尊重封装并使用访问方法,您应将 HouseCard 属性设置为私有。

其次,请记得分享所有与代码相关的内容,这样我们才能更好地帮助您。我会假设 Players.get(i).getSquare 在您的代码中返回 HouseCard 的一个实例。

最后,如果 square 属性的类型是 Card,您需要在调用 getCardName() 方法之前对 HouseCard 进行类型转换。

您最终将会得到类似这样的代码:

HouseCard card = (HouseCard) Player.get(i).getSquare();
String cardName = card.getCardName();
英文:

First, you should set HouseCard attributes as private, if you want to respect encapsulation and use your accessor methods.

Second, remember to share all the code related so we can help you better. I will assume Players.get(i).getSquare returns an instance of HouseCard in your code.

And finally, if square attribute is type of Card, you will need to make cast of HouseCard before calling the getCardName() method.

You will end up having something like this:

HouseCard card = (HouseCard) Player.get(i).getSquare();
String cardName = card.getCardName();

答案2

得分: 1

您的问题是getCardName()方法在您的Card类中未定义。由于这个变量似乎是适用于所有子类的数据,我建议将它移到父类Card中。

public abstract class Card {
  private String cardName;

  public Card(String cardName) {
     this.cardName = cardName;
  }

  public String getCardName() {
    return cardName;
  }

  //其他方法
}

然后,您的子类可以在实例化时调用super()方法来设置该值。

public class HouseCard extends Card {
  public HouseCard(String cardName) {
    super(cardName);
  }
}

然后,您就不会有任何问题在Card对象上调用getCardName()方法,因为您在Card父类中定义了它。您还可以在子类中调用getCardName()方法以获取此上下文中的值(或者如果您想直接引用它,可以使用protected关键字代替private来定义变量)。

@Override
public String toString() {
  return getCardName() + " some other info specific to this class"; 
}
英文:

Your issue is that the getCardName() method is not defined in your Card class. Since that variable seems like data that would apply to all your subclasses I recommend moving it up into the parent Card class.

public abstract class Card {
private String cardName;
public Card(String cardName) {
this.cardName = cardName;
}
public String getCardName() {
return cardName;
}
//Other methods
}

Then your subclasses can call the super() method to set that value when they are instantiated.

public class HouseCard extends Card {
public HouseCard(String cardName) {
super(cardName);
}
}

And then you won't have any issues calling the getCardName() method on a Card object since you defined what that is in the Card parent class. You can also then call the getCardName() method inside your subclasses to get the value in this context (or use the protected keyword instead of private for the variable if you wanna just reference it directly).

@Override
public String toString() {
return getCardName() + &quot; some other info specific to this class&quot;; 
}

huangapple
  • 本文由 发表于 2020年7月28日 20:54:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63134627.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定