I have three static methods each in their own public classes. Simple arithmetic methods to help me learn.
The methods use three variables that when defined as static int variables in the main method. The program works.
Now according to my understanding of what I have read, I should be able to move the variable definition to another class and define them as public. The main method in its own public class should then be able to find these definitions and run. But this does not happen. Instead my eclipse workspace reports that the definitions cannot be resolved to a variable.
Here is the very simple code (which gives me the compilation error):
package christmas;
public class addintegers {
public int number1 = 5;
public int number2 = 10;
public int answer;
public static int add2numbers(int a, int b) {
return (a + b);
}
}
class 2
package christmas;
public class subtractintegers {
public static int sub2numbers(int a, int b) {
return (a - b);
}
}
Then I have my main method. This is where I am getting the compilation error.
package christmas;
public class glue {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(addintegers.add2numbers(number1, number2));
System.out.println(subtractintegers.sub2numbers(number1, number2));
answer = (addintegers.add2numbers(number1, number2)) + (subtractintegers.sub2numbers(number1, number2));
System.out.println("answer =" + answer);
}
}
the errors I get are:
>create local variable number1
>create local variable number2
>create local variable answer
First off:
Class names should be nouns, and use UpperCamelCase
Method names should be verbs, and use lowerCamelCase
E.g., something along the lines of:
public class Addition {
public static int add(int a, int b) {
return a + b;
}
}
public class Subtraction {
public static int subtract(int a, int b) {
return a - b;
}
}
If you want to have number1, number2, and answer fields in the class that I renamed Addition, normally what you would do is make them private instance variables and expose them through getters:
public class Addition {
private int number1 = 5;
public int getNumber1() {
return number1;
}
}
You can then access them by creating an instance of the class, e.g.: new Addition().getNumber1();. Since the Addition and Subtraction classes seem to be utility classes however, perhaps it makes more sense to declare these fields private static so you won't have to instantiate the classes:
public class Addition {
private static int number1 = 5;
public static int getNumber1() {
return number1;
}
}
You can then access them by referencing the class as opposed to an instance of the class, e.g.: Addition.getNumber1();.
You are almost there. You are missing 2 key points:
To share the variables number1, number2 and answer without instantiating the addIntegers class, you need to make them static.
To access the variables number1, number2 and answer from within the glue class' main method, you need to prefix the variables with the addIntegers class.
package christmas;
public class addintegers {
public static int number1 = 5;
public static int number2 = 10;
public static int answer;
public static int add2numbers(int a, int b) {
return (a+b);
}
}
package christmas;
public class glue {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(addintegers.add2numbers(addintegers.number1,addintegers.number2));
System.out.println(subtractintegers.sub2numbers(addintegers.number1,addintegers.number2));
addintegers.answer = (addintegers.add2numbers(addintegers.number1,addintegers.number2))+(subtractintegers.sub2numbers(addintegers.number1,addintegers.number2));
System.out.println("answer =" +addintegers.answer );
}
}
package com.rohov;
public class Application {
public static void main(String[] args) {
System.out.println(AddInteger.sum(AddInteger.num1, AddInteger.num2));
System.out.println(SubInteger.sub(AddInteger.num1, AddInteger.num2));
AddInteger.sum = AddInteger.sum(AddInteger.num1, AddInteger.num2) + SubInteger.sub(AddInteger.num1, AddInteger.num2);
System.out.println(AddInteger.sum);
}
}
class AddInteger {
public static int num1 = 5;
public static int num2 = 10;
public static int sum;
public static int sum(int a, int b) {
return a + b;
}
}
class SubInteger {
public static int sub(int a, int b) {
return a - b;
}
}
Related
How is the following program correct?
abstract class Calculate
{
abstract int multiply(int a, int b);
}
public class Main
{
public static void main(String[] args)
{
int result = new Calculate()
{
#Override
int multiply(int a, int b)
{
return a*b;
}
}.multiply(12,32);
System.out.println("result = "+result);
}
}
We are changing the scope of the overridden method here.It is not public anymore and it should of default scope.Is the scope change of overridden method allowed?
You are creating an anonymous subclass in your current code, but you are very close to having a functional interface. Let's change it to that, like
#FunctionalInterface
interface Calculate {
int multiply(int a, int b);
}
Now you have a single abstract method and can use fancy lambdas. Like,
public static void main(String[] args) {
Calculate calc = (a, b) -> a * b;
int result = calc.multiply(12, 32);
System.out.println("result = " + result);
}
Note this is exactly like your original example, just syntactic sugar added with Java 8.
From your code, it multiply is not public to begin with. If you change your mulyiply method your Calculate class to
public abstract int multiply(int a, int b);
then it will not work.
According to your code, the calculate method is not in public scope, so you are not changing the scope.
abstract class Calculate {
public abstract int multiply(int a, int b);
}
public class MyClass {
public static void main(String[] args) {
int result = new Calculate() {
#Override
public int multiply(int a, int b) {
return a * b;
}
}.multiply(11,11);
System.out.println("result = " + result);
}
}
The access level cannot be more restrictive than the overridden method's access level. For example: If the super class method is declared public then the overriding method in the subclass cannot be either private or protected.
Now there is a separate scope as default scope introduced in java , so you can call it as package private scope.
For rules of overriding in java you can follow the Link
I am not clear about the procedure of extending a class. Given the following piece of code, why the output is 32?
class Rts {
public static void main(String[] args) {
System.out.println(zorg(new RtsC()));
}
static int zorg(RtsA x) {
return x.f()*10 + x.a;
}
}
abstract class RtsA {
int a = 2;
int f() { return a; }
}
class RtsB extends RtsA {
int a = 3;
int f() { return a; }
}
class RtsC extends RtsB {
int a = 4;
}
First off, fields aren't overridden, so all this is equivalent to
public class Rts {
public static void main(String[] args) {
System.out.println(zorg(new RtsC()));
}
static int zorg(RtsA x) {
return x.f()*10 + x.a;
}
}
abstract class RtsA {
int a = 2;
int f() { return a; }
}
class RtsB extends RtsA {
int b = 3;
int f() { return b; }
}
class RtsC extends RtsB {
int c = 4;
}
The implementation of f() for an object of type RtsC comes from RtsB, since that is the lowest-level class that overrides f(), so its implementation is used, and that returns b, which is 3. That's multiplied by 10, and then added to the a from RtsA, since zorg only knows that x is of type RtsA, so that field is used. That's 3 * 10 + 2 = 32.
(Note that the fact that RtsA is abstract didn't come into this at all; that mostly only matters when you have abstract methods to worry about.)
Can I multiply a static and a non static variables, like this:
public class C {
protected int c;
private static int s;
public int ma() { return this.c*this.s; }
}
Or:
public class B{
protected int x;
private static int y;
public static int ms() { return x + y; }
}
The second code is not working and I am wondering is it because it's expecting static?
The second block of code is not working because ms is static. You cannot reference non-static members (x) from a static context.
You need to either make ms a non-static function or make x a static variable.
Like this:
public class B{
protected static int x; // now static
private static int y;
public static int ms() { return x + y; }
}
Or like this:
public class B{
protected int x;
private static int y;
public int ms() { return x + y; } // now non-static
}
A static variable/function is one that is shared across the application. In your second example
public class B{
protected int x;
private static int y;
public static int ms() { return x + y; }
}
Your method is declared static and is therefore a static context. Rule of thumb: You can't access non-static things from a static context. Here is some reasoning as to why that is.
Say you have two objects of type B one where x=1 and one where x=2. Since y is static it is shared by both objects. Let y=0.
Suppose from somewhere else in your program you call B.ms(). You're not referring to any particular B object. Therefore the JVM is unable to add x + y because it doesn't know what value of x to use. Make sense?
I have two classes that extend the same abstract class. They both need the same constant, but with different values. How can I do this? Some example code to show what I want to do.
abstract class A {
public static int CONST;
}
public class B extends A {
public static int CONST = 1;
}
public class C extends A {
public static int CONST = 2;
}
public static void main(String[] args){
A a = new B();
System.out.println(a.CONST); // should print 1
}
The above code does not compile because CONST is not initialized int class A. How can I make it work? The value of CONST should be 1 for all instances of B, and 2 for all instances of C, and 1 or 2 for all instances of A. Is there any way to use statics for this?
You can't do that.
You can do this, however:
abstract class A {
public abstract int getConst();
}
public class B extends A {
#Override
public int getConst() { return 1; }
}
public class C extends A {
#Override
public int getConst() { return 2; }
}
public static void main(String[] args){
A a = new B();
System.out.println(a.getConst());
}
If a constant has a variable value, it's not a constant anymore. Static fields and methods are not polymorphic. You need to use a public method to do what you want.
Ex
class A () {
class A(int a, int b) {
}
}
class B extends A {
int m;
int n;
class B()
{
getInput(); // i wanna invoke this method first before calling super(). But it does not allow in Java. How to work around this ?
super(m,n);
}
public void getInput() {
Scanner scanner = new Scanner(System.in);
m = scanner.nextInt();
n = scanner.nextInt();
}
public static void main () {
B b = new B();
}
}
You can force your super class to run a method at the beginning of its constructor and then override that method in the subclass. Many frameworks have a "setup" type method that you can override to accomplish such things.
public class A {
protected int a; // 'protected' so subclass can see it
protected int b;
public A() {
setup(); // Runs whatever setup method is implemented, even in subclasses
}
protected void setup() { /* nothing */ } // 'protected' to be overridden by subclass
}
public class B extends A {
public B()
{
super();
}
/**
* When A's constructor calls setup(), this method will run.
*/
#Override
protected void setup() {
Scanner scanner = new Scanner(System.in);
a = scanner.nextInt(); // Stores value in A's protected variable.
b = scanner.nextInt();
}
}
Depending on the specifics of the classes you're writing, this is where you might have multiple constructors, public or protected methods for setting values, etc. This is where Java is fairly flexible. As the comments below indicate, this isn't a very good practice in constructors, but I'd need more context to figure out how to accomplish what you're asking.
You could chain multiple constructors together as jbrookover alluded to in such a manner. Sligtly convoluted though:
class A () {
public A(int a, int b) {
}
}
class B extends A {
int m;
int n;
public B()
{
this(new Scanner(System.in));
}
private B(Scanner scanner) {
this(scanner.nextInt(),scanner.nextInt())
}
private B(int m, int n) {
super(m,n)
this.m = m;
this.n = n;
}
public static void main (String ... args) {
B b = new B();
}
}