public class Test {
public static void main(String[] args) {
B b = new B();
b.test();
}
}
class A {
String aString = "a";
void test() {
System.out.println(aString);
}
}
class B extends A {
String aString = "b";
}
why the cant input out "b"?
i just think b.test() will call method of superClass, so b will user superClass's attribute.
why the cant input out "b"? i just think b.test() will call method of superClass, so b will user superClass's attribute.
Java class and instance variables can be inherited, but they are not virtual. That is, all variable identifiers appearing in Java code are resolved at compile time -- there is no dynamic resolution for them.
Thus, the appearance of identifier aString in method A.test() is resolved at compile time to the aString attribute of class A. This is the attribute that all invocations of that method will access, regardless of the actual class of the object on which it is invoked. If you want to use the attribute of class B when test() is invoked on an instance of that class then provide getter methods in classes A and B and have A.test() obtain the string via those.
The variable in b is hiding the variable in a. You can fix it by removing the type in b
class B extends A {
public B () {
aString = "b";
}
}
class A {
String aString = "a";
void test() {
System.out.println(aString);
}
}
class B extends A {
String aString = "b";
}
Creates 2 aString variables for B. While A will not know about B extending it, B can always access "things" from its parent class A, using the super keyword. So when you are in B, you can use aString and super.aString and they will refer the 2 different variables:
class Ideone {
public static void main (String[] args) {
A a=new A();
B b=new B();
a.test();
b.test();
b.suptest();
}
static class A {
String aString="A.aString set from A";
void test() {
System.out.println("A.test(): "+aString);
}
}
static class B extends A {
String aString="B.aString set from B";
{
super.aString="A.aString set from B";
}
void test() {
System.out.println("B.test(): "+aString);
}
void suptest() {
System.out.print("B.suptest() calling super.test(): ");
super.test();
}
}
}
You can try it on IdeOne, produces output
A.test(): A.aString set from A
B.test(): B.aString set from B
B.suptest() calling super.test(): A.test(): A.aString set from B
Where the first two lines show nothing fancy, A.aString and B.aString both contain their initial value.
But the third output line shows that super.test() call in B really "ends" in A.test(), and that the initializer block in B really altered the inherited aString field.
(Side note: the static class magic relates to the example being contained in a single file, it doesn't affect the inheritance-part)
You are correct.
Since Class A and the method test() are not abstract and the fact that the method test() was not overrided by its subClass B, the return will be exactly how was specified in Class A even if you call it from a B instance.
Related
I wrote down this mini-program:
A class:
public class A
{
public A()
{
System.out.println(getS());
}
public String getS() { return s;}
}
B class:
public class B extends A
{
private String s = "hello2";
public String getS() { return s;}
}
main:
public static void main(String[] args)
{
B b = new B();
}
and it printed:
null
Why is that?
I know that the String that printed is B's string, but why it didn't initialized before?
According to this answer - the variable initialized before the constructor..
EDIT -
I edited the code so the unrelated code won't confuse
Here is what's going on: when you construct B, the first thing its constructor needs to do is constructing A. This is done before B's own field s is initialized.
A constructs its own s, and then calls getS. However, it does not get its own getS, because B provides an override for it. Recall that B.s has not been initialized yet. That is why you see null printed.
Follow-up reading: What's wrong with overridable method calls in constructors?
What is happening:
You create a B instance, this will call the super() so the constructor of A.
Here it will do the print using the getter getS(). This will use the getter of B since this is the type of this but in this getter, the String is not yet instanciate since it is still doing the super class construction, so it return null.
Note that the String s in A is hidden by the one in B
The order during an instance is :
the static (from the super then the class)
the super class declaration (statement then constructor)
the block statement
the constructor
As Seen with :
public class A{
static{System.out.println("sA");}
{System.out.println("A1");}
public Main() {
System.out.println("new A");
}
{System.out.println("A2");}
public static void main(String[] args) {
new A();
}
}
class B extends Main {
static{System.out.println("sB");}
{ System.out.println("B1"); }
public B() {
System.out.println("new B");
}
{ System.out.println("B2"); }
}
Output :
sA
sB
A1
A2
new A
B1
B2
new B
it prints null because you have polymorphism in java. You Overrided method getS(). So when you call it from A, you try to call getS() from class B. But you didn't create instance of class B yet, because you need to finish class A first. So String in class B haven't been initialized yet, because of it you get null.
I wrote a piece of code as following:
class MyParent {
String a = "abcdefg";
String b;
public void print() {
b = "ABCDEFG";
System.out.println(a);
}
}
class MyChild extends MyParent {
String c = super.b;
public void print2() {
System.out.println(c);
}
}
public class Parent {
public static void main(String args[]) {
MyParent mp = new MyParent();
mp.print();
MyChild mc = new MyChild();
mc.print2();
}
}
There are two classes and they are parent&child.
There is a b declared in the class MyParent , and is given a value in the function print() .
I wanna print b in the child class MyChild. But if I run the code, it can print a correctly, but b shows null.
I'm new to Java. Please help me about it.
UPDATE
Thanks to everyone answers my question. I found the solution.
I used the simplest way. I changed it into **static String b**.
static makes my arguments can be used all around.
But I don know the exact way of using data declarations. So I will keeping learning.
It prints null because in MyParent class you declared it as an empty String. You initialized b in print() method. So if you want to take value of b you can do this:
MyChild mc = new MyChild();
mc.print();
The instance of mp and mc objects are different. So the value of b is set to "ABCDEFG" in object mp but mc.b is still null.
Try calling mc.print() and then mc.print2()
However if you want different instances of object's to share the same value of b on updating, then you can make b as static.
you have to call
print()
method of MyParent to initialize "b". You are not initializing it.
when u make extend class evry method and attributes who got protected and less go to the child now if the parent got string b the child also got string b
if u want the string b of the child will be the same value of string b in parent u make a constructor and make inside the constructor this.b=super.b and its mean when u create the object of the child class its initialize the attribute .
now in this code u should not initialize attribute like that in object oriented.
class MyParent {
String a = "abcdefg";
String b="ABCDEFG";
public MyParent(){}
public void print() {
System.out.println(a);
}
}
class MyChild extends MyParent {
public MyChild(){
this.b =super.b;
}
public void print2() {
System.out.println(b);
}
}
public class Parent {
public static void main(String args[]) {
MyParent mp = new MyParent();
mp.print();
MyChild mc = new MyChild();
mc.print2();
}
}
In this program
class a
{
int a=25;
public void aa()
{
System.out.println(a);
}
}
class b extends a
{
int a=2;
public static void main(String[] args) {
b x=new b();
x.aa();
}
}
why does "x.aa()" prints 25 ans why not 2?,what is the reason behind it?
class a
{
int a=25;
public void aa()
{
System.out.println(a);
b();
}
public void b()
{
System.out.println("this should print");
}
}
class b extends a
{
int a=2;
public static void main(String[] args) {
b x=new b();
x.aa();
}
public void b()
{
System.out.println("this should not print");
}
}
and if we consider the above output,then here again the output of b() of above should print "this should print" but we are getting the ouput from sublcass "this should not print"
Class b inherits class A, so when you call x.aa, it is calling method aa of class a. The member a of class a is initialized with 25 so it prints 25. Class a does not know about the member a of class b.
Fields cannot be overridden, and are not virtual. B.a* is independent of A.a, to the point that they can actually have different types. There is no way for B to make A aware of B.a in place of A.a. Instances of B will actually have two fields named a, but one is hidden ("shadowed") by the other. (If desired, code B can refer to its A.a field by writing ((A)this).a. This is because the appropriate a is selected based on the type of ((A)this), which is A, rather than the runtime type of the instance, which would be B or a subtype of B.)
* Note: I have renamed your classes to A and B: per the Java naming conventions, class-names begin with uppercase letters.
b x=new b();
while you will do this this will print out put of the constructor as its giving because its clearly making the object of b class and while in the case of class A in that class that b() act as the method so it wont call when you are making object of class b.
while in the case of
b x=new b();
x.aa();
this it will by default call the inheritance and will print as u getting output.
and one more thing.
public void aa()
{
System.out.println(a);
}
in the case of this it will use the local variable of that particular class so it will print whatever you have defined on that class. in your case that is a=25;
by the way nice question.
method aa() is member of class a. so, method aa() can see/access instance member of class a.
Now, you have inherited class a to b. it means object of class b can access/call aa(). but, it doesn't mean that aa() is allowed to access variable a of class b. thats why method aa() is printing the variable a of it's own class and prints 25.
now about your second program. in class b, you are overriding method b(). while calling an overridden method, the selection of method(whether from sub class or super class) is done on the basis of instance of a invoking object(whether sub class or super class respectively).
you have called method aa() with the instance of class b that is why method b() of class b is called.
ot sure if a similar question do exists or have been answered earlier. I did a search but couldn't find anything related.
Please see following example. There's a class A with noargument contructor. Class B extends Class A but no default contructor exists. The output is B-> get c, and I think java uses the runtime polymorphism logic to invoke the B object method.
Here would like to understand if its correct and how Java works here (Maybe what's the underlying logic)
Thanks
public class A {
private String cStr="";
private String dStr="";
A()
{
getcStr();
}
public String getcStr() {
System.out.println("A-> get c");
return cStr;
}
public String getdStr() {
System.out.println("A-> get d");
getcStr();
return dStr;
}
}
public class B extends A{
private String cStr;
public String getcStr() {
System.out.println("B-> get c");
return cStr;
}
}
public static void main (String[] args)
{
A a= new B();
a.getdStr();
}
EDIT: the output for the a.getdStr() is A-> get d B-> get c
If a class doesn't have a default constructor, in your case B, then java will implicitly insert a no argument constructor something like this
public B() {
super();
}
To answer your question, Yes, due to run time polymorphism, Java invoke's B's getcStr() method. Because B's constructor is calling A's constructor via super()
This is a famous anti-pattern. And its anti-pattern because you are trying to invoke a overriden method on B before B is fully constructed
Imagine your B class was like this
public class B extends A{
private String cStr = "abc";
public String getcStr() {
System.out.println(cStr);
return cStr;
}
}
Now the output of your program would have been null instead of "abc" because B is not fully constructed yet (that means cStr is not initialized to "abc")
there is no default constructor for B so it'll call A() constructor.....
Now new B(); creates the object of B so java will first look into class B that is any procedure like getcstr() exists if procedure found there it will invoke it otherwise check in the super class for that procedure......
In Python, class methods can be inherited. e.g.
>>> class A:
... #classmethod
... def main(cls):
... return cls()
...
>>> class B(A): pass
...
>>> b=B.main()
>>> b
<__main__.B instance at 0x00A6FA58>
How would you do the equivalent in Java? I currently have:
public class A{
public void show(){
System.out.println("A");
}
public void run(){
show();
}
public static void main( String[] arg ) {
new A().run();
}
}
public class B extends A{
#Override
public void show(){
System.out.println("B");
}
}
I'd like to call B.main() and have it print "B", but clearly it will print "A" instead, since "new A()" is hardcoded.
How would you change "new A()" so that it's parameterized to use the class it's in when called, and not the hard-coded class A?
Static methods in java are not classmethods they are staticmethods. In general it is not possible to know which class reference the static method was called from.
Your class B does not have a main method and static methods are not inherited.
The only way I can see this happening is to find whatever is calling A.main( String[] arg ) and change it to call B.main instead.
B.main:
public static void main( String[] arg ) {
new B().run();
}
How is your program started? Is there a batch file, shortcut, etc? Something you can change? Where does A.main get called?
I think this isn't possible. Here's why:
In Java, the implementation of a method is determined by the instance's run-time type. So, to execute B.show(), you need to have an instance of B. The only way I could see to do this, if the method that constructs the instance is supposed to be inherited, is to use Class.newInstance() to construct an instance of a type that's not known at runtime.
The problem with that is that within a static method, you have no reference to the containing class, so you don't know whose newInstance method to call.
Why do you want to do this, though? There may be some better way to achieve whatever it is you want to achieve.
In your example I wouldn't put your main method inside of A. This is setup as the entry point into the system (you can't be in B if you are specifically entering into A).
In the example below I created class A, B, and C. Class C instantiates A and B and runs them. Notice that in C I created an A, a B, and another A that I instantiate as a B. My output is:
A
B
B
Hopefully this makes sense.
public class A {
public void show(){
System.out.println("A");
}
public void run(){
show();
}
}
public class B extends A {
#Override
public void show(){
System.out.println("B");
}
}
public class C {
public static void main(String[] args) {
A a = new A();
B b = new B();
A anothera = new B();
a.show();
b.show();
anothera.show();
}
}