How to create objects from a class with private constructor? - java

I have a class Game that is my main class and a second class Card.
Class Card hast its properties and constructor private, only function init is public.
Function init checks values for plausibility and if everything is fine than the constructor gets the values and creates an object.
Now I wannt in class Game to create an object from class Card.
How should I do this?
Here is my code:
Class Game:
import java.util.List;
import java.util.Vector;
public class Game {
public static void main(String[] args)
{
/*
CREATING NEW CARD OBJECT
*/
int value = 13;
Vector<Card> _card_set = new Vector<Card>();
for (int i = 2; i < 54; i++)
{
if(--value == 0)
{
value = 13;
}
Card _myCard;
_myCard.init(i,value);
}
}
}
Class Card:
public class Card {
private int index;
private int value;
private String symbol;
/*
CREATING A PLAYCARD
*/
private Card(int index,int value)
{
this.index = index;
this.value = value;
value = (int) Math.floor(index % 13);
if(this.index >= 2 && this.index <= 14)
{
this.symbol = "KARO";
}
else if (this.index >= 15 && this.index <= 27)
{
this.symbol = "HERZ";
}
else if (this.index >= 26 && this.index <= 40)
{
this.symbol = "PIK";
}
else if (this.index >= 41 && this.index <= 53)
{
this.symbol = "KREUZ";
}
System.out.println("Card object wurde erstellt: " + symbol + value);
System.out.println("------<><><><>------");
}
/*
SHOW FUNCTION
GET DETAILS ABOUT PLAYCARD
*/
public String toString()
{
return "[Card: index=" + index + ", symbol=" + symbol + ", value=" + value + "]";
}
/*
Initialize Card object
*/
public Card init(int index, int value)
{
/*
Check for plausibility
if correct constructor is called
*/
if((index > 1 || index > 54) && (value > 0 || value < 14))
{
Card myCard = new Card(index,value);
return myCard;
}
else
{
return null;
}
}
}

You should define your init method as static, implementing the static factory method that Braj talks about. This way, you create new cards like this:
Card c1 = Card.init(...);
Card c2 = Card.init(...);
...

As #Braj mentioned in comments, you can use static factory. Private constructor cannot be accessed outside of class, but it can be accessed from inside, like the following:
public class Test
{
private Test(){
}
static Test getInstance(){
return new Test();
}
}
This pattern can be used for making Builders, for example.

Note :
You can access private constructor from within the class itself as in a public static factory method.
You can access it from the enclosing class it its a nested class.

public class demo
{
private demo()
{
}
public static demo getObject()
{
return new demo();
}
public void add()
{
}
}
class Program
{
static void Main(string[] args)
{
demo d1 = demo.getObject();
d1.add();
}
}

I would say don't make the constructor private, don't make the build code under the constructor (place it in a new method, which can be private) and make a method to return the card outside the class.
Then use the card object and call the method to retrieve your card from the Card class, make sure to declare the type Card and make sure that the method returns properly.

Class<?> class = Class.forName("SomeClassName");
Constructor<?> constructor = class.getConstructors[0];
constructor.setAccessible(true);
To convert the privately declared constructor to the public one till program execution. Also, this concept is related to Reflection API.
Object o = constructor.newInstance();
if(o.equals(class)) {
System.out.println("Object for \"SomeClassName\" has been created");
}

Related

Cannot pass random enum value to function in Java

Cheers, I am pretty new to java and I and I have ran across a problem
I have three classes, all inheriting things between them. Starting I have a class A:
public class A{
private int index;
public A(int index) {
System.out.println("Creating an instance of A");
this.index = index;
}
}
then I have a sublass of A, class M which has a enum inside as:
public class M extends A{
public enum Letter {
A,B,C;
}
private Letter letter;
public M(int index, Letter aLetter) {
super(index);
System.out.println("Creating an instance of M");
this.letter = aLetter;
}
}
and finally a last class P , subclass of M:
public class P extends M {
private T t;
public enum T{
o,
a,
t
}
public P(int index, Letter aLetter, T aT) {
super(index,aLetter);
System.out.println("Creating an instance of P");
this.t = aT;
}
}
What I want to do is create e.g. 3 objects of the class P, and pass on to them RANDOMLY a value of each of these enums. I thought of creating a function in the main class which would be kind of like:
Letter getRandLetter() {
Random rand = new Rand();
int pick = rand.nextInt(M.Letter.values().length);
if (pick == 0) {
return Letter.A;
} else if (pick == 1) {
return Letter.B;
} else {
return Letter.C;
}
}
my main looks like this:
int N = 3;
M[] new_m = new M[N]
for(int i = 0; i < N; i++) {
new_m[i] = new P(i, getRandLetter(), getRandT());
}
however I get this error: Cannot make a static reference to the non-static method . What Can I do to achieve what I want?
The error is telling what to do:
Cannot make a static reference to the non-static method
Your main method is static, and the methods called from it should be static as well. So your getRandLetter() and getRandT() methods should be static.
getRandLetter() should look like this:
static Letter getRandLetter() {
Random rand = new Rand();
int pick = rand.nextInt(M.Letter.values().length);
if (pick == 0) {
return Letter.A;
} else if (pick == 1) {
return Letter.B;
} else {
return Letter.C;
}
}
And getRandT() should be static as well.

"actual and formal argument lists differ in length" error

I'm trying to create a class that will do everything that a different class can do, but it will use random integers in order to create the objects that would normally require user input. Here I have a Pokemon program where I have class where the user creates a Pokemon trainer by inputting their name, and the program will create an ArrayList where the trainer's Pokemon are stored. I have a subclass called ComputerTrainer where it should have the same functionality, but randomly generated Pokemon will be added to the trainer's list of Pokemon. I created a constructor that accesses the protected variables in the PokemonTrainer class, but I'm getting an error that says "reason: actual and formal argument lists differ in length". Why I am getting this error?
Here is the code for the PokemonTrainer class:
import java.util.ArrayList;
public class PokemonTrainer
{
// private constants
private static final int MAX_POKEMON = 2;
protected ArrayList<Pokemon> pokemonList;
protected String name;
protected int numOfPokemon;
// Write your PokemonTrainer class here
public PokemonTrainer(String name)
{
this.name = name;
pokemonList = new ArrayList<Pokemon>();
}
public boolean addPokemon(Pokemon p)
{
if(numOfPokemon < MAX_POKEMON)
{
pokemonList.add(p);
numOfPokemon++;
return true;
}
else
{
return false;
}
}
public boolean hasLost()
{
int numOfPokemonThatLost = 0;
for(Pokemon p : pokemonList)
{
if(p.hasFainted())
{
numOfPokemonThatLost++;
}
}
if(numOfPokemonThatLost == numOfPokemon)
{
return true;
}
else
{
return false;
}
}
public Pokemon getNextPokemon()
{
int nextPokemon = 0;
int numOfPokemonThatLost = 0;
for(Pokemon p : pokemonList)
{
while(p.hasFainted() && nextPokemon < numOfPokemon)
{
nextPokemon++;
numOfPokemonThatLost++;
if(nextPokemon < numOfPokemon)
{
p = pokemonList.get(nextPokemon);
}
}
}
if(numOfPokemonThatLost == numOfPokemon)
{
return null;
}
else
{
return pokemonList.get(nextPokemon);
}
}
public Pokemon getPokemon(int nPokemon)
{
return pokemonList.get(nPokemon);
}
public int getNumberOfPokemons()
{
return pokemonList.size();
}
public static int getMaxPokemon()
{
return MAX_POKEMON;
}
public String toString()
{
return name;
}
}
and here is the code for the ComputerTrainer subclass:
import java.util.ArrayList;
import java.util.Random;
public class ComputerTrainer extends PokemonTrainer
{
// private constants
// Possible pokemon names and move names to generate random Pokemon
private static final String[] POKEMON_NAMES = {"Pikachu", "Bulbasaur", "Charmander", "Squirtle"};
private static final String[] MOVE_NAMES = {"Tailwhip", "Bodyslam", "Splash", "Shock"};
private static final int MAX_DAMAGE = 25;
private static final int MAX_MOVES = 4;
private PokemonImages images = new PokemonImages();
// Write a Constructor that sets the name of the ComputerTrainer
// and adds 2 randomly generated Pokemon to itself
public ComputerTrainer(String name)
{
this.name = name;
pokemonList = new ArrayList<Pokemon>();
for(int i = 0; i < PokemonTrainer.getMaxPokemon(); i++)
{
Random num = new Random();
int randomNumber = num.nextInt(POKEMON_NAMES.length);
Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
pokemonList.add(p);
numOfPokemon++;
}
}
/*
* Adds a randomly generated Pokemon to this ComputerTrainer's
* collection of Pokemon. A ComputerTrainer can only have 2
* Pokemon. This method returns true if there was room for the
* new Pokemon and it was successfully added, false otherwise.
*/
public boolean addRandomPokemon()
{
if(numOfPokemon < PokemonTrainer.getMaxPokemon())
{
Random num = new Random();
int randomNumber = num.nextInt(POKEMON_NAMES.length);
Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
pokemonList.add(p);
numOfPokemon++;
return true;
}
else
{
return false;
}
}
// Returns a Move randomly chosen from the set of Moves
// that this trainer's current Pokemon knows.
// If all Pokemon have fainted, returns null.
public Move chooseRandomMove()
{
Pokemon currentBattlingPokemon = getNextPokemon();
// This method isn't finished yet
}
}
The program outputs the following error:
ComputerTrainer.java:20: error: constructor PokemonTrainer in class PokemonTrainer cannot be applied to given types;
{
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
The problem is that PokemonTrainer only has a constructor that has one String as parameter:
public class PokemonTrainer
{
public PokemonTrainer(String name) {
...
}
but you are not calling that constructor from ComputerTrainer:
public class ComputerTrainer extends PokemonTrainer
{
public ComputerTrainer(String name) {
this.name = name;
...
}
}
Java does not automatically call the constructor of the superclass that matches the actual constructor, it calls the default (parameter-less constructor) but the superclass does not have it.
Solution: add an explicit invokation of the correct constructor of the superclass:
public class ComputerTrainer extends PokemonTrainer
{
public ComputerTrainer(String name) {
super(name);
...
}
}
see Java Language Specification 8.8.7. Constructor Body for more details
Note: the error message is a bit confusing since there is like a hidden super() call as first statement in the ComputerTrainer constructor

How to call out method with parameter?( Java )

I'm working on a task given off of a textbook . I can't call out the "poisonAttack" method from the same class. Would appreciate if anyone can give me feedback.
public class PoisonMatango extends Matango {
PoisonMatango pm = new PoisonMatango ('A');
public PoisonMatango ( char suffix) {
super(suffix);
}
// The method I am trying call.
public void poisonAttack(Hero h) {
super.attack(h);
int poisonCount = 5;
if ( poisonCount >=0 ) {
System.out.println("The enemy had spread poisonous pollons");
int pollenDamage = h.hp / 5;
h.hp-= pollenDamage;
System.out.println("Hero has received " + pollenDamage + "damage from " );
poisonCount --;
}else
{
System.out.println("No additional attack were made since poisonCount= 0");
}}
}
You have to use Class object 'pm' created to call method and pass required parameter as per method definition. Your code is having Object type param of class Hero
pm.poisonAttack(hr);
Below is solution for above code:-
// Class Object used as param in solution
public class Hero {
int hp = 100;
}
// Super Class
public class Matango {
Hero a;
public Matango(Hero suffix) {
this.a =suffix;
}
// Super Class Method
public void attack(Hero h){
System.out.println("\n\nHero hp var value::"+h.hp);
}
}
// PoisonMatango
public class PoisonMatango extends Matango {
public PoisonMatango ( Hero suffix) {
super(suffix);
}
// The method I am trying call.
public void poisonAttack(Hero h) {
super.attack(h);
int poisonCount = 5;
if ( poisonCount >=0 ) {
System.out.println("The enemy had spread poisonous pollons\n");
int pollenDamage = h.hp / 5;
h.hp-= pollenDamage;
System.out.println("Hero has received " + pollenDamage + "damage from \n" );
poisonCount --;
}else
{
System.out.println("No additional attack were made since poisonCount= 0 \n");
}}
public static void main(String args[])
{
// Create Object of Param class, this example passes object but we can pass simple data type as per method definition.
Hero hr = new Hero();
PoisonMatango pm = new PoisonMatango (hr);
pm.poisonAttack(hr);
}
}

make a global object in java

I want to make an array of objects and use it in different functions. I wrote this pseudocode
privat stock[] d;
privat stock example;
public void StockCheck(){
d =new stock[2];
d[0]= new stock("a","test1", 22);
d[1]= new stock("b","test2", 34);
}
#Override
public stock getStock(String name) throws StockCheckNotFoundException{
int i;
System.out.println("ok" + name + d.legth); // error
example = new stock("example","example",2);
return example;
}
In class test I make an instance of getStock and I call the function getStock stock.getStock();
I get a NullPointerExeption when I do d.length. d is null but I don't understand why.
Hmmmm. If that is in any way like your real code, then the problem is that your "constructor" isn't really a constructor, as you've declared it to return void, making it an ordinary method instead. Remove tbat "void" and it may fix the problem!
Perhaps this example of code will do what you need, using three classes
Test - the main test code
Stock - the implied code for Stock from your question
StockCheck - the corrected code from your question.
(Note: you may really want to use an ArrayList inside StockQuote so you can add and delete Stocks.)
Test class
package stackJavaExample;
public class Test {
public static void main(String[] args) {
String[] testNames = {"test1","test2","notThere"};
StockCheck mStockCheck = new StockCheck();
for (int i=0; i<testNames.length; i++) {
Stock result = mStockCheck.getStock(testNames[i]);
if (result == null) {
System.out.println("No stock for name: " + testNames[i]);
} else {
System.out.println("Found stock: " + result.getName() + ", " + result.getSymbol() + ", " + result.getValue());
}
}
}
}
Stock class
package stackJavaExample;
public class Stock {
private String symbol;
private String name;
private double value;
public Stock(String symbol, String name, double value) {
this.symbol = symbol;
this.name = name;
this.value = value;
}
public String getSymbol() { return symbol;}
public String getName() { return name;}
public double getValue() {return value;}
}
StockCheck class
package stackJavaExample;
public class StockCheck {
private Stock[] d;
public StockCheck() {
d = new Stock[2];
d[0] = new Stock("a","test1", 22);
d[1] = new Stock("b","test2", 34);
}
public Stock getStock(String name) {
for (int i=0; i < d.length; i++) {
if (d[i].getName().equalsIgnoreCase(name)) {
return d[i];
}
}
return null;
}
}

What is wrong with my testing Player Class in Blackjack Java

I am trying to test my player class properly, I have almost done it but I am having issues with my p1.setPlayerHand method. This is the following code I have used for my player class:
Player Class:
package model;
public class Player
{
private String PlayerName;
private Hand PlayerHand;
private boolean Dealer;
public Player(String name)
{
PlayerName = name;
PlayerHand = new Hand();
Dealer = false;
}
public void setName (String name)
{
this.PlayerName = name;
}
public String getName()
{
return PlayerName;
}
public void setDealer (Boolean dealer)
{
this.Dealer = dealer;
}
public boolean getDealer()
{
return Dealer;
}
public void setPlayerHand (Hand hand)
{
this.PlayerHand = hand;
}
public void getHand()
{
PlayerHand.displayCardsinHand();
}
public static void main (String [] args)
{
Player p1 = new Player("player1");
Hand h = new Hand();
//System.out.println(p1);
p1.setName("BARRY");
System.out.println(p1.getName());
p1.setDealer(false);
System.out.println(p1.getDealer());
//this is the error that is preventing my program to run
p1.setPlayerHand(h.addCard(new Card(Suit.CLUBS, CardRank.ACE)));
p1.getHand();
}
}
The following error I receive (after testing the Player Class) is this:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The method setPlayerHand(Hand) in the type Player is not applicable for the arguments (void)
at model.Player.main(Player.java:57)
This is the Hand Class underneath (that is linked to the Player Class):
Hand Class:
package model;
import java.util.Vector;
import java.util.Random;
public class Hand
{
private Vector<Card> hand;
public Hand()
{
hand = new Vector<Card>();
}
public void addCard(Card c)
{
hand.add(c);
}
public void displayCardsinHand()
{
for (int card = 0; card < hand.size(); card++)
{
System.out.println(hand.elementAt(card));
}
}
public int getCardsinHand()
{
return hand.size();
}
public Card getCard(int position)
{
if(position >= 0 && position < hand.size())
return (Card)hand.elementAt(position);
else
return null;
}
public int getScore()
{
int value = 0;
boolean ace = false;
for (int i = 0; i < hand.size(); i++)
{
Card c;
c = getCard(i);
value = value + c.getRankValue();
if(c.getRankValue() == 1)
{
ace = true;
}
}
if(ace == true && value + 10 <= 21)
{
value = value + 10;
}
return value;
}
public static void main (String [] args)
{
Hand h = new Hand();
System.out.println(h);
h.displayCardsinHand();
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.HEARTS, CardRank.ACE));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.SPADES, CardRank.JACK));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.DIAMONDS, CardRank.QUEEN));
System.out.println(h.getCardsinHand());
h.addCard(new Card(Suit.CLUBS, CardRank.KING));
System.out.println(h.getCardsinHand());
System.out.println(h.getCardsinHand());
h.displayCardsinHand();
h.getCard(1);
System.out.println(h.getScore());
}
}
I have tried modifying the p1.setPlayerHand testing numerous times. I appreciate any advice and tips on how to solve this issue, thank you.
If my code is too long for this post then I will gladly accept any advice on what I should do to cut it short (for future reference).
If anyone here required to see any other classes that I wrote (that may help them help me solve this error) then please notify me on here, thank you.
The method addCard doesn't return anything (void). So you can't pass the result of this method to setPlayerHand(Hand). That's what you're doing.
The code should compile and run if you change
p1.setPlayerHand(h.addCard(new Card(Suit.CLUBS, CardRank.ACE)));
to
h.addCard(new Card(Suit.CLUBS, CardRank.ACE));
p1.setPlayerHand(h);
This is because the setPlayerHand method needs to be passed an object of type Hand, but the addCard method doesn't return anything (it's declared as void).

Categories

Resources