relation between two classes (german code) [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I want to make an array with which I can create some instances of the class Schiff (Ship) by using the class Flotte (Armada). Somehow it does not work. Which method is more useful? addShiff or addSchiff2?
public class Schiff
{
private String material;
private int kanonen;
private int ursprungsMäste;
private int mästeStehenNoch;
public Schiff (String material, int kanonen, int mäste)
{
this.material = material;
this.kanonen = kanonen;
ursprungsMäste = mäste;
mästeStehenNoch = mäste;
}
public String gibMaterial()
{
return material;
}
public void mastGetroffen(int wieVieleTreffer)
{
mästeStehenNoch = mästeStehenNoch - wieVieleTreffer;
}
public void wieVieleMäste ()
{
System.out.println("Es stehen noch " + mästeStehenNoch + " Mäste!");
}
}
+++++++
public class Flotte
{
private Schiff [] flottenArray;
public Flotte ()
{
flottenArray = new Schiff [100];
}
public void addSchiff (String material, int kanonen, int ursprungsMäste)
{
for (int zahl = 0; zahl<flottenArray.length; zahl++)
{
if (flottenArray[zahl] == null)
{
flottenArray[zahl] = new Schiff (material, kanonen, ursprungsMäste);
}
}
}
public void addSchiff2 (Schiff neuesSchiff)
{
for (int zahl = 0; zahl<flottenArray.length; zahl++)
{
if (flottenArray[zahl] == null)
{
flottenArray[zahl] = neuesSchiff;
}
}
}
public void gegnerischerFeuerAngriff ()
{
for (Schiff schiff : flotte)
{
if (schiff.gibMaterial().equals("holz"))
{
flottenArray.remove(schiff);
}
}
}
}

What exactly does not work?
Looks good to me.
My feeling is that you can drop the addSchiff (String material, int kanonen, int ursprungsMäste) method because:
One: It is just another way of writing addSchiff2(new Schiff(material, kanonen, ursprungsMäste)) and this is also how it should be coded to avoid repeating yourself:
public void addSchiff (String material, int kanonen, int ursprungsMäste)
{
addSchiff2(new Schiff(material, kanonen, ursprungsMäste))
}
Two: If you later decide to add fields to class Schiff you will have to change the interface of Flotte if you keep the method that constructs a Schiff instance from passed parameters. This is not the case if you just have a method that takes a Schiff instance. So getting rid of addSchiff() decreased inter-class coupling, which is gut.
Klar zur Halse!

Related

How to add Objects in an ArrayList with an abstract Class [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 months ago.
Improve this question
I am trying to add Card objects into an ArrayList of Cards in order to create a Deck of Cards. In order to do that I looped through the suits and the values of the cards and attempted to add Card objects. I am getting an error that I cannot instantiate the type Card.
This is my Card Class:
public abstract class Card
{
public static final String FACES[] = {"ZERO","ACE","TWO","THREE","FOUR",
"FIVE","SIX","SEVEN","EIGHT","NINE","TEN","JACK","QUEEN","KING"};
private String suit;
private int number;
//constructors
public Card(){
}
public Card ( int num, String type) {
number = num;
suit = type;
}
// modifiers
//accessors
public String getSuit() {
return suit;
}
public int getNumber() {
return number;
}
public abstract int getValue();
public boolean equals(Object obj)
{
if (getNumber()==((Card) obj).getNumber()) {
return true;
}
return false;
}
//toString
public String toString () {
int var = getNumber();
return FACES[var] + " of " + getSuit() + " | Value " + getValue();
}
}
This is my Deck Class:
import java.util.ArrayList;
import java.util.Collections;
public class Deck
{
public static final int NUMFACES = 13;
public static final int NUMSUITS = 4;
public static final int NUMCARDS = 52;
public static final String SUITS[] = {"CLUBS","SPADES","DIAMONDS","HEARTS"};
private int topCardIndex;
private ArrayList<Card> stackOfCards;
public Deck ()
{
//initialize data - stackOfCards - topCardIndex
topCardIndex = 0;
for (int i=0;i<NUMSUITS;i++){
for( int j=0; j<NUMFACES; j++) {
stackOfCards.add(new Card(j,SUITS[i]));
}
}//loop through suits
//loop through faces
//add in a new card
}
//modifiers
public void shuffle ()
{
//shuffle the deck
//reset variables as needed
}
//accessors
public int size ()
{
return 0;
}
public int numCardsLeft()
{
return stackOfCards.size();
}
public Card nextCard()
{
return stackOfCards.get(topCardIndex--);
}
public String toString()
{
return stackOfCards + " topCardIndex = " + topCardIndex;
}
}
When having the type of a List to an abstract class you can add any extention of that abstract class to that list. For example, if you would have an abstract class Car and two other classes: FooCar and BarCar extends that class you are allowed to add both an instance of FooCar and BarCar to that list.
In your implementation of card however there is no point in it being abstract, in fact it shouldn't be abstract as you are trying to instantiate it.
For more information about abstraction I suggest to check out: https://www.w3schools.com/java/java_abstract.asp, it provides a easy to follow guide on how to use abstraction and what it is. You can also use the official documentation for more information https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

Setters And Getters to different Class

My problem is that, simply I don't know what code to use to get my value from my getX method to my other classses main method.
package hangman;
public class Hangman {
private int triesLimit;
private String word;
public void setTriesLimit(int triesLimit) {
this.triesLimit = triesLimit;
}
public void setWord(String word) {
this.word = word;
}
public int getTriesLimit() {
return this.triesLimit;
}
public String getWord() {
return this.word;
}
#Override
public String toString() {
return ("Enter Secret Word " + this.getWord()
+ ".\nEnter max # of tries (Must be under 7) "
+ this.getTriesLimit());
}
}
Thats from the sub-class and I am trying to store the value of the triesLimit into the main of this classes main method
package hangman;
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
Scanner scn = new Scanner(System.in);
int triesCount = 0;
int correctCount = 0;
hangman.toString();
int triesLimit = hangman.getTriesLimit();
String secretWord = hangman.getWord();
StringBuilder b = new StringBuilder(secretWord.length());
for (int i = 0; i < secretWord.length(); i++) {
b.append("*");
}
char[] secrectStrCharArr = secretWord.toCharArray();
int charCnt = secretWord.length();
for (int x = 0; triesCount < triesLimit; triesCount++) {
while (charCnt >= 0) {
System.out.println("Secrect Word :" + b.toString());
System.out.println("Guess a letter :");
char guessChar = scn.next().toCharArray()[0];
for (int i = 0; i < secrectStrCharArr.length; i++) {
if (guessChar == secrectStrCharArr[i]) {
b.setCharAt(i, guessChar);
correctCount++;
} else if (guessChar != secrectStrCharArr[i]) {
triesCount++;
System.out.println("Incorrect: " + triesCount);hangmanImage(triesCount,correctCount);
}
}
}
}
}
I tried looking it up on here but couldn't find setters and getters used in a sub/superclass
You need to create an instance of the class in the main method to access the variables and method available in that class like so
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
hangman.setTriesLimit(2)
int value = hangman.getTriesLimit();
}
You can look into static keyword to access the value directly but that requires a bit more understanding of OOP's and JAVA.
This should work fine.
Hope it helps :)
EDITED
ToString method is just to convert everything in your model class to String which you have done correctly,but you have implemented incorrectly.... Change your ToString content so
#Override
public String toString() {
return ("The Secret Word you entered: " + this.getWord()
+ ".\n The max # of tries (Must be under 7): "
+ this.getTriesLimit());
}
You have initialized Scanner which does what you want, to ask the user to enter the values but again you haven't implemented it so add this to your main method
Scanner scn = new Scanner(System.in);
hangman.setTriesLimit(scn.nextInt());
hangman.setWord(scn.next());
hangman.toString()//Will work now
Trial and error is your best friend now :)
and Google some of the issues rather than waiting for an answer :)
Like rohit said, this is as simple as understand the basics of OOP, specific the encapsulation.
If you want to get a little deeper into OOP patterns, you could use the Observer pattern. This allows you to change the status of any class instance, even if they're not related by inheritance, aggregation, etc.
You can scale the solution by making List of Observer
Your observable interface
public interface IObservable {
// Set the observer
public void setObserver(IObserver iObserver);
// Notify the observer the current status
public void notifyObserver();
}
Your observer interface
public interface IObserver {
public void update(boolean status);
}
Your observer implementation
public class PlayHangman implements IObserver {
private boolean status = false;
public void printStatus() {
System.out.println("Status: " + (this.status ? "Win" : "Lose"));
}
#Override
public void update(boolean status) {
// The instance status is updated
this.status = status;
// Print the current status
this.printStatus();
}
}
Your observable implementation
public class Hangman implements IObservable{
private String goalWord = "";
private String currentWord = "";
private int triesLimit = 0;
private int tries = 0;
private IObserver iObserver;
public Hangman(String goalWord, int triesLimit) {
this.goalWord = goalWord;
this.triesLimit = triesLimit;
}
public void setCurrentWord(String currentWord) {
this.currentWord = currentWord;
this.notifyObserver();
}
public void addTry() {
this.tries++;
this.notifyObserver();
}
#Override
public void setObserver(IObserver iObserver) {
this.iObserver = iObserver;
}
#Override
public void notifyObserver() {
// True = win
this.iObserver.update(this.tries < this.triesLimit &&
this.goalWord.equals(this.currentWord));
}
}
Your Main class
public class Main{
public static void main(String[] args) {
// PlayHangman (game status)
PlayHangman playHangman = new PlayHangman();
// Hangman initializes with a goalWord and the triesLimit
Hangman hangman = new Hangman("HangmanJava", 5);
// Set the observer
hangman.setObserver(playHangman);
// During the game you just can set the current word and add a try
// You're not setting the status directly, that's the magic of the Observer pattern
hangman.setCurrentWord("Hang");
hangman.addTry();
hangman.setCurrentWord("HangmanJava");
}
}
Hope this helps and enjoy Java

Int value does not change after calling method [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
After calling doReading(),the value of pages is supposed to change, but it does not. Is it possible to do this without declaring int pages; in the MyMath2 and MyScience2 classes. The output should be something like:
Before reading:
Math- must read 5 pages
After reading:
Math- must read 3 pages
Abstract Homework2
public abstract class Homework2 implements Processing
{
private int pagesToRead;
private String typeHomework;
{
// initialise instance variables
pagesToRead = 0;
typeHomework = "none";
}
public Homework2(int pages, String hw)
{
pagesToRead = pages;
typeHomework = hw;
}
public abstract void createAssignment(int pages);
public int getPages()
{
return pagesToRead;
}
public void setPagesToRead(int p)
{
pagesToRead = p;
}
public String getTypeHomework()
{
return typeHomework;
}
public void setTypeHomework(String hw)
{
typeHomework = hw;
}
public String toString()
{
return "reading: \n" + typeHomework + " - must read " + pagesToRead + " pages";
}
}
TestHomework2
public class TestHomework2
{
public static void main(String []args)
{
List<Homework2> tester = new ArrayList<Homework2>();
tester.add( new MyMath2(5, "Math"));
tester.add( new MyScience2(7, "Science"));
for (Homework2 c: tester)
{
System.out.print("Before ");
System.out.println(c);
c.doReading();
System.out.print("After ");
System.out.println(c);
}
}
}
Interface Processing
public interface Processing
{
void doReading()
}
MyMath2
public class MyMath2 extends Homework2 implements Processing
{
int pages;
public MyMath2(int pages, String hw)
{
super(pages,hw);
}
public void createAssignment(int pages)
{
setTypeHomework("Math");
setPagesToRead(pages);
}
public void doReading()
{
pages = pages - 2;
}
}
MyScience2
public class MyScience2 extends Homework2 implements Processing
{
int pages;
public MyScience2(int pages, String hw)
{
super(pages,hw);
}
public void createAssignment(int pages)
{
setTypeHomework("Science");
setPagesToRead(pages);
}
public void doReading()
{
pages = pages - 3;
}
}
Fields are not overridden. This means that the initial pagesToRead won't get updated when doReading() is called, since that method changes pages.
You should just do:
public void doReading(){
setPagesToRead(getPages() - 2);
}
System.out.print("After ");
System.out.println(c);
class the toString() of Homework2
public String toString()
{
return "reading: \n" + typeHomework + " - must read " + pagesToRead + " pages";
}
there you return the pagesToRead. But in doReading you reduce pages not pagesToRead:
public void doReading()
{
pages = pages - 2;
}
reduce pagesToRead:
public void doReading()
{
pagesToRead = pagesToRead - 2;
}
When you change the page count by calling doReading, you are changing the value of pages in MyMath2 object (property of MyMath2 object). And the number that you are printing is coming from Homework2.pagesToRead field.
This field in Homework2 is never changed when you call doReading method and hence you get the same value. You could fix this by setting the value that you set in MyMath2 object like:
public void doReading(){
pages = pages - 2;
super.setPagesToRead(pages);
}
Or you completely remove pages field from MyMath2 and use field from parent object like:
public void doReading(){
super.setPagesToRead(super.getPagesToRead() - 2);
}
Same applies to MyScience2 class as well.

I can't call a method in the client from my LinkedList class [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
got it working, see comments.
well apparently it's not just in the client. I can't call any of the methods I've created at all. For my assignment, I'm supposed to create those methods in a class then implement them in a client. I can't even call the methods within the initial class. Not sure why.
import java.util.*;
public class Driver5
{
public static final int SENTINEL = 0;
public static void main(String[] args)
{
int value = 1;
Scanner keyboard = new Scanner(System.in);
LinkedList<Intcoll5> P = new LinkedList<Intcoll5>();
while(value != SENTINEL)
{
if (value > 0)
{
P.**insert**(value);
}
}
}
}
still working on some methods, just trying to call insert()
import java.util.LinkedList;
import java.util.*;
public class Intcoll5
{
LinkedList<Integer> c = new LinkedList<Integer>();
ListIterator<Integer> I = c.listIterator();
public Intcoll5(int i)
{
c = new LinkedList<Integer>();
}
public void insert(int i)
{
Integer I = new Integer(i);
if (!c.contains(I))
{
c.addFirst(I);
}
}
public void copy(Intcoll5 obj)
{
while (I.hasNext())
{
}
}
public boolean belongs(Integer i)
{
return true;
}
public void omit(Integer i)
{
if (c.contains(i))
{
c.remove(i);
}
}
public int get_howmany()
{
int i = 0;
while (I.hasNext())
{
i++;
}
return i;
}
public void print()
{
while (I.hasNext())
{
Integer n = I.next();
System.out.println(n.intValue());
}
}
public boolean equals(Intcoll5 obj)
{
return true;
}
}
just "insert" is underlined in the client, error is: "cannot find symbol".
There is no insert method in the LinkedList class.
Just use add.
if (value > 0) {
Intcoll5 object = new Intcall5();
object.insert(value);
P.add(object);
}
I believe you're trying to invoke the Intcoll5#insert() method, but for this you will need to refer an instance of the Incoll5 class. Note that your P object refers a LinkedList.
Also, the constructor of the Intcoll5 class seem pretty weird to me, since it doesn't use it's i parameter. Change it to:
public Intcoll5()
{
c = new LinkedList<Integer>();
}

An Arraylist of Arrays or os there a better way?

So thanks to the wonderful people here i've managed to get something semi workable, still have a couple bugs but maybe you guys can help me figure it out. So far none of the solution provided were a exact match (which is why i havent up voted them) but they did help me look at things in a new way and get things moving forward. So here is the current problem.
First the code then the explination
RaceButtons[RaceCounter] = new JToggleButton();
RaceButtons[RaceCounter].setIcon(RCiconSM);
RaceButtons[RaceCounter].setBorder(BorderFactory.createEmptyBorder());
RaceButtons[RaceCounter].setContentAreaFilled(false);
RaceButtons[RaceCounter].setActionCommand(temp_race.getRaceNameString(RaceCounter));
RaceButtons[RaceCounter].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Race race = new Race(1, 1, GenderList[PHYSICAL_SEX]);
race.setRaceID(race.getRaceIDFromString(ae.getActionCommand()));
//System.out.println(race.getraceID());
if (RaceButtons[race.getraceID()].isSelected()){
RaceButtons[race.getraceID()].setBorderPainted(true);
RaceButtons[race.getraceID()].setBorder(new LineBorder(Color.blue,2));
MyRaceArray.add(new Race(race.getraceID(), 1, GenderList[PHYSICAL_SEX]));
}else{
RaceButtons[race.getraceID()].setBorderPainted(false);
};
So first i create an array of Toggle buttons and when you click it it draw the border and then getting it's info i can add it to the array for races but this lives me with another problem i cant quite figure the logic off. Namly if there are already selected button it adds another instances to the button, it shouldn't do that it should ignore iexaisting entries but that means i have to check the arry for a matching object of type Race withthe same info right? What's the best way to do that?
And when you deselect it how do i remove that same object.
This is how your code should look like with a Race class:
import java.util.ArrayList;
import java.util.List;
public class Race {
private int raceID;
private double purity;
private int strMod;
private int dexMod;
private int conMod;
private int wisMod;
public int getRaceID() {
return raceID;
}
public void setRaceID(int raceID) {
this.raceID = raceID;
}
public double getPurity() {
return purity;
}
public void setPurity(double d) {
this.purity = d;
}
public int getStrMod() {
return strMod;
}
public void setStrMod(int strMod) {
this.strMod = strMod;
}
public int getDexMod() {
return dexMod;
}
public void setDexMod(int dexMod) {
this.dexMod = dexMod;
}
public int getConMod() {
return conMod;
}
public void setConMod(int conMod) {
this.conMod = conMod;
}
public int getWisMod() {
return wisMod;
}
public void setWisMod(int wisMod) {
this.wisMod = wisMod;
}
#Override
public String toString() {
return "Race [raceID=" + raceID + ", purity=" + purity + ", strMod="
+ strMod + ", dexMod=" + dexMod + ", conMod=" + conMod
+ ", wisMod=" + wisMod + "]";
}
public static void main(String args[]) {
//create a list of race objects
List<Race> raceCollection = new ArrayList<Race>();
//create a race object
Race race = new Race();
race.setRaceID(1);
race.setPurity(0.75);
race.setStrMod(5);
race.setDexMod(7);
race.setConMod(-2);
race.setWisMod(3);
//add race object to collection
raceCollection.add(race);
//You can create and add multiple objects of race to the collection
//Iterate your list and print the objects
for(Race raceObj:raceCollection) {
System.out.println(raceObj);
}
}
}
You will be able to make it work using an ArrayList of arrays, but that possibly isn't the best way in the long run. It can be very fiddly and error-prone to deal with - what happens when you insert a new race or attribute, but forget to to change the index somewhere?
Arrays and ArrayLists are usually best reserved for situations where you actually have a sequence / list (often with a meaningful sequence order).
In your case I'd be more inclined to adopt a prototype model. Typically in Java you would represent each race with a HashMap (or a data structure containing a HashMap), there the map represents the relationship between the "Attribute ID" and the "Default Value".
Creating a new elf is then just a case of initialising the elf's attributes using the default values from his race (or a average of different races, if you want...)
Some people may suggest making an OOP class with lots of named fields. This can also work, but IMHO a prototype model is better - it gives you much more flexibility in the long run. You often want to process large groups of attributes in the some way, and doing this is pretty messy if you have to refer to each of the attribute fields individually.
import java.util.ArrayList;
import java.util.List;
public class Race
{
private final int raceID;
private final double purity;
private final int strMod;
private final int dexMod;
private final int conMod;
private final int wisMod;
public Race (int raceID, double purity, int strMod, int dexMod, int conMod, int wisMod)
{
this.raceID = raceID;
this.purity = purity;
this.strMod = strMod;
this.dexMod = dexMod;
this.conMod = conMod;
this.wisMod = wisMod;
}
public int getRaceID ()
{
return raceID;
}
public double getPurity ()
{
return purity;
}
public int getStrMod ()
{
return strMod;
}
public int getDexMod ()
{
return dexMod;
}
public int getConMod ()
{
return conMod;
}
public int getWisMod ()
{
return wisMod;
}
#Override public String toString ()
{
return "RaceID:" + raceID
+ " purity:" + purity
+ " strMod:" + strMod
+ " dexMod:" + dexMod
+ " conMod:" + conMod
+ " wisMod:" + wisMod;
}
#override public int hashCode ()
{
return raceID;
}
#override public boolean equals (Race r)
{
return (r != null && this.raceID == r.getRaceID());
}
#override public Object clone ()
{
return new Race(this.raceID,this.purity,this.strMod,this.dexMod,this.conMod,this.wisMod);
}
public static void main(String args[])
{
// simple test
ArrayList<Race> races = new ArrayList<Race>();
Race a = new Race(0,0.5,1,2,3,4);
Race b = new Race(1,0.75,2,3,4,5);
Race c = new Race(2,0.25,-1,-2,-3,-4);
races.add(a);
races.add(b);
races.add(c);
for(Race race : races)
{
// System.out.println(race.toString());
System.out.println(race);
}
}
}
Then we have the visual model, which can be handled like this:
class RacePanel implements ActionListener
{
private Map<Integer,JToggleButton> r;
private Map<Integer,Race> f;
public RacePanel()
{
r = new TreeMap<Integer,JToggleButton>();
f = new TreeMap<Integer,Race>();
}
public JToggleButton add (Race a)
{
JToggleButton button = new JToggleButton();
button.setIcon(RCiconSM);
button.setBorder(BorderFactory.createEmptyBorder());
button.setContentAreaFilled(false);
button.setActionCommand(a.getRaceID());
button.addActionListener(this);
r.put(a.getRaceID, button);
f.put(a.getRaceID, a);
}
public void remove (int raceID)
{
r.remove(a.getRaceID);
f.remove(a.getRaceID);
}
// When a button is clicked
public void actionPerformed(ActionEvent e)
{
// related race
Race a = f.get(e.getActionCommand());
// clicked button
JToggleButton b = r.get(e.getActionCommand());
// ..
}
public ArrayList<JToggleButton> getButtonList ()
{
return new ArrayList<Value>(r.values());
}
public ArrayList<Race> getRaceList ()
{
return new ArrayList<Value>(f.values());
}
public Race getRace (int raceID)
{
return f.get(raceID);
}
public JToggleButton getButton (int raceID)
{
return r.get(raceID);
}
// ..
}

Categories

Resources