This code is supposed to fetch the variables from my class Course.
public void prettyPrint(){
Course myCourse = new Course(myCourse.n, myCourse.days, myCourse.start, myCourse.end);
for (int i=0; i>Courses.size();i++){
System.out.println("---"+ Course.dayString + ' '+ ' '+" ---");
System.out.println(myCourse.start +"-"+ myCourse.end+ ": " + myCourse.n );
}
This gets me errors that say "myCourse.n may not be initalized." How do I initialize them if they are just pulling the info from the Course class?
Course myCourse = new Course(myCourse.n, myCourse.days, myCourse.start, myCourse.end); // myCourse is just a reference, when you call new , myCourse hasn't been initialized.
Maybe you should code like this:
Course myCourse = new Course(n, days, start, end);
You cannot reference values in an object before creating it. However, you can create static class variables and reference them without creating any objects as shown:
class Course{
static int n = 1;
static int days = 180;
//..other definitions
//..
}
class Main{
public static void main(){
Course myCourse = new Course(Course.n, Course.days);
}
}
However, static variables introduce dependency between instance variables. A better design would be the factory design pattern with a sample implementation as follows:
class Course{
int n;
int days;
// other instance definitions
public course(int n, int days){
this.n = n;
this.days = days;
}
}
class History extends Course{
public History(){
super(10,200);//the values that you want this course to have
}
}
class Geography extends Course{
public Geography(){
super(20,100);//the values that you want this course to have
}
}
class Main{
public static void main(String args[]){
Course history = new History();
Course geography = new Geography();
}
}
Related
I'd like to create an array of objects where 3 objects are from one class, and a 4th is from second class.
In the first class I did the following:
public class Pupil {
public int n= 0;
Pupil(int n) {
this.n = n;}
}
in the second class I did the following:
public class Tutor {
public int m= 0;
Tutor(int m) {
this.m = m;}
}
In the main class, I created several pupil objects and one tutor object, like this:
public class Main {
public static void main (String[] args) {
//Pupil(n) while for tutor objects it'd be Tutor(m)
Pupil pupil1 = new Pupil(9);
Pupil pupil2 = new Pupil(8);
Pupil pupil3 = new Pupil(6);
Tutor tutor1 = new Tutor(2);
Using objects for printing in main works fine.
But I'd like to create a fourth class where I group them into arrays of objects, but it won't see the objects that I created to create groups out of them. I'm also not sure about the format for creating an array of objects.
public class Groups {
public static void main(String [] args){
Pupil [] g1 = {tutor1, pupil1, pupil2, pupil3};
//cannot resolve any symbols
}
}
EDIT: according to my tutor the groups class should be static to solve this, but I'm not sure how to actually code this?
Edit2: an answer pointed that the array should be Object as the above code would only be able to create an array of pupils, not pupils and tutors objects.
Object [] g1 = {tutor1, pupil1, pupil2, pupil3};
but that still doesn't solve the main issue where no objects are seen from the groups class (//cannot resolve any symbols)
Arrays can only contain the same type of object. With that being said, here is a way:
Object[] g1 = {tutor1, pupil1, pupil2, pupil3};
Java is a strongly typed programming language so you cannot add different type objects to a same collection. But you take advantage of OPP polymorphism principle. You can create a parent class and extend your subclasses from parent class.
Parent Class
public class Group {
}
Child Classes
public class Pupil extends Group {
public int m = 0;
public Pupil(int m) {
this.m = m;
}
}
public class Tutor extends Group {
public int n = 0;
public Tutor(int n) {
this.n = n;
}
}
So this way you can use it as follows:
public class TestSchool {
public static void main(String[] args) {
Pupil pupil1 = new Pupil(9);
Pupil pupil2 = new Pupil(8);
Pupil pupil3 = new Pupil(6);
Tutor tutor1 = new Tutor(2);
Tutor tutor2 = new Tutor(2);
Group[] groupArray = {pupil1, pupil2, pupil3, tutor1, tutor2};
}
}
I'm trying to add let's say 5 classes that they all extend a General class and implements an init() method in a different way.
What I need is a way to store those classes while passing a number of chances for that Class to "happen"
For this I created a Class holder:
public class ClassHolder {
private Class<? extends GeneralOutcome> holdClass;
private int chances;
public ClassHolder(Class<? extends GeneralOutcome> holdClass, int chances) {
super();
this.holdClass = holdClass;
this.chances = chances;
}
public Class<? extends GeneralOutcome> getHoldClass() {
return holdClass;
}
public void setHoldClass(Class<? extends GeneralOutcome> holdClass) {
this.holdClass = holdClass;
}
public int getChances() {
return chances;
}
public void setChances(int chances) {
this.chances = chances;
}
}
Also a GeneralOutcome class that the ones that will be added to a list will extend:
public class GeneralOutcome {
public void init(String text, int times) {
}
}
And the way I'm adding them to a list:
public class Randomizer {
private static List<ClassHolder> myList = new ArrayList<ClassHolder>();
private static ClassHolder outcome01 = new ClassHolder(Outcome01.class, 10);
private static ClassHolder outcome02 = new ClassHolder(Outcome02.class, 10);
private static ClassHolder outcome03 = new ClassHolder(Outcome03.class, 10);
private static ClassHolder outcome04 = new ClassHolder(Outcome04.class, 10);
private static ClassHolder outcome05 = new ClassHolder(Outcome05.class, 10);
public static void main(String[] args) {
for(int i = 0; i < outcome01.getChances(); i++) {
myList.add(outcome01);
}
for(int i = 0; i < outcome02.getChances(); i++) {
myList.add(outcome02);
}
for(int i = 0; i < outcome03.getChances(); i++) {
myList.add(outcome03);
}
for(int i = 0; i < outcome04.getChances(); i++) {
myList.add(outcome04);
}
for(int i = 0; i < outcome05.getChances(); i++) {
myList.add(outcome05);
}
System.out.println(myList.size());
int rand = (int) (Math.random() * myList.size());
System.out.println(rand);
ClassHolder theHoldClass = myList.get(rand);
System.out.println(theHoldClass.getHoldClass());
Class<? extends GeneralOutcome> theOutcome = theHoldClass.getHoldClass();
theOutcome.init();
}
}
The problem is that I'm not able (Don't know how really) cast back to GeneralOutcome to I can access the .init() method.
I get The method init() is undefined for the type Class<capture#3-of ? extends GeneralOutcome>
I know this isn't the best way to do this. So I'm open to both, a fix for this and also what would be a better way to achieve something like this.
What you are trying to do here doesn't work for some reasons.
First of all, your init method isn't static. So that call
Class<? extends GeneralOutcome> theOutcome = theHoldClass.getHoldClass();
theOutcome.init();
leads directly to a compile-time error.
But then, the whole design looks strange. What is the point of holding Class objects in the first place?
Why don't you create an interface
public interface OutcomeFunctionality {
public void foo(String text, int times);
}
to later instantiate objects of whatever class implementing that interface? So that you can finally can deal with lists of such objects (together with those probabilities)?
[ I used the name foo on purpose: alone the strange name "init" makes it very unclear what your code is intended to do! In that sense you should rethink your design, and find better method names to express what those methods will be doing! ]
Long story short: using/holding Class objects doesn't buy you anything in your example code - it only adds complexity. So my advise is: start working there and get rid of that "detour". You might also want to read about the Open/Closed principle - that could give you some guidance how a good OO design looks like that uses abstract classes / subclassing in order to split "behavior" between base and derived classes.
I am having an issue with declaring and initializing object arrays within Java using jGrasp. This is an assignment and I copied the code straight from the book and changed the class and array name. I have tried assigning and initializing without an array by using 'itemA, itemB, itemC' with the same duplicate output as you can see at the bottom of the code.
Driver class:
class Driver
{
public static void main(String[] args)
{
RetailItem[] item = new RetailItem[3];
item[0] = new RetailItem("a", 1, 1);
item[1] = new RetailItem("b", 2, 2);
item[2] = new RetailItem("c", 3, 3);
for (int i = 0; i < item.length; i++)
{
System.out.printf("item: " + item[i].getItemName());
}
}
The output results in:
item: c
item: c
item: c
I do not understand as I am a beginner as to why the output is always the last array object initialized.
The output that I am attempting is:
item: a
item: b
item: c
Here is my RetailItem class:
class RetailItem
{
private static String itemName;
private static int unitsOnHand;
private static double priceEach;
//Constructor(s)
public RetailItem(String name, int qty, double price)
{
itemName = name;
unitsOnHand = qty;
priceEach = price;
}
//Public Methods
public static double getPriceEach()
{
return priceEach;
}
public static String getItemName()
{
return itemName;
}
public static int getUnitsOnHand()
{
return unitsOnHand;
}
}
Your problem is that itemName (and all your other variables) have been declared static. This binds them to the class, not to an instance, so when your constructor alters itemName, it alters that variable for the whole class.
To see what I mean by "class variable", try this: define a main method in RetailItem that looks like this:
public static void main(String[] args) {
// Print the property of the RetailItem *class*: remember, you don't even have an instance of the class at this point.
System.out.println(RetailItem.itemName); // null
RetailItem item = new RetailItem("a", 1, 1);
// Print the property of the class again, ignoring the instance that you created.
System.out.println(RetailItem.itemName); // "a"
}
To resolve this, just remove the static declaration from anything you intend to be an instance variable (as well as the setters/getters!).
private String itemName;
public String getItemName() {
return itemName;
}
The problem is that you're setting the itemName, unitsOnHand, and priceEach as static. Basically this means that all instances of RetailItem will have the same value for each of those variables. If you remove the static keyword each instance will have their own itemName, unisOnHand, and priceEach variables.
I'm working on a classic homework program and cannot for the life of me figure out why my static variable in the superclass reacts the way it does..
The program is a bankaccount where I have created a superclass, Account, and two subclasses, CreditAccount and SavingsAccount.
public abstract class Account {
private double balance;
private int accountId;
**private static int lastAssignedNumber = 1000;** <--- the static int
private String accountType;
public Account (double q_balance, String q_accountType)
{
balance = q_balance;
accountType = q_accountType;
**accountId = ++lastAssignedNumber; <------ counter for new accountId**
}
)
public class CreditAccount extends Account {
public CreditAccount(double balance)
{
super(balance, "Creditaccount");
}
}
public class SavingsAccount extends Account {
public SavingsAccount(double balance)
{
super(balance, "Savingsaccount");
}
}
Previously, without subclasses when Account was the only object, the counter worked beautifully. But now when I create some new objects of savingsaccount and creditaccounts the program acts really weird and returns accountnumbers as follows:
new SavingsAccount(0); // **1001**
new CreditAccount(0); // **1001**
new CreditAccount(0); // **1002**
new SavingsAccount(0); // **1003**
new CreditAccount(0); // **1002**
new CreditAccount(0); // **1004**
new SavingsAccount(0); // **1005**
What in gods name is happening?! What am I missing? Shouldn't the two subclasses provoke the same static variable 'lastAssignedNumber' and add to it accordingly??
Kindest regards // Gewra
There is nothing wrong with your code , given that you are creating accounts in single thread model.
Your following code is working absolutely fine:
abstract class Account
{
private double balance;
private int accountId;
private static int lastAssignedNumber = 1000;
private String accountType;
public Account (double q_balance, String q_accountType)
{
balance = q_balance;
accountType = q_accountType;
accountId = ++lastAssignedNumber;
}
public int getAccountID()
{
return accountId;
}
}
class CreditAccount extends Account
{
public CreditAccount(double balance)
{
super(balance, "Creditaccount");
}
}
class SavingsAccount extends Account
{
public SavingsAccount(double balance)
{
super(balance, "Savingsaccount");
}
}
public class AccountLedger
{
public static void main(String st[])
{
Account ac[] = new Account[7];
ac[0] = new SavingsAccount(0); //1001
ac[1] = new CreditAccount(0); //1002
ac[2] = new CreditAccount(0); //1003
ac[3] = new SavingsAccount(0); //1004
ac[4] = new CreditAccount(0); //1005
ac[5] = new CreditAccount(0); //1006
ac[6] = new SavingsAccount(0); //1007
for (int i = 0 ; i < ac.length ; i++)
{
System.out.println(ac[i].getAccountID());
}
}
}
The concepts of multi- and singlethreading are frankly completely new to me but I've tried making both an AtomicInteger and a volatile variable with the exactly same result. I guess it's my structure of the program that is fundamentaly wrong.
The construct is a BankLogic-class holding an ArrayList of Customer-objects. The Customer-objects hold an ArrayList of Account-objects. It doesn't matter where I put the AtomicInteger-object, even though I put it in the BankLogic-class and pass it through to the constructor, it still turns out the same results.
Guess I should just place the accounts-ArrayList in the BankLogic-class and run a method comparing personal-ids (adding a persId-variable to the account-class) instead?
It certainly doesn't feel like such an elegant solution but I see no other way.
Thanks for all the answers!
I am very new to programming and have a question about using variables in what I believe to be called "nested classes."
class BeginningGameTest {
int attack;
int defend;
public static class James
{
attack = 25;
defend = 15;
}
public static class Janet
{
attack = 45;
defend = 1;
}
public static class Jackson
{
attack = 10;
defend = 20;
}
public static void main(String[] args) {
System.out.prinln(James.attack);
}
}
Do I have the general idea down? I would like to save variables that are the "same" thing, but are different from class to class and are accessed differently like in the print line. I do get a few errors, what should I do to keep the same concept and still keep it fairly simple so I could understand it? Are there any easy to understand tutorials for people who are new to programming in general?
Thanks in advance!
The design of this seems incorrect.
What you're trying to go for when working in an object-oriented language is the basic model of something you wish to represent.
Those three static classes seem to represent the same type of object, so let's create a simple model for them. Think of models like a cookie-cutter. Every cookie cut with this will be the same generic "shape", but will have different characteristics about it (sprinkles, frosting beard, etc). This model should be in its own separate file.
public class Player {
private String name;
private int attack;
private int defense;
public Player(String theirName, int theirAttack, int theirDefense) {
name = theirName;
attack = theirAttack;
defense = theirDefense;
}
// create getters and setters for their attack and defense
}
To actually make use of it, you'd want to instantiate the object.
public class BeginningGameTest {
public static void main(String[] args) {
Player p1 = new Player("James", 25, 15);
Player p2 = new Player("Janet", 45, 1);
Player p3 = new Player("Jackson", 10, 20);
// interactions with the objects below
}
}
Some superb beginner resources already exist in the Java tag wiki; give those a thorough reading. Try new things out, and don't be afraid to ask (good) questions about things you don't understand.
You should create an inner class then define instances of that class within the main method.
public class BeginningGameTest {
public static void main(String[] args) {
Player james = new Player(25,15);
Player janet = new Player(45,1);
Player jackson = new Player(10,20);
System.out.println(james.getAttack());
}
}
class Player{
int attack;
int defend;
public Player(int attack, int defend){
this.attack = attack;
this.defend = defend;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefend() {
return defend;
}
public void setDefend(int defend) {
this.defend = defend;
}
}
You should use the concept of instances to distinguish persons, rather than defining a class for each person. You can define a single class "Person" and instantiate James, Jackson etc. To give them each different attack/defence values, you can use constructors with arguments.
I feel that you might benefit from reading an introduction to object oriented programming. Try searching for "object oriented programming".
You can go two ways about this. You could create subclasses such that James, Janet and Jackson are all classes of the same type, being BeginningGameTest. For example, James could be:
public class James extends BeginningGameTest
{
public James()
{
attack = 25;
defend = 15;
}
}
What I think you want James, Janet and Jackson to be, are not subclasses, but rather instances of the same class BeginningGameTest, like this:
BeginningGameTest James = new BeginningGameTest();
James.setAttack(25);
James.setDefend(15);
There are a few concepts you should read upon:
Classes vs instances
Inheritance
And I also implicitly introduced you to the concept of setters (and getters), typical for Java beans.
This will work:
public static class James
{
static int attack = 25;
static int defend = 15;
}
// ...
Then this would work:
public static void main(String[] args)
{
System.out.prinln(James.attack);
}
This is probably a better design:
public class Player()
{
public static enum NAME { JAMES, JANET };
int attack, defend;
public Player(NAME name)
{
switch (name)
{
case JAMES:
attack = 25;
defend = 15;
break;
// ...
}
}
public static void main(String[] args) throws Exception
{
System.out.println(new Player(NAME.JAMES).attack);
}
}
This is a better design for realistic requirements: (allowing run-time creation of players)
int attack, defend;
String name;
public Player(int attack1, int defend1, String name1)
{
attack = attack1;
defend = defend1;
name = name1;
}
What you can simply do is create different objects of your class that will hold different values of variables attack and defend. Here is the code for the same.
/* package whatever; // don't place package name! */
class Main
{
int attack,defend;
public Main(int attack,int defend)
{
this.attack=attack;
this.defend=defend;
}
public void show()
{
System.out.println("attack: "
+attack+" defend: "+defend);
}
public static void main (String[] args) throws java.lang.Exception
{
Ideone James = new Main(125,15);
James.show();
Ideone Janet = new Main(45,1);
Janet.show();
Ideone Jackson = new Main(10,20);
Jackson.show();
}
}