java static binding and polymorphism - java

I am confused with the static binding example below. I reckon that S2.x and S2.y shows static binding as they prints out the fields according to s2's static type. And S2.foo() makes s2call the foo method in the super class, as foo is not over ridden in the subclass.
However with S2.goo(), isn't it supposed to call the goo() method in the Test1 subclass? Like it's polymorphism? How come it's static binding? It looks like S2.goo() calls the Super Class goo()method and prints out =13. Many thanks for your help in advance!
public class SuperClass {
public int x = 10;
static int y = 10;
protected SuperClass() {
x = y++;
}
public int foo() {
return x;
}
public static int goo() {
return y;
}
}
and SubClass
public class Test1 extends SuperClass {
static int x = 15;
static int y = 15;
int x2= 20;
static int y2 = 20;
Test1()
{
x2 = y2++;
}
public int foo2() {
return x2;
}
public static int goo2() {
return y2;
}
public static int goo(){
return y2;
}
public static void main(String[] args) {
SuperClass s1 = new SuperClass();
SuperClass s2 = new Test1();
Test1 t1 = new Test1();
System.out.println("S2.x = " + s2.x);
System.out.println("S2.y = " + s2.y);
System.out.println("S2.foo() = " + s2.foo());
System.out.println("S2.goo() = " + s2.goo());
}
}

In Java static variables and methods are not polymorphic. You can't expect polymorphic behavior with static fields.

Static methods can not be overridden, because they get bind with the class at compile time itself.
However, you can hide the static behavior of a class like this:
public class Animal {
public static void foo() {
System.out.println("Animal");
}
public static void main(String[] args) {
Animal.foo(); // prints Animal
Cat.foo(); // prints Cat
}
}
class Cat extends Animal {
public static void foo() { // hides Animal.foo()
System.out.println("Cat");
}
}
Output:
Animal
Cat
Refer link for method hiding in Java.
Also, take care that static method should not be called on instance as they get bind to Class itself.

Related

Why can one call a static method on a type parameter if Java's generics aren't reified?

What's the point of allowing static method invocation on type parameters if Java couldn't be bothered with type reification?
public class a {
interface Foo {
static int getNum() { return 0; }
}
static class FooT implements Foo {
static int getNum() { return 1; }
}
interface A<T extends Foo> {
default int getFooNum() {
return T.getNum();
}
}
static class B implements A<FooT> {}
public static void main(String[] args) {
A p = new B();
// A rational being would expect this to print 1, but being the great
// language that Java is, earthly rationality doesn't hold.
System.out.println(p.getFooNum());
}
}

How to change static variable inside in a class by a method

I have three classes:
Class One
public class One {
private static Two object;
public static void set_up(Two object) {
int y = object.get();
System.out.println(y);
}
public static void prn () {
System.out.println(object.get());
}
}
Class Two
public class Two {
private int x;
public int get() {
return x;
}
Two(int n){
x = n;
}
}
Class Three
public class Three {
public static void main( String[] argv ) {
One st = new One();
Two two = new Two(2);
st.set_up(two);
st.prn();
}
}
I want to change the static variable object in class Two by method set_up(Two object).
The problem is that static variable inside the class has the same name as the arguments in the method. How can I modify set_up(Two object) so I copy values from given argument to static object?
You can qualify it by using the class' name:
public static void set_up(Two object) {
One.object = object;
}

How to modify superclass variable from subclass?

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.

Java: Using different constructors

This is my first day learning java (on my own), so I need some help.
This is my code:
public class java_main {
public static void main(String[] args) {
MyClass my = new MyClass(3,4);
MyClass your = new MyClass();
}
public class MyClass {
public int a,b;
public Myclass(int i, int j) {
a = i;
b = j;
}
public Myclass() {
a = 1;
b = 2;
}
}
}
I'm getting this error:
No enclosing instance of type java_main is accessible. Must qualify the allocation with an enclosing instance of type java_main (e.g. x.new A() where x is an instance of java_main).
Any suggestions? Thanks in advance!!!
The problem you have is that you have enclosed in java_main class MyClass
public class java_main {
public class MyClass {
}
}
Remove the java_main, to get valid result.
public class MyClass {
public static void main(String[] args) {
MyClass my = new MyClass(3,4);
MyClass your = new MyClass();
}
private final int a,b;
public Myclass() {
this(1,2);
}
public Myclass(int a, int b) {
this.a = a;
this.b = b;
}
}
The ussue you have is casued that you have to create first instance of outer class in way to be create instance of inner.
public static void main(String[] args)
{
java_main outer = new java_main();
Myclass my = outer.new Myclass(3,4);
Myclass your = outer.new Myclass();
}
The key word static apply to parts of code that is not part of object it is only enclosed by its path (a method must be in class).
Try to find a tutorial that will guide you.
You could make MyClass public:
public static class MyClass{
...
}
It works ...
public class java_main{
public static void main(String[] args) {
// TODO Auto-generated method stub
Myclass my = new Myclass(3,4);
Myclass your = new Myclass();
System.out.println("keval");
}
}
class Myclass
{
public int a,b;
public Myclass(int i, int j)
{
a = i;
b = j;
}
public Myclass()
{
a = 1;
b = 2;
}
}
change your code to this:
public class java_main {
public static void main(String[] args)
{
Myclass my = new Myclass(3,4);
Myclass your = new Myclass();
}
}
class Myclass
{
public int a,b;
public Myclass(int i, int j)
{
a = i;
b = j;
}
public Myclass()
{
a = 1;
b = 2;
}
}
Just try this,
public class java_main {
public static void main(String[] args) {
MyClass my = new java_main().new MyClass(3, 4);
MyClass your = new java_main().new MyClass();
}
public class MyClass {
public int a, b;
public MyClass(int i, int j) {
a = i;
b = j;
}
public MyClass() {
a = 1;
b = 2;
}
}
}
Better approach is move the public class into separate file
Class name should start with Capital letter as per Java naming standard.
Here, I just created an instance of java_main and by using that instance created an instance for MyClass. This is an approach if you don't want to make MyClass as static inner class.
else make MyClass as static inner class it will work but it depends on use case,
public class java_main {
public static void main(String[] args) {
MyClass my = new java_main().new MyClass(3, 4);
MyClass your = new java_main().new MyClass();
}
public class MyClass {
public int a, b;
public MyClass(int i, int j) {
a = i;
b = j;
}
public MyClass() {
a = 1;
b = 2;
}
}
}
The problem you are having is you cannot reference non-static variables (instances of MyClass) from the static context (main menu in java_main class).
Either you change your MyClass like this,
public static class Myclass
Or take out MyClass out of the java_main class. And remove the public access modifier from the MyClass. Because you cannot have two public classes in the same file.
public class java_main {
public static void main(String[] args)
{
Myclass my = new Myclass(3,4);
Myclass your = new Myclass();
}
}
class Myclass
{
public int a,b;
public Myclass(int i, int j)
{
a = i;
b = j;
}
public Myclass()
{
a = 1;
b = 2;
}
}
Hope this helps for you or someone else.
Cheers!

If I have more files in one project I need to make all fields static?

If I make for example one project. Inside with two class. For example: X and Y. I make them what I want, and I want to make a main method in Y. Only system.out.printlf the values in X and Y. But it writes that I need to make them static if I want to run this. I tried to make a new file with only the main class and inside the X Y values but it showed an error. What I missed?
you have missed object creation. Try X x = new X(); in your Y file. I would recommend to read some tutorials on Java, starting from here.
The main method is declared static
public static void main(String[] args) {}
Inside of main, it can only access static variables that exist in the enclosing class. You will see this for example with this bit of code:
public class X {
private int i = 5;
public static void main(String[] args) {
System.out.println(i);
}
}
To make the above work you need to declare i as static:
public class X {
private static int i = 5;
public static void main(String[] args) {
System.out.println(i);
}
}
A better way would be to do this:
public class X {
private int i = 5;
public X() {
System.out.println(i);
}
public static void main(String[] args) {
new X();
}
}
Static methods can only access static methods and other variables declared as static.
This article may also help you to understand what is going on here.
I'm guessing that's because everything happens inside the main method which is indeed static right? e.g.
public class C {
int X;
int Y; //or whatever other type
..
public static void main(String args[]) {
System.out.print( X ); //this won't work!
}
}
instead use this aprroach:
public class C {
int X;
int Y; //or whatever other type
..
public static void main(String args[]) {
C inst = new C();
System.out.print( c.X ); //this will work!
}
}
The main method is static and can only access static fields from the class. non static fields belong to an instance/object which you'd have to create:
public class X {
static int a = 0;
int b = 0;
public static void main(String[] args) {
System.out.println(a); // OK -> accesses static field
System.out.println(b); // compile error -> accesses instance field
X x = new X();
System.out.println(x.b); // OK -> accesses b on instance of X
}
}

Categories