It seems to me constructors can share the same code, for example in:
public class Foo {
private int foo;
{foo = 5;}
public Foo(){}
public Foo(int v){this.foo = v;}
public int getFoo(){return foo;}
}
The code "foo=5;" is called for both constructors.
It seems to me you can not, but I want to make sure. It not possible to create such common code that use parameters ?
eg, something like:
public class Foo {
private int foo;
(int m){foo = m*5;}
public Foo(int m){}
public Foo(int v,int m){this.foo = v;}
public int getFoo(){return foo;}
}
To my understanding, the only way is to create a private void init(int m) to be called by all constructors ?
ps: I call {foo = 5;} "common code", but I guess this feature has another official name ?
EDITS (1):
The term I was looking for is initializer block
This question is not the same as asking if a constructor can also call another
constructor. Because when using an initializer block, the code is called AUTOMATICALLY, ie. without risk to call a constructor and forget to call it
My comment about using "void init" was not good, indeed in this case calling another constructor is better.
In short, my question: can an initializer block takes parameters ? Which would be kind of the same as forcing some parameters on all constructors to be implemented.
EDITS (2):
I now wonder if the only way to achieve what I am asking is to use inheritance to force the use of a specific constructor.
You can call your constructors from other constructors by calling this(), and matching the parameter list.
Say i have:
Foo(int a, int b) {
// some code..
}
but i want to also call:
Foo(int a, int b, int c) {
// some other code
}
I would say this:
Foo(int a, int b) {
this(a, b, 0);
// Whatever other code you want in this constructor.
}
You need to understand the way how Java creates objects!Assume the you have
class A{
private String b = "b";
private static String a = "a";
{
b = "b2";
}
static{
a = "a2";
}
public A()
{
b = "b3";
}
}
So the idea is that when you create an object
new A();
The first
private static String a = "a";
After
static{
a = "a2";
}
After
private String b = "b";
After
{
b = "b2";
}
And only after
public A()
{
b = "b3";
}
But be careful the priorities of static variables and static blocks are the same. And the priorities of normal variables and blocks are again the same. So if you put the next code
static{
a = "a2";
}
and after
private static String a = "a";
you will have that the code in the block is ignored, because you use the variable before declaration! And the same for normal variables!
Related
In the code below I have a classic Java pass-by-value issue (written in processing; setup() == main).
void setup()
{
A a = new A();
a.makeTheB(a.b);
System.out.println(a.b); //Returns null
}
class A
{
B b;
public void makeTheB(B tempB)
{
tempB = new B();
}
}
class B
{
float x; //not used
}
Anyone have any clever tricks they use to assign a new object to a reference passed as a parameter?
I can describe my intent if needed, but I would love a generalized answer if one exists.
EDIT: Looks like I need to describe my intent.
I'm using the Composite pattern to create a recursive hierarchy of objects. I have an object outside that hierarchy that I would like to reference one of the objects within the hierarchy. I would like to pass that object though the composite, Chain of Responsibility style, and then have that object reference whichever object took responsibility for it.
I can find a way to achieve this though return values I'm sure, but being able to assign the parameter I passed down the hierarchy would sure be nice if there's any cleaver way to do it.
You can try returning the object of B that you create in class A4
Illustrated below.
public class A {
B b;
public B makeTheB(B tempB) {
tempB = new B();
return tempB;
}
}
public class B {
float x; //not used
}
public class Test {
public static void main(String[] args) {
A a = new A();
B b = a.makeTheB(a.b);
System.out.println(b); //Returns nu
}
}
Output: B#7852e922
You can do this, but perhaps you need to provide a better description of what you want to achieve.
void setup()
{
A a = new A();
a.makeTheB(a);
System.out.println(a.b);
}
class A implements Consumer<B>
{
B b;
public void accept(B b) {
this.b = b;
}
/**
* Create a B, and give it to a Consumer which knows where it needs to be stored.
*/
public void makeTheB(Consumer<B> consumer)
{
consumer.accept(new B());
}
}
class B
{
float x; //not used
}
I've seen this question asked in several ways, but the code is usually specific to the user, and I get lost a little. If I'm missing a nice clear and simple explanation, I'm sorry! I just need to understand this concept, and I've gotten lost on the repeats that I've seen. So I've simplified my own problem as much as I possibly can, to get at the root of the issue.
The goal is to have a main class that I ask for variables, and then have those user-inputted variables assessed by a method in a separate class, with a message returned depending on what the variables are.
import java.io.*;
public class MainClass {
public static void main(String[] args) {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
String A;
String B;
try {
System.out.println("Is A present?");
A = reader.readLine();
System.out.println("Is B present?");
B = reader.readLine();
Assess test = new Assess();
} catch (IOException e){
System.out.println("Error reading from user");
}
}
}
And the method I'm trying to use is:
public class Assess extends MainClass {
public static void main(String[] args) {
String A = MainClass.A;
String B = MainClass.B;
if ((A.compareToIgnoreCase("yes")==0) &&
((B.compareToIgnoreCase("yes")==0) | (B.compareToIgnoreCase("maybe")==0)))
{
System.out.println("Success!");
}
else {
System.out.println ("Failure");
}
}
}
I recognize that I'm not properly asking for the output, but I can't even get there and figure out what the heck I'm doing there until I get the thing to compile at all, and I can't do THAT until I figure out how to properly pass values between classes. I know there's fancy ways of doing it, such as with arrays. I'm looking for the conceptually simplest way of sending a variable inputted from inside one class to another class; I need to understand the basic concept here, and I know this is super elementary but I'm just being dumb, and reading what might be duplicate questions hasn't helped.
I know how to do it if the variable is static and declared globally at the beginning, but not how to send it from within the subclass (I know it's impossible to send directly from the subclass...right? I have to set it somehow, and then pull that set value into the other class).
In order to pass variables to an object you have either two options
Constructor - will pass parameter when creating the object
Mutator method - will pass parameters when you call the method
For example in your Main class:
Assess assess = new Assess(A, B);
Or:
Assess assess = new Assess();
assess.setA(A);
assess.setB(B);
In your Assess class you have to add a constructor method
public Assess(String A, String B)
Or setter methods
public void setA(String A)
public void setB(String B)
Also, Assess class should not extend the main class and contain a static main method, it has nothing to do with the main class.
Below there is a code example!
Assess.java
public class Assess {
private a;
private b;
public Assess(String a, String b) {
this.a = a;
this.b = b;
}
public boolean check() {
if ((A.compareToIgnoreCase("yes")==0) &&
((B.compareToIgnoreCase("yes")==0) ||
(B.compareToIgnoreCase("maybe")==0)))
{
System.out.println("Success!");
return true;
} else {
System.out.println ("Failure");
return false;
}
MainClass .java
public class MainClass {
public static void main(String[] args) {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
String A;
String B;
try {
System.out.println("Is A present?");
A = reader.readLine();
System.out.println("Is B present?");
B = reader.readLine();
Assess test = new Assess(A, B);
boolean isBothPresent = test.check();
// ................
} catch (IOException e){
System.out.println("Error reading from user");
}
}
I think what you're looking for are method parameters.
In a method definition, you define the method name and the parameters it takes. If you have a method assess that takes a string and returns an integer, for example, you would write:
public int assess(String valueToAssess)
and follow it with code to do whatever you wanted with valueToAssess to determine what integer you wanted to return. When you had decided that i was the int to return, you would put the statement
return i;
into the method; that terminates the method and returns that value to the caller.
The caller obtains the string to be assesed, then calls the method and passes in that string. So it's more of a push than a pull, if you see what I mean.
...
String a = reader.readLine();
int answer = assess(a);
System.out.println("I've decided the answer is " + answer);
Is that what you're looking for?
A subclass will have access to the public members of the superclass. If you want to access a member using {class}.{member} (i.e. MainClass.A) it needs to be statically declared outside of a method.
public class MainClass {
public static String A;
public static String B;
...
}
public class Subclass {
public static void main(String[] args) {
// You can access MainClass.A and MainClass.B here
}
}
Likely a better option is to create a class that has these two Strings as objects that can be manipulated then passed in to the Assess class
public class MainClass {
public String A;
public String B;
public static void main(String[] args) {
// Manipulate A, B, assign values, etc.
Assess assessObject = new Assess(A, B);
if (assessObject.isValidInput()) {
System.out.println("Success!");
} else {
System.out.println("Success!");
}
}
}
public class Assess {
String response1;
String response2;
public Assess (String A, String B) {
response1 = A;
response2 = B;
}
public boolean isValidInput() {
// Put your success/fail logic here
return (response1.compareToIgnoreCase("yes") == 0);
}
}
First you don't need inheritance. Have one class your main class contain main take the main out of Assess class. Create a constructor or setter methods to set the variables in the Assess class.
For instance.
public class MainClass
{
public static void main(String[] Args)
{
Assess ns = new Assess( );
ns.setterMethod(variable to set);
}
}
I'm not 100% sure of your problem, but it sounds like you just need to access variables that exist in one class from a subclass. There are several ways...
You can make them public static variables and reference them as you show in your Assess class. However, they are in the wrong location in MainClass use
public static String A, B;
You can make those variables either public or protected in the parent class (MainClass in your example). Public is NOT recommended as you would not know who or what modified them. You would reference these from the sub-class as if present in the sub-class.
public String A, B; // Bad practice, who modified these?
protected String A, B;
The method that might elicit the least debate is to make them private members and use "accessors" (getters and setters). This makes them accessible programmatically which lets you set breakpoints to catch the culprit that is modifying them, and also let you implement many patterns, such as observer, etc., so that modification of these can invoke services as needed. If "A" were the path to a log file, changing its value could also cause the old log to close and the new one to be opened - just by changing the name of the file.
private String A, B;
public setA(String newValue) {
A = newValue;
}
public String getA() {
return A;
}
BUT ...
Your question says "send to the subclass", but confounded by your knowing how to do this using global variables. I would say that the simplest way is to provide the values with the constructor, effectively injecting the values.
There are other ways, however, your example shows the assessment performed by the constructor. If your Assess class had a separate method to perform the assessment, you would just call that with the variables as arguments.
Your example is confusing since both classes have main methods and the child class does the assessing - I would think you would want the opposite - Have MainClass extend Assess, making "MainClass an Assess'or", let main assign the Strings to Assess' values (or pass them as arguments) to the parent class' "assess" method ("super" added for clarity):
super.setA(local_a);
super.setB(local_b);
super.assess();
or
super.assess(A, B);
For my programming class in first year engineering I have to make a D-game in Java, with only very little knowledge of Java.
In one class I am generating a random integer via
public int rbug = (int)(Math.random() * 18);
every so many ticks. I have to use this integer in another class (in the requirements for an if-loop), and apparently it needs to be static. But when I change the variable to public int static, the value doesn't change any more.
Is there an easy way to solve this problem?
Edit: part of code added:
public int rbug = (int)(Math.random() * 18);
which is used in
public void render(Graphics g){
g.drawImage(bugs.get(rbug), (int)x, (int)y, null);
And in another class:
if(Physics.Collision(this, game.eb, i, BadBug.rbug)){
}
As error for BadBug.rbug I get the message
Cannot make a static reference to a non-static field
Using static to make things easier to access is not a very good ideal for design. You would want to make variables have a "getter" to access them from another class' instance, and possibly even a "setter". An example of this:
public class Test {
String sample = 1337;
public Test(int value) {
this.sample = value;
}
public Test(){}
public int getSample() {
return this.sample;
}
public void setSample(int setter) {
this.sample = setter;
}
}
An example of how these are used:
Test example = new Test();
System.out.println(example.getSample()); // Prints: 1337
example = new Test(-1);
System.out.println(example.getSample()); // Prints: -1
example.setSample(12345);
System.out.println(example.getSample()); // Prints: 12345
Now you might be thinking "How do I get a string from the class that made the instance variable within the class?". That's simple as well, when you construct a class, you can pass a value of the class instance itself to the constructor of the class:
public class Project {
private TestTwo example;
public void onEnable() {
this.example = new TestTwo(this);
this.example.printFromProject();
}
public int getSample() {
return 1337;
}
}
public class TestTwo {
private final Project project;
public TestTwo(Project project) {
this.project = project;
}
public void printFromProject() {
System.out.println(this.project.getSample());
}
}
This allows you to keep single instances of classes by passing around your main class instance.
To answer the question about the "static accessor", that can also be done like this:
public class Test {
public static int someGlobal = /* default value */;
}
Which allows setting and getting values through Test.someGlobal. Note however that I would still say that this is a horrible practice.
Do you want to get a new number every time that you want BadBug.rbug? Then convert it from a variable to a method.
My main java code is like that:
package Javathesis;
//import... etc
//...
public class Javathesis; // My main class
{
public static void // There are a lot of these classes here
//...
//...
class x
{
String a;
String b;
x(String a, String b)
{
this.a = a;
this.b = b;
}
}
public void getAllDataDB1
{
ArrayList<ArrayList<x>> cells = new ArrayList<>();
while(resTablesData1.next())
{
ArrayList<CellValue> row = new ArrayList<>();
for (int k=0; k<colCount ; k++) {
String colName = rsmd.getColumnName(i);
Object o = resTablesData1.getObject(colName);
row.add(new x(rsmd.getColumnType(),o.toString());
}
cells.add(row);
}
public static void main(String[] args)
{
connectToDB1();
// i want to call an instance of class "x" HERE!!!
}
}
How can i call class x in public static void main? Am i doing something wrong? I already test the way i know
Class class = new Class();
class.x(String a, String b);
but i receive errors. Can somebody help me to fix this?
Thanks in advance.
Since x is an inner class it need an outer class instance to obtain a reference:
Class x = new Javathesis().new x(a, b);
In addition the semi-colon needs to be removed from the class declaration
Methods in x can be invoked using the reference created
Java Naming conventions show that classes start with an uppercase letter. Also its good to give the class a more meaningful name than a single letter name
There are multiple problems with this code:
Class class = new Class();
class.x(String a, String b);
You cannot name a variable 'class', it is a reserved word. Also, x is a class - you cannot just call it, you need to instantiate it.
Also, why would you instantiate a Class - which is a class encapsulating knowledge about Java class?
Something like that might work:
Javathesis thesis = new Javathesis();
Javathesis.x thesis_x = new thesis.x("a","b);
Also, please, start class names with the capital letter - it is a convention in Java.
You should create an instance of your inner class
YourInnerClass inner = new YourOuterClass().new YourInnerClass();
and then call a method on it
inner.doMyStuff();
To call a class method without instantiating an object from that class, the method must be declared as static, and then invoked from wherever you want using the class name dot method parentheses arguments.
public class x {
//constructor, etc
public static int add(int x,y) {
return x+y;
}
}
//make the call from somewhere else
int y = x.add(4,5);
When using C++ one is not allowed to access a private attribute inside a main function. Example:
#include <iostream>
using namespace std;
class Test {
private: int a;
public:
Test(int value) { a = value; }
int getValue() { return a; }
};
int main (int argc, char *argv[]) {
Test test2(4);
cout << test2.a; // Compile error! Test::a is private within this context
cout << test2.getValue(); // OK!
return 0;
}
It is clear why there is an error when accessing private attributes outside class methods, since C++ do not have main functions inside classes.
However, in Java it is allowed:
public class Test {
private int a;
public Test(int value) { a = value; }
public int getValue() { return a; }
public static void main (String args[]) {
Test test1 = new Test(4);
System.out.println(test1.a);
}
}
I understand in this case main is INSIDE the Test class. However, I cannot understand the idea WHY is this allowed, and what is the impact of this in the development/management of the code.
When learning C++, I once heard "Classes shouldn't have a main. Main acts with or uses instances of classes".
Can someone shed some light on this question?
You are looking at this from the wrong point of view. The question is not why main can acces the class internals. There is not one 'main' in Java. The important difference to this respect is that for C++ there is a single entry point into the application that is main, while in Java a single application can have multiple entry points, as many as one per class. The entry point must be a static method (member function in C++ jargon) of a class with a particular signature, and the behavior is exactly the same as for other static methods of the same class.
The reason that Java can have multiple entry points is that you tell the VM on startup where (what class) you want to start your application in. That is a feature that is not available in C++ (and many other languages)
You can actually do the same in C++:
class Test {
private: int a;
public:
Test(int value) { a = value; }
int getValue() { return a; }
static void Main()
{
Test t(10);
cout << t.a;
}
};
It's as simple as that: in both languages, private variables are accessible only from inside the class.
However, I cannot understand the idea WHY is this allowed.
It's just a language feature. If you weren't able to access privates from inside the class, what could you do with them?
Also, not that access-levels are class-wide, not instance-wide. That might be throwing you off. That means you can access a different instance's privates from an instance of the same class. Also, in C++, there's the friend keyword that gives you the same privileges.
Your intuition is correct. The second code is valid in Java because main is inside the Test class. To make it equivalent to the C++ code try to access the private member of a different class, which will fail to compile:
class Test2 {
private int a;
public Test(int value) { a = value; }
public int getValue() { return a; }
}
public class Test {
public static void main (String args[]) {
Test2 test2 = new Test2(4);
System.out.println(test2.a); // does not compile
}
}
The actual underlying difference is the fact that in C++ functions can exist outside classes, while in Java any method needs to be part of a class.
private in Java could be considered "file local" c.f. package local. For example you can access private members of a class defined in the same outer class.
AFAIK, The assumption is you don't need to protect yourself from code in the same file.
public interface MyApp {
class Runner {
public static void main(String... args) {
// access a private member of another class
// in the same file, but not nested.
SomeEnum.VALUE1.value = "Hello World";
System.out.println(SomeEnum.VALUE1);
}
}
enum SomeEnum {
VALUE1("value1"),
VALUE2("value2"),
VALUE3("value3");
private String value;
SomeEnum(final String value) {
this.value = value;
}
public String toString() {
return value;
}
}
}
http://vanillajava.blogspot.com/#!/2012/02/outer-class-local-access.html
This reason is: Java is a fully Object Oriented Programming model, so in it any things must defined in class or smallest unit in java is class.