i have this example:
class One
{
public void testOne(){System.out.println("One!!!");}
public void testTwo(){System.out.println("One!!!");}
}
public class Jenia extends One
{
static void test(One o) {o.testOne(); o.testTwo();}
public static void main(String args[])
{
test(new One());
}
}
Results:
One!!!
One!!!
ok, no questions.
than, i try modified my code:
only this method:
public static void main(String args[])
{
test(new Jenia());
}
results:
One!!!
One!!!
ok, we have this results because - here upcasting(Jenia-One).
its all ok too, but, modified again:
in class Jenia override methodtestOne`:
public void testOne(){System.out.println("Two!!!");}
so i have this code:
class One
{
public void testOne(){System.out.println("One!!!");}
public void testTwo(){System.out.println("One!!!");}
}
public class Jenia extends One
{
public void testOne(){System.out.println("Two!!!");}
static void test(One o){o.testOne(); o.testTwo();}
public static void main(String args[])
{
test(new Jenia());
}
}
and results:
Two!!!
One!!!
my question: why Two!!! ?? why we not lost override methods?
Because all the methods in Java are virtual in terms of C++/C# and all the values passed by reference. So when you call some method, the type of the reference is irrelevant, what is important is the type of the object it points to. In your case the object is of Jenia type, so Jenia method gets called.
Thats the desired behaviour.. which method gets called depends on the runtime type, not the reference type. Since the obect is type of Jenia, the Jenia version of testOne gets called, even if the reference is type of One. Thats plain old polymorphism.
See the explanation in comments
class One
{
public void testOne(){System.out.println("One!!!");}//method one
public void testTwo(){System.out.println("One!!!");}//method two
}
public class Jenia extends One
{
public void testOne(){System.out.println("Two!!!");}//method 3
static void test(One o){o.testOne(); o.testTwo();}//method 4
public static void main(String args[])
{
test(new Jenia());//calls method 4 which in turns calls 3 and 2.
}
}
}
When you call o.testOne() in test method, it calls Jenia.testOne since the o is an instance of Jenia. You can check it by o.getClass().getName();.
java overriding here is the tutorial http://download.oracle.com/javase/tutorial/java/IandI/override.html
public class A {
void print() {
System.out.println("A");
}
public static void main(String[] args){
A a1 = new A();
a1.print(); // A
A a2 = new B();
a2.print(); // B ! because it overrides print method
B b = new B();
b.print(); // B
}
}
class B extends A {
void print() {
System.out.println("B");
}
}
Related
I want to ask a question about java constructor.
Example,i have "A" class and "B" class and i created constructor in "b" class. In normal way, when i create "b" class object in main method of "a" class, class "b" constructor will automatically work. So, my question is when I create b class object in "a" class,i want to work other functions first before working constructor.
So what should i do?
public class A {
public static void main(String[] args) {
B b = new B();
}
}
public class B {
public B() {
System.out.print("Hello Constructor");
}
public void m() {
System.out.print("Hello Method");
}
}
Normally :: Output :: Hello Constructor
Hello Method
i want this Output :: Hello Method Hello Constructor
Can be? Sorry for my bad English...
Inside the constructor of B, call the method M. your question is a tad confusing, but if I understand you correctly, this is what you want.
public class A{
public static void main(String[] args){
B bb=new B();
}
public class B{
public B(){
M();
System.out.print("Hello Constructor");
}
public void M(){
System.out.print("Hello Method");
}
actually you can't do it with your thinking way(or i don't know a way for it) but you can try this:
public class A {
public static void main(String[] args) {
B b = new B();
}
}
public class B {
public B() {
//write what are you wanting to do like m(); for this exapmle
System.out.print("Hello Constructor");
}
public void m() {
System.out.print("Hello Method");
}
}
its simple trick but it wokrs.By the way you can try it without constructor like initializing your variables with another method:
public class A{
public static void main(String[] args){
B bb=new B();
bb.m();
bb.b();
}
public class B{
public void b(){
System.out.print("Hello Constructor");
}
public void m(){
System.out.print("Hello Method");
}
Java 7
First of all, I'm going to simplify the example to avoid posting unnecesary code. My specific concrete example a little bit complicated, but I' try to preserve the point.
public class Test {
public static void main(String[] args){
Test t = new Test(){ //<---------------------------------------------------------
public void m(){ // |
Test t = new Test(){// |
public void m(){// |
//Here I need to invoke the most inclosing class's m() method
}
//other actions
};
}
public void someMethod(){
//action
}
};
}
public void m(){
}
}
Is it possible to do in Java? I mean, to invoke the method of anonymous class that way?
No it's impossible because there is no reference to the anonymous classes.
This is the only possible way to call the instance m() method :
new Test(){
public void m(){
}
}.m();
By definition according to the oracle documentation here :
Anonymous classes enable you to make your code more concise. They
enable you to declare and instantiate a class at the same time. They
are like local classes except that they do not have a name. Use them
if you need to use a local class only once
So if you have to use one of the methods of your class you have to create a local one.
You cannot access the methods of the anonymous class using normal java, but you are able using reflection:
Test t = new Test{
public void m() {
System.out.println("Welcome to my class");
}
};
Class<?> c = t.getClass();
Method m = c.getDeclaredMethod("m");
// m.setaccessible(true); // if private
m.invoke(t);
Here is a way to do it:
public class Test
{
public static void main(String[] args)
{
Test t = new Test()
{
public void m() // this one will be called
{
Runnable r = new Runnable()
{
#Override
public void run()
{
m();
}
};
Test t = new Test()
{
public void m()
{
r.run();
}
};
}
};
}
public void m()
{
}
}
If the method returns a value, use Callable<V> instead.
I have a question about this code right here
public Car {
public static void m1(){
System.out.println("a");
}
public void m2(){
System.out.println("b");
}
}
class Mini extends Car {
public static void m1() {
System.out.println("c");
}
public void m2(){
System.out.println("d");
}
public static void main(String args[]) {
Car c = new Mini();
c.m1();
c.m2();
}
}
I know that polymorphism does not work with static methods, only to instance methods. And also that overriding doesn't work for static methods.
Therefore I think that this program should print out: c, d
Because c calls the m1 method, but it's static, so it can't override and it calls the method in class Mini instead of Car.
Is this correct?
However, my textbook says that the answer should be : a, d
is it a typo? Because I'm a little confused right now.
Please clear this up, thanks.
Because c calls the m1 method, but it's static, so it can't override and it calls the method in class Mini instead of Car.
That's exactly backwards.
c is declared as Car, so static method calls made through c will call methods defined by Car.
The compiler compiles c.m1() directly to Car.m1(), without being aware that c actually holds a Mini.
This is why you should never call static methods through instance like that.
I faced the same issue while working with Inheritance. What I have learned is if the method being called is Static then it will be called from the class to which the reference variable belongs and not from the class by which it is instantiated.
public class ParentExamp
{
public static void Displayer()
{
System.out.println("This is the display of the PARENT class");
}
}
class ChildExamp extends ParentExamp
{
public static void main(String[] args)
{
ParentExamp a = new ParentExamp();
ParentExamp b = new ChildExamp();
ChildExamp c = new ChildExamp();
a.Displayer(); //Works exactly like ParentExamp.Displayer() and Will
call the Displayer method of the ParentExamp Class
b.Displayer();//Works exactly like ParentExamp.Displayer() and Will
call the Displayer method of the ParentExamp Class
c.Displayer();//Works exactly like ChildExamp.Displayer() and Will
call the Displayer method of the ChildtExamp Class
}
public static void Displayer()
{
System.out.println("This is the display of the CHILD class");
}
}
public class A {
public void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
I want to use A's foo, what is the syntax for doing that? I tried a.super.foo();.
Thank you
You can only do so from within the class B. You won't be able to invoke A's foo from outside A or B classes.
A a= new B(); will always set the reference a to an instance of B. Thus, even though you cast it to A, at runtime the method that gets invoked is B.foo. That's runtime polymorphism.
I am really uneasy about a design that needs to do this kind of thing. If you want the object to behave like an A, why did you create a B?
You cannot use super from the outside of the class. Assuming you really, really need this (but I really doubt you can't find a better way) the best you can do about it is to expose a method that does this call to the outside:
public class B extends A {
public void super_foo() {
super.foo();
}
public void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.super_foo();
}
}
Here is it
public class A {
public void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public void foo() {
super.foo();
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
You can't access it. The keyword is that it has been overridden by Java so it's no longer accessible.
What you want to achieve will work if the method is static. Non virtual methods in java
public class A {
public static void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public static void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
In the code below, myString is always initialized to null. I have to manually initialize in an init() or similar. As far as I can tell it is related to superclass/subclass but I don't understand the exact mechanism
public class A extends B {
private String myString = "test";
public static void main(String[] args) {
new A();
}
public A() {
super();
}
public void c() {
System.out.println(myString);
}
}
public class B {
public B() {
c();
}
public void c() {
}
}
The issue with your code is, that myString is initialized at the begin of the constructor of class A but right after the super constructor (i.e. class B). Since you access the variable before from the constructor of class B (indirectly via call to overriden methode c) your get this behaviour.
As a rule of thumb: if you want to avoid unexpected behavior do not call overriden methods before the constructor has been executed.
Add a call to c(); overidden method right after the object has been fully created and call to superclass constructor is done.
Change your code to this ..
public class A extends B {
private String myString = "test";
public static void main(String[] args) {
new A();
}
public A() {
super();
c(); // Include the call to c(); here ...
}
public void c() {
System.out.println(myString);
}
}
public class B {
public B() {
}
public void c() {
}
}
// Output : test
Thinking in Java Second Edition by Bruce Eckel, Behavior of polymorphic methods
inside constructors (p. 337-339).