How to modify superclass variable from subclass? - java

In C++ I could use 1 class throughout multiple files and when I modify a value using a function from one file, it would change that value globally.
In Java every file has to have it's own class; when I change a value using a method from one file, it does not change this value globally.
For example in C++ the files might look like this:
someClass.h
class someClass{
private:
int x;
public:
//Constructor
someClass(){
x = 5;
}
void changeVariable(); //Declaring function for later
}
main.cpp
int main(){
someClass cClass;
cClass.changeVariable(); //Call function
cout << x; //outputs 6
}
fileA.cpp
void someClass::changeVariable(){
x = 6; //x is changed to 6 globally.
}
In Java:
someClass.java
public class someClass {
int x;
//Constructor
public someClass() {
x = 5;
}
main.java
public class main {
public static void main() {
someClass cClass = new someClass();
subClass cSub = new subClass();
cSub.changeVariable();
System.out.print(x); //outputs 5
}
}
fileA.java
public class fileA extends someClass {
void changeVariable() {
x = 6; //x is changed to 6 only for fileA
}
}
My question is how can I change a variable from the sub class so that the variable is changed globally (For Java). Sorry if the question is still confusing.

Try with this:
public class someClass {
static int x;
//Constructor
public someClass() {
x = 5;
}
That a variable where static means that its value is common for all objects of the same class. That only one variable x is created for all, not one for each object.
Read that answer if you want a good explication of what static means:
What does the 'static' keyword do in a class?

Expose a function. setXyz in parent
public class someClass {
int x;
//Constructor
public someClass() {
x = 5;
}
public void setX(int n){
this.x = n;
}
}
public class fileA extends someClass {
void changeVariable() {
setX(6);
}

No need for static variable, this is the most equivalent thing you can do in Java:
public abstract class SomeClass {
protected int x = 5;
public abstract void changeVariable();
}
public class FileA extends SomeClass {
#Override
public void changeVariable() {
x = 6;
}
}
SomeClass doesn't have to be abstract of course, but you would have to implement it's changeVariable method.
Also x cannot be private, it has to be protected, so that it can be accessed by subclasses.

Related

Java inheritance fields [duplicate]

This question already has answers here:
Is there a way to override class variables in Java?
(17 answers)
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I am not able to understand the following output.
I don't know why the output is 10, I think the line A a = new B() creates a new instance of class B, I think the result should be 20
class A {
int i = 10;
}
class B extends A {
int i = 20;
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
}
}
Why this works like this .. please explain.
First, see Hiding Fields (emphasis added)
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different
In other words, this isn't "inheritance" since you're actually hiding A's i behind B's i, and you are using a reference object of A, so you are getting its fields. If you did B b = new B(), you would see 20, as expected.
If you expect true overrides, try using methods.
class A {
public int get() {
return 10;
}
}
class B extends A {
#Override
public int get() {
return 20;
}
}
See
A a = new B();
System.out.print(a.get()); // 20
If you really want to see both at once, see this example.
class A {
int i = 10;
}
class B extends A {
int i = 20;
#Override
public String toString() {
return String.format("super: %d; this: %d", super.i, this.i);
}
}
And
A a = new B();
System.out.print(a); // super: 10; this: 20
In java you cannot override an instance variable. The output you are getting is expected. In Java you can only override instance methods and not instance variables.
If you want 20 as an output you may use getter methods over those instance variables.
class A {
int i = 10;
int getI() {
return i;
}
}
class B extends A {
int i = 20;
int getI() {
return i;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getI());
}
}
Polymorphism is not applicable for fields in Java.Evaluating Variables decision is taken at compile time so always base class variables are accessed.
Because you define 2 variables: one in the subclass B, and one with the same name in superclass A.
A a = new B();
a.i; // refers to A.i
If you cast the A to a B, it will access B.i:
System.out.println(((B)a).i);
I think you need to use 1 variable:
class A {
int i;
public A() {
i = 10;
}
}
class B extends A {
public B() {
i = 20;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i); // will print 20
}
Member variable i is already defined in class A.
In order to achieve what you are looking for, change the class B as shown below:
class B extends A {
public B() {
i = 20;
}
}

"error: cannot find symbol " when calling a Method defined using Generics

After reading through the Generics info I am attempting a simple sample and encountering the following error.
MyClass.java:32: error: cannot find symbol
System.out.println("X = " + temp.x);
^
symbol: variable x
location: variable temp of type T
where T is a type-variable:
T extends Object declared in method tryThis(T)
1 error
Without the reference to "temp.x" it compiles which leads me to believe the definition is correct but possibly the way the variable is referenced is the issue. Or it could be the actual implementation is wrong. Not sure.
The main class has a method which can be called by either of the 2 inner classes. When called, the method attempts to access the variable specific to the inner class that called it.
public class MyClass {
public class InnerClass1 {
int x = 100;
public void runThis() {
tryThis(this);
return;
}
}
public class InnerClass2 {
int x = 200;
public void runThis() {
tryThis(this);
return;
}
}
public static void main(String[] args) {
MyClass x = new MyClass();
}
private <T> void tryThis(T temp) {
System.out.println("X = " + temp.x);
}
}
symbol: variable x
location: variable temp of type T
where T is a type-variable:
T extends Object declared in method tryThis(T)
^^^^^^^^^^^^^^^^
Without further specification, e.g. <T extends InnerClass1>, the only thing that is known about T within that method is that it extends Object, and for Object, the attribute x is not defined.
Maybe you should define a common super-class for those two classes, and declare x in that super-class.
In order to get the value x from each class dynamically, you can define a common interface or abstract class for InnerClass1 and InnerClass2 to implement or extend. This allows the inheritance of methods and variables. Seeing that both holds a value of type T, let us create an interface called ValueHolder<T>:
interface ValueHolder<T> {
public T getValue();
}
Both the InnerClass1 and InnerClass2 will need to implement this interface:
public class InnerClass1 implements ValueHolder<Integer> {
private int x = 100;
#Override
public Integer getValue() {
return this.x;
}
}
public class InnerClass2 implements ValueHolder<String> {
public String x = "200";
#Override
public String getValue() {
return this.x;
}
}
As you can see, InnerClass1 implements ValueHolder<Integer>, meaning the inherited getValue methods return type will be Integer. The same goes for InnerClass2, which implements ValueHolder<String>.
Change your tryThis as follows:
private <T> void tryThis(ValueHolder<T> temp) {
System.out.println("Value = " + temp.getValue());
}
Now each value can be printed like this:
Generics g = new Generics();
g.tryThis(new InnerClass1());
g.tryThis(new InnerClass2());
Output:
X = 100
X = 200
T in
private <T> void tryThis(T temp)</code>
is just a placeholder for any class. The compiler knows nothing more about it, so it knows nothing about the symbol x as well.
To accomplish what you are trying to do, you would need something like this:
public class Generics {
abstract class MyClass {
int x;
}
public class InnerClass1 extends MyClass {
InnerClass1() {
super.x = 100;
}
public void runThis() {
tryThis(this);
return;
}
}
public class InnerClass2 extends MyClass {
InnerClass2() {
super.x = 200;
}
public void runThis() {
tryThis(this);
return;
}
}
public static void main(String[] args) {
Generics x = new Generics();
x.new InnerClass1().runThis();
x.new InnerClass2().runThis();
}
private <T extends MyClass> void tryThis(T temp) {
System.out.println("X = " + temp.x);
}
}
However, you would not need Generics for this specific case:
private void tryThis2(MyClass temp) {
System.out.println("X = " + temp.x);
}
would accomplish the same.
Generics are very complex, although they look easy to use.

How come variables are initialized to their default values even if we have a constructor

i have a question regarding default constructors in java.
as much as i have read about constructors in java, a default constructor initializes all instance variables to their default values. but what if we define a constructor for a class, then how come variables are initialized to their default values if we want them to ?
suppose i have 2 files
a.java
public class a
{
int x;
public a(int z)
{
if(z > 0)
{
x = z;
}
}
public void get()
{
System.out.println(x);
}
}
and b.java
public class b
{
public static void main(String[] args)
{
a obj = new a(-4);
obj.get();
}
}
now here condition (z>0) fails, so x is initialized to zero. but what exactly does this as their is no default constructor in class a.
Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type.
Source
That means that the compiler will do that for you when you build the program.
In your a class (renamed A below to follow conventions) as you have written it, there is no default constructor. A default constructor for a class is a constructor which is public and has no arguments.
With the code you have written, this will fail:
A a = new A();
As soon as you declare another constructor in a class, there is no default constructor anymore.
As to instance variables, if you do not initialize them explicitly, they are set to default values. That is:
public class A
{
private int x;
public int getX()
{
return x;
}
}
if you do:
final A a = new A();
System.out.println(a.getX());
this will print out 0. The class above is exactly equivalent to:
public class A
{
private int x /* = 0 -- default value for uninitialized int instance variables */;
// redundant
public A()
{
}
public int getX()
{
return x;
}
}
When you declare a variable in java, it's by default initialized as it's default value.
For the primitive types is that 0 (or it's equivalent), for Objects is that null
So in your example has x initialy the value 0 and you never overwrite it.
In java if we dont define any constructor, it takes its self a default constructor which will have default values.while we creating object we intialize values to the constructor.
public class Car{
int numOfWheels;
public Car(int numOfWheels){ //created constructor//
this.numOfWheels=numOfwheels;
}
}
public static void main(string[]args){
Car skoda = new Car(4);
} *//initialized value to the object using constructor in parenthesis//*
public class a
{
int x;
public a(int z)
{
//as we know that every class base class is Object class this constructor first statement is super(); means compiler automatically add this statement that call object class default constructor and initialize default values
if(z > 0)
{
x = z;
}
}
public void get()
{
System.out.println(x);
}
}
public class a
{
int x;
public a(int z)
{
/*As we know that every class base class is Object.....
compiler automatically add super(); that call Object class default constructor
that initialize the value of instance variable */
if(z > 0)
{
x = z;
}
}
public void get()
{
System.out.println(x);
}
}
public class b
{
public static void main(String[] args)
{
a obj = new a(-4);
obj.get();
}
}
//other example is below
/*class A
{
public A()
{
System.out.println("Arjun Singh Rawat and Ashish Chinaliya");
}
}
class B extends A
{
public B()
{
//compiler automatically add super();
}
}
class calling
{
public static void main(String arg[])
{
B bb=new B();
}
}*/
thanks...
public class Demo {
static int a;
Demo(int b )
{
System.out.println(" Constructor");
}
public static int func()
{
System.out.println(a);
return 1;
}
public static void main( String args[])
{
new Demo(func());
}
}
Output
0
Constructor
It's not the default constructor that initializes our fields to their default values ,
In this program, the static field a is being initialized to 0 even though there is no default constructor
added by the compiler. Also it's being initialized to 0 before a constructor being called .

'this' prefix in Java?

Does the this prefix for accessing member variables exist in Java?
Here is my HelloWorld code:
public class HelloWorld {
public static int x = 0;
public static void main(String[] args) {
HelloWorld.x = 45;
System.out.println(HelloWorld.x);
}
}
The above code works with/without the class name prefixing the variable x. However, if i try: this.x = 45; or this->x = 45; I receive an error:
non-static variable this cannot be referenced from a static context
I understand member variables can be accessed without the HelloWorld (class name) prefix, like I have done. But, I want to know if the this prefix exists in Java, how do I use it?
EDIT:
Also, could you provide an example where this is appropriate?
duffymo & byte - I greatly appreciate your help. Thanks.
Java has this as a prefix, but it's a reference to the current instance.
Static methods and attributes are associated with a class, not an instance, so you can't use this inside a static method.
public class HelloWorld {
public int x = 0; // note: now it's an instance attribute
public static void main(String[] args) {
HelloWorld hw = new HelloWorld();
System.out.println(hw.x);
}
public int getX() { return this.x; }
public void setX(int x) { this.x = x; }
}
You're attempting to use 'this' to refer to a static, not an instance variable. 'this' is only used to refer to the instance variables of an instantiated object of this class. You cannot use 'this' to refer to static variables on a class.
When you use 'this' you are saying "I want to refer to the variables of this particular instantiation of this class". A static on the other hand is always going to be the same variable for the class, irrespective of instantiation.
In addition the correct syntax for referring to an instance variable is by the dot operator:
this.x = 42; //correct
this->x = 42; //will not compile as its not valid Java
So essentially what you're after is something like the following:
public class Foo {
private int x;
public void setX(int x) {
this.x = x;
}
public int getX() {
return this.x;
}
}
public class HelloWorld {
public static void main(String[] args)
{
Foo foo = new Foo();
foo.setX(45);
System.out.println(foo.getX());
}
}
Remove the static modifier from your variable and then try it with this. Here is the difference:
Static variables exist only once in the whole program. No matter where you are, you could refer to HelloWorld.x and it would always be the same thing. That means, as you've declared it, anyone can modify it too, which may or may not be a good thing.
Member variables (not declared with static) are local to an instance of a class, which means you have to have created an instance with new before you can use it. However, every time you use new to create a new instance of that class, its non-static fields will be different. That is why you have to use this or, if in a different class, a reference to a specific instance in order to access them.
A clarification:
in getter methods it's not necessary to use the keyword this (as it's been shown in other answers). If you're new to Java this will introduce you to variable scopes (local variables vs instance variables). In other words the following works perfectly:
public class Foo {
private int x;
public void setX(int x) {
this.x = x; //Here the keywork this is necessary!
}
public int getX() {
return x; //in this case the 'x' can only be instance variable
}
}
There is also another important use of this for invoking constructors defined in the same class (You might want to check the keyword 'super' as well). Check the following:
public class HelloWorld {
public static void main(String[] args) {
Foo foo1 = new Foo();
Foo foo2 = new Foo(3, 4, 5);
System.out.println("Foo1:\n" + foo1);
System.out.println("Foo2:\n" + foo2);
}
}
class Foo {
private int x, y, z;
public Foo() {
this(-1, -1);
}
public Foo(int x, int y) {
this.x = x;
this.y = y;
}
public Foo(int x, int y, int z) {
this(x, y);
this.z = z;
}
#Override
public String toString() {
return "x= " + x + "\ny= " + y + "\nz= " + z + "\n";
}
}
Enjoy!
You can only use "this" from within an object instance.
"static", by definition, is OUTSIDE of ANY object.
Here's an excellent link in the Java documentation:
http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html
'Hope that helps!
for static variables, use ClassName (like you did). For instance (non-static) variables, use this.variableName
you can use it to access instance variables and methods, you are getting this error because you are using this to access static variables.
and also ... java doesn't have =>, in java you use the .
objectName.variableName = newValue
Use this for getters/setters/constructors.
For example.
class Test {
int x;
int y;
public void Test(int x, int y) {
this.x=x;
this.y=y;
}
public void setX(int x) {
this.x=x;
}
}

Object Oriented Class Communication

I have a Java assessment that gets marked by a robot. Whenever I upload my assignment it shows a screen like this.
A good object-oriented design places each method into the most appropriate
class. The most appropriate class for a method should be the same class as
the data fields that that method needs to access. If you don't place a method
into the right class, then this will most likely increase the amount of
communication that is required between your classes.
The score below measures the amount of communication between your classes. A
lower score is better.
19 method invocations between classes
7 arguments passed between classes
15 results returned between classes
Amount of communication = invocations + 2*inputs + 2*outputs = 63
Now what exactly does "method invocations between classes", "arguments passed between classes" and "results returned between classes" mean?
Method invocations between classes
As your class contains their own methods if you want to call the method from another class you have to use an instance of this class.
For example :
class A{
public void methodA(){
  }
}
class B{
public void methodB(){
}
}
If I want to call methodA() from the class B I must use this:
public void methodB(){
A a = new A();
a.methodA(); // method invocation between classes
}
Argument passed between classes
This time methodA() will need an argument, and B as a field which could be used as argument.
class A{
public void methodA(int argument){
  }
}
class B{
private int fieldB = 42;
public void methodB(){
}
}
To call methodA() from B you will pass an argument from a class to another.
public void methodB(){
A a= new A();
a.methodA(fieldB); //Argument passed between classes
}
Results returned between classes
And now methodA() returns a result this is the code.
class A{
public int methodA(){
return 42;
}
}
class B{
private int fieldB;
public void methodB(){
}
}
To use/handle the returned value of the methodA() from the class B you'll have to do this:
public void methodB(){
A a= new A();
fieldB = a.methodA(); //Result returned between classes
}
I'd have to say:
method invocations between classes
Suppose you have classes X and Y. This would be any time class X calls some method on class Y.
e.g.,
class Y
{
public void foo() { }
}
class X
{
public void someMethod()
{
Y y = new Y();
y.foo();
}
}
arguments passed between classes
Could possibly mean one of two things.
Either you are accessing a field of another class directly.
class Y
{
public int number;
}
class X
{
public void someMethod()
{
Y y = new Y();
int yNum = y.number;
}
}
Or a method was called where arguments are supplied. (most likely case)
class Y
{
public void foo(int arg) { }
}
class X
{
public void someMethod()
{
Y y = new Y();
y.foo(56);
}
}
results returned between classes
Received a value from a method of another class that returned a value. e.g., getters or other methods.
class Y
{
public int foo() { return 42; }
private int number;
public int getNumber() { return number; }
}
class X
{
public void someMethod()
{
Y y = new Y();
int yFoo = y.foo();
int yNumber = y.getNumber();
}
}

Categories