I'm in a java course so I'm trying to be a little vague with the code so I can learn but not cheat. The assignment is to take last week's program and extend functionality. Basically, I wrote a program where I'm using switch with two cases (not sure that's the best choice, but it's what I did), and I want to add more user options. So it currently allows input 'w', 'x', but I want to add 'y' and 'z' as options by extending class A with class B.
There is a default case in the class A that basically outputs "only enter 'w' and 'x'." The problem, is even with the new B class which extends it, it prevents anything but 'w' and 'x'.
I know I need the B class to override that so it allows w, x, y, and z, and then the default triggers when anything but those four options are entered. Either way, help please!
Below is class A (I got rid of some of the code for my question, but all the variables, user input and scanner work. It's the cases I'm having issues with):
import java.util.Scanner;
public class A {
public A()
{
// define and implement variables
// call scanner into existance to read inputs from the user
// Ask for user input (abbreviated section) and store in variables
oper = myManager.next(".").charAt(0);
switch(oper)
{
// case w call to firstMethod method
case 'w':
DoSomething = firstMethod(num1,num2);
System.out.println(" The result is "+FirstAns);
break;
// case w call to secondMethod method
case 'x':
DoSomethingElse = secondMethod(num1,num2);
System.out.println(" The result is "+SecondAns);
break;
default:
System.out.println(" Please Enter 'w' or 'x' only.");
}
/* note, this portion I got rid of some work, it's normally
math related but modified here just to return characters for
this post since I think it's irrelevant to my question (and I
don't want to cheat) */
static char firstMethod(char a)
{
return a;
}
static char secondMethod(char a)
{
return a;
}
}
}
And below is class B which extends A, and I'm not able to convince to allow more cases. Note, after compilation, I'm executing B, but it's still only allowing the cases from A.
import java.util.Scanner;
public class B extends A {
public B()
{
// define and implement variables
// call scanner into existance to read inputs from the user
// Ask for user input (abbreviated section) and store in variables
oper = myManager.next(".").charAt(0);
switch(oper)
{
// case w call to firstMethod method
case 'w':
DoSomething = firstMethod(num1,num2);
System.out.println(" The result is "+FirstAns);
break;
// case w call to secondMethod method
case 'x':
DoSomethingElse = secondMethod(num1,num2);
System.out.println(" The result is "+SecondAns);
break;
case 'y':
DoSomethingMore = thirdMethod(num1,num2);
System.out.println(" The result is "+ThirdAns);
break;
// case w call to firstMethod method
case 'z':
DoSomethingLast = fourthMethod(num1,num2);
System.out.println(" The result is "+FourthAns);
break;
default:
System.out.println(" Please Enter 'w', 'x', 'y', or 'z' only.");
}
}
// again, simplified this portion
static char thirdMethod(char a)
{
return a;
}
static char fourthMethod(char a)
{
return a;
}
public static void main(String[] args) {
B b = new B();
}
}
I then update the test program to import class B (instead of the old program which imported A since B is supposed to extend A). But it still only shows cases from A. I know it's the order of operations on how the program loads the cases, just not sure how to fix it.
The default constructor of a superclass is always called first by the default constructor of the subclass.
In your example, the class A constructor is called when creating class B with the default constructor.
A solution is to move your logic into a method with the same signature in both classes and call that method in the constructor of the superclass.
Something like this:
class A {
public A() {
logic();
}
private void logic() {
// Your switch of A
}
}
class B extends A {
public B() {
super();
}
private void logic() {
// Your switch of B
}
}
Dynamic Binding is the OO-principle behind this solution.
Related
How does Java decide which constructor to call in below program?
public class Test
{
Test(int a, int b)
{
System.out.println("a = "+a+" b = "+b);
}
Test(int a, float b)
{
System.out.println("a = "+a+" b = "+b);
}
public static void main (String args[])
{
byte a = 10;
byte b = 15;
Test test = new Test(a,b);
}
}
The the first constructor taking second parameter as int is called, but if I remove first constructor, then the other constructor is called. In case both constructors are there, why the first one is called?
In the first case both byte arguments are widened to int, and this is preferable to converting one argument to float.
In the second case there's no constructor taking two ints, so the only possible choice involves the conversion.
The language definition document contains an exhaustive discussion of constructor resolution.
package RPG;
import java.util.Random;
import java.util.Scanner;
public class Beginnings
{
public static boid main (String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Pick a class:");
System.out.println("Fighter: Deals more damage");
System.out.println("Mage: Has more health");
System.out.println("Theif: Deals less damage but has more health");
String Class = scan.nextLine();
if (Class.matches(".*Fighter.*"));
Fighter user = new Fighter();
else if (Class.matches(".*Mage.*"));
Mage user = new Mage();
else if (Class.matches(".*Thief.*"));
Thief user = new Thief();
else
Human user = new Human();
user.Name();
user.Explore();
/*When I run the code, it highlights the first "user" and says "variable declaration not allowed here"
I don't know how to fix this.
*/
You've got a few spelling mistakes that might be causing problems
public static boid main (String[] args)
should be
public static void main (String[] args)
and
System.out.println("Theif: Deals less damage but has more health");
should probably be
System.out.println("Thief: Deals less damage but has more health");
Futhermore, capital case Class() and lowercase class are already things in the Java SDK as well. You should use a different variable name. I've used characterStr in my example below. Standard practice dictates that you should use camelcase for naming variables and upper case for naming Java classes. When instantiating a Class() object, people generally instantiate it as Class clazz = new Class().
Moving forward, I think you should create a super class for your different User Classes. Set up something like this:
public abstract class Character
public class Fighter extends Character
public class Thief extends Character
public class Mage extends Character
public class Human extends Character
This way, the code in your main() can use your Character() object
public static void main(String[] args)
{
// Prompt the user for the character they want
Scanner scan = new Scanner(System.in);
System.out.println("Pick a class:");
System.out.println("Fighter: Deals more damage");
System.out.println("Mage: Has more health");
System.out.println("Theif: Deals less damage but has more health");
// Get the user's response
String characterStr = scan.nextLine();
Character user; // You might have to initialize this. Did not test
if (characterStr.matches(".*Fighter.*"))
{
user = new Fighter();
}
else if (characterStr.matches(".*Mage.*"));
{
user = new Mage();
}
else if (characterStr.matches(".*Thief.*"));
{
user = new Thief();
}
else
{
user = new Human();
}
user.Name();
user.Explore();
}
First problem : You cannot declare a variable in the then of the if statement if you don't put the declaration between parenthesis. The compiler doesn't accept it.
Second problem : you should declare a single variable before the if-else-if if you want at the end call a method on the instantiated instance as you do :
user.Name();
user.Explore();
In each if you should instantiate the suitable child User class and assign the it to the user variable declared above.
In Java, method should begin with lowercase. I modified it.
The code supposes that User is the parent class and class you instantiate in condition statements are subclasses of User.
User should define a name() method and a explore() method.
User user = null;
if (Class.matches(".*Fighter.*")){
user = new Fighter();
}
else if (Class.matches(".*Mage.*")){
user = new Mage();
}
else if (Class.matches(".*Thief.*")){
user = new Thief();
}
else{
user = new Human();
}
user.name();
user.explore();
Assuming the 'user' is a player who has a 'class' (ie fighter / mage). I would make a separate player class and store that information.
class Player {
String classType; // where you would store the player's class information
int hitPoints;
}
The type of the variable has to be a common base class of all objects you potentially assign to it. Since the class Object is a base class of all other classes, you could do this:
Object user = new Fighter();
But it is probably not a good idea.
You should probably derive Fighter, Mage etc. from a base class, say Character. Instead of a base class you can also use an interface.
I have two classes
Class1:
public class Class1 {
public static void main(String[] args) {
Class2 classObject = new Class2();
classObject.add(2, 3);
classObject.print();
}
}
And Class2:
public class Class2 {
public int add(int a, int b) {
int n = a + b;
return n;
}
public void print() {
System.out.println(add(2,3));
}
}
I want to use the print method to print out what is being returned in the add method.The add method gets its information from the classObject as seen in Class1.
I know there are different ways to go about doing this, but i'm quite sure that there is a way to do it the way i want to, i just can't figure out how.
In Class2 in the print method when i called the add method i put arbitrary numbers there. What i want to do is somehow bring the numbers from from classObject.add(int,int) and print the the returning integer n.
If what you want to demonstrate is showing an object with state, maybe you mean something like this:
public class Class2 {
int n;
public void add(int a, int b) {
n = a + b;
return n;
}
public void print() {
System.out.println(n);
}
}
This way Object1 never knows the internals of Object2, and it's really a pretty good abstraction.
You can simply change the signature of the print method as below. Method like print are processing methods which needs the input which you can pass as method arguments.
public void print( int a) {
System.out.println(a);
}
Now you need to make a simple call like below.
classObject.print(classObject.add(2,3));
You should not be calling add method from inside the print method. As per the name it seams print is a general purpose method. You should pass input as method arguments and it should be responsible to print the input.
If you wish your print method to just print addition then You can pass the two numbers as input parameters to method print and also change the method name as below. You need to call the method add from inside the print (modified version). In this case you should hide the method add and make it private.
public void printTheAddition(int n, int m){
System.out.println(add(n,m));
}
In this case just call printTheAddition method with two input arguments.
So I am super new to programming in general and I'm only a few weeks into a beginning summer course on Java and I'm super confused on this assignment for a simple java calculator that we need to use three classes in.
I decided to write the code and get "working" in one class and then try and split it up into the necessary multiple classes. However, I'm having trouble doing that. I guess I'm more confused then I thought I was on how methods and parameters work. I'd greatly appreciate any help explaining how they work particularly in this program or something similar so that I can understand it more clearly.
Here are a part of the instructions that I'm having a hard time with....
"The Driver class is the only class wit hmain(String[] args)method.Driver class should call a method in the Menu class to print the menu, and from that method there should be calls to methods in Actions class for respective functionality from the menu."
The Menu class and the method calls are working correctly and I planned on basically adding the rest to the Action class but I just keep confusing myself more every time I mess with it. I don't know if it makes a difference but I thought about adding the switch to the Menu class, also if I do, do I need to make it a method to call the switch? How would that work?
import java.util.Scanner;
import java.io.*;
public class Driver {
public static void main(String[] args) {
String s1 = Menu.getInput("Enter a numeric value: ");
String s2 = Menu.getInput("Enter a numeric value: ");
String option = Menu.getInput("Enter: \n 1=Add \n 2=Subtract \n 3=Multiply \n 4=Divide");
class Action {
int optionInt = Integer.parseInt(option);
double result = 0;
switch (optionInt) {
case 1:
result = addValues(s1, s2);
break;
case 2:
result = subtractValues(s1, s2);
break;
case 3:
result = multiplyValues(s1, s2);
break;
case 4:
result = divideValues(s1, s2);
break;
default:
System.out.println("You entered an incorrect value");
}
public static String(
System.out.println("The answer is " + result);
}
private static double divideValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 / d2;
return result;
}
private static double multiplyValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 + d2;
return result;
}
private static double subtractValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 - d2;
return result;
}
private static double addValues(String s1, String s2) {
double d1 = Double.parseDouble(s1);
double d2 = Double.parseDouble(s2);
double result = d1 + d2;
return result;
}
}
}
class Menu {
public static String getInput(String prompt) {
String option;
Scanner scan = new Scanner(System.in);
System.out.println(prompt);
return option = scan.nextLine();
}
}
Thanks for any help!!
Scott
I think this is what you probably looking for :
import java.util.Scanner;
import java.io.*;
public class Driver {
public static void main(String[] args) {
// get the Menu instance & call the method to get the menu list
Menu m = new Menu();
m.getMenu();
}
}
Note: Note here inorder to call a method that resides in another class you first need to get instance of the class and then on that instance you need to invoke the method. Like in the above m.getMenu()
In Menu class you need to write the following logic :
class Menu {
public void getMenu() {
// take the user inputs and write your validation and proper conversion logic e.g 'int' or 'double' what ever you want
Scanner s = new Scanner(System.in);
System.out.println("Enter the first number :");
double num1 = s.nextDouble();
System.out.println("Enter the second number :");
double num2 = s.nextDouble();
System.out.println("Please select an operation :");
System.out.println("1 - Add " + "\n" + "2 - Subtract" + "\n"
+ "3 - Multiply" + "\n" + "4 - Divide");
int choice = s.nextInt();
Double result;
Action service = new Action();
switch (choice) {
// call the appropriate method based on user selection
case 1:
result = service.addValues(num1, num2);
service.displayResult(result);
break;
case 2:
result = service.subtractValues(num1, num2);
service.displayResult(result);
break;
case 3:
result = service.multiplyValues(num1, num2);
service.displayResult(result);
break;
case 4:
result = service.divideValues(num1, num2);
service.displayResult(result);
break;
default:
System.out.println("Your choice is invalid.");
}
}
}
NOte: Here you're doing nothing but taking the user inputs and passing those inputs as parameter to the appropriate methods. (Again note here, how the methods are being invoked).
In Action class put your service logic
class Action {
public double addValues(double a, double b) {
return a + b;
}
public double subtractValues(double a, double b) {
return a - b;
}
public double multiplyValues(double a, double b) {
return a * b;
}
public double divideValues(double a, double b) {
return a / b;
}
public void displayResult(double result) {
System.out.println("Result is :" + result);
}
}
Note: Here each method serves a very different purpose. When you invoke any method on the instance of this class by passing your user inputs as parameter then it simply serve its purpose.
P.S:
Methods are much like your behaviors. Simply consider yourself as a machine. Now when you get thirsty you drink water, right? so here is your brain that is the main() instructing your hand to perform some task much like you're invoking a method to serve a purpose here. (I don't know how far I able to give a clarity of this, but I hope this will be helful to you in some extent :) )
Firstly, I'd recommend a good book, or failing that, look through Oracle's resources such as this...
Java is an object oriented language. An object is an INSTANCE of a class. Think of classes like modules, that are logically separated and in theory should be runnable and logical not only in the environment which you create it, but in other scenarios as well.
For example, you may have a program called Car Park, which is the driver (contains the main method, the entry point to a Java program). You then have a class called Car, and a class called Person. A class should contain variables and method related to that class. So in the Car class, you may have variables such as colour, noOfWheels, noOfSeats etc. The car class may also contain methods to 'do things' associated with the class, such as updateColor() or changeNoOfWheels().
In regards to methods and parameters, it is really quite simple.
When a method is defined as such:
public void updateColor(Color newColor)
{
color = newColor;
}
The Color that is being passed inbetween the brackets is called the formal parameter. It defines the type that is required when the method is actually called. This can be any type, depending on what your method does. A method that adds two integers may accept (int x, int y as its parameters.
This method simply takes the color that is passed to it, and assigns that to the color of the car (updates the color, as the method is called).
From the driver class, you must instantiate objects from the class.
So,
Car myCar = new Car()
Once it is instantiated, you can call the methods that belong to it.
myCar.updateColor(red);
The color between the brackets here is the actual parameter. This assumes that red is a predefined variable for a color, otherwise you can call new Color() and define your own.
I have 2 classes right now, the first class has the arraylist in it. But on the second class when I try to access the arraylist it keeps giving me the red line underneath saying that the variable doesn't exist.
Here is class one...
public class BankMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
BankMain main = new BankMain();
menu();
}
public static void cardNumbers(){
ArrayList<Integer> cardNum = new ArrayList<Integer>();
Scanner cards = new Scanner(System.in);
Scanner input = new Scanner(System.in);
Scanner keyboard = new Scanner(System.in);
System.out.println("Please select a 5 digit card number");
cardNum.add(input.nextInt());
System.out.println("Thank you! You're card number is " +cardNum);
System.out.println("Type 'c' to go back to main menu.");
String value = keyboard.next();
if(value.equalsIgnoreCase("c")){
menu();
}
else if (!keyboard.equals('c')){
System.out.println("Invalid Entry!");
}
}
public static void menu(){
System.out.println("What Would you like to do today?");
System.out.println();
System.out.println("Create Account = 1");
System.out.println("Login = 2");
System.out.println("Exit = 3");
query();
}
public static void query(){
Scanner keyboard = new Scanner(System.in);
double input = keyboard.nextInt();
if (input == 2){
BankMainPart2 main2 = new BankMainPart2();
System.out.println("Please enter your 5 digit card number.");
main2.loginCard();
}
else if (input == 1){
cardNumbers();
}
else if (input == 3){
System.out.println("Thank you, have a nice day!");
System.exit(0);
}
}
}
Here is the second class...
public class BankMainPart2 {
public static void loginCard(){
if (cardNum.contains(name)) {
}
}
}
I know I haven't entered anything in the if statement yet on the second class but I'm just trying to get my array list to work on both classes.
The code looks very naive. A very simple answer to your question is
You have not declared any cardNum in BankMainPart2 as global variable or in loginCard as local variable, how do you think it will be available in the loginCard method?
ArrayList<Integer> cardNum = new ArrayList<Integer>();
is local to cardNumbers method.
How can you access it from other class?
A local variable cannot be accessed from outside the method, so first thing, make cardNum class level variable
Make the variable public if you want other classes to be able to access it directly, else make the variable private and create getter method (setter if required).
You can also send the variable when calling the method as argument
If this is class level variable, make it static and use Classname.variable.
--Edit--
As you have asked for details let me give you a quick overview of the different approaches.
A variable declared inside a method is local. as name suggest "local", no one but the method knows there is such a variable. No other method in the class knows about existence of this variable, let alone some outside class.
I say you can make it static, but static should strictly be used for class level storage, not object level. Say a list which is modified by multiple objects of the same class (I hope you know concepts of objects, else go to the basics otherwise it will not be clear). Now as per your example, I guess this is not what you want.
A public variable is generally no - no, only in few cases it will be useful (for example in android programming where performance is utmost important). Normally we will create a variable and provide getter setters. A getter or setter is used normally when we want to give access to the variable, which again does not look like what you want.
Last, the variable is private to you class, but if you want some method to do something about it, you can pass it as argument, this looks the case for you.
Step by step
take the variable out of method and add to class level, note that I removed static from method names
public class BankMain {
private ArrayList<Integer> cardNum = new ArrayList<Integer>();
// rest of code as it is
..
..
BankMain main = new BankMain();
//change
main.menu();
//no need foe static
public void cardNumbers(){
//no need here now
//ArrayList<Integer> cardNum = new ArrayList<Integer>();
Scanner cards = new Scanner(System.in);
Scanner input = new Scanner(System.in);
..
..
//public static void menu(){
public void menu(){
//send the list
//I see there are confusion at times regarding calling of static method.
//please note objectname.staticMethod() or classname.staticMethod() is one
//and same thing. Just that classname.staticMethod() is more clear
BankMainPart2.loginCard(cardNum);
}
and
public class BankMainPart2 {
public static void loginCard(ArrayList<Integer> cardNum){
if (cardNum.contains(name)) {
}
}
}
Your method, BankMainPart2.loginCard has not context of "cardNum", it doesn't know what it is (type or value).
In order for the method to be able to act on the array list, you must pass a reference to it, something like...
public class BankMainPart2 {
public static void loginCard(ArrayList<Integer> cardNum){
if (cardNum.contains(name)) {
}
}
}
make the cardnum arraylist as an instance variable in BankMain class and extend BankMain in BankMainClass2 and using reference of BankMain you would be able to access cardNum like this
Class BankMain {
public ArrayList<String> cardNum = new ArrayList<String>();
}
Class BankMain2 extends BankMain {
public void method() {
BankMain2 main = new BankMain2();
sysout(main.cardNum.size());
}
}
but the above scenario would only work when cardNum ArrayList in BankMain class is either marked public,protected or default(Nomodifier). it wouldnt work if its marked as private and other non access modifier such as static and final
You can try any one of these
1.Declare the Arraylist as public then import the first class and use the cardNum in the second class
2.Make the cardNum a static var and use it directly in second class as BankMain.cardNum
3.Pass the Arraylist as argument to the second class.
The key problem is in the the way you are trying to create your classes. Your current problem can be solved by answer given by #MadProgrammer. But you should definitly have a look into the Object Oriented Programming Concepts. This section on How to identify and design a Class? should give you some clear pointers.