Does a non-static method create an instance of the class in which it is declared? If not why this code works?
import java.awt.*;
public class Main extends Frame {
public Main () {
//super keyword needs an istance of the class don't it?
super ("My frame");
super.setSize (200,100);
}
public static void main (String [ ] args) {
new Main();
}
}
If a non-static method creates an instance of the class the next code should work...
import.java.applet.*;
public class Main extends Applet {
public void print () {
System.out.println ("Hi");
}
public void init () {
this.print();
}
}
A non-static method can only be accessed in the context of an instance that already exists.
public class Foo {
public static void someStaticMethod() { /* ... */ }
public void someNonStaticMethod() { /* ... */ }
}
Elsewhere:
Foo.someStaticMethod(); // this works
Foo.someNonStaticMethod(); // this DOESN'T work
Foo foo = new Foo();
foo.someNonStaticMethod(); // but this does
Within a non-static method, you have access to an instance by default (implicitly), or can refer to it explicitly using the this keyword. In your example:
public class Main extends Frame {
public Main () {
//super keyword needs an istance of the class don't it?
super ("My frame");
super.setSize (200,100);
}
public static void main (String [ ] args) {
new Main();
}
}
...the instance in question in the call to super is the implicit instance you create with new Main().
Instances of classes in Java are created by calling a constructor using the new keyword:
Main main = new Main();
public void Main () { } however is not a constructor, but a instance method (which, in your example, never gets called).
public class Main {
public static void main(String[] args) {
Main main = new Main(); // create instance
main.Main(); // call method 'Main'
new Main().Main(); // or both at once
}
public Main() {
// this is the (default) constructor
}
public void Main() {
// this is an instance method (whose name 'should' start lowercase
}
}
Does a non-static method create an instance of the class in which it is declared?
No.
why this code works?
Because when such a method is called, it should be called from an already instantiated instance. "this"/"super" refer to the implicit parameter, which is the instance in question (instantiated and passed in from elsewhere, with "new"). If instantiation has not occurred, a NullPointerException will immediately be thrown.
Well actually in the main question I wrote a wrong code (I've been out for all the day and I'm quite tired) anyway it helped me to understand more. Now what about this code
import java.applet.*;
public class Main extends Applet {
//overrides Applet.init ()
public void init () {
//here I use super keyword without creating an istance of the class
super.init ();
//code here...
}
}
Related
This question already has answers here:
Java superclass calls subclass method
(5 answers)
Closed 1 year ago.
Why does method() call the overridden subclass method2 instead of method2 in the BaseClass?
public class BaseClass {
public void method(){
System.out.println("method() called");
method2();
}
public void method2(){
System.out.println("method2() called");
}
}
public class ChildClass extends BaseClass {
public void method2(){
System.out.println("method2() from BaseClass");
}
}
public class Main {
public static void main(String[] args) {
ChildClass obj = new ChildClass();
obj.method();
}
}
This is the concept of Runtime polymorphism (Dynamic Method Dispatch). Because you are assigning the object (instance) of ChildClass to obj reference variable, it will call the method of child class.
Always the method of the class whose instance is created gets called first. If that method is not present in that particular child class, then the parent's inherited method gets called.
If you come from the C++ corner:
all instance methods (non-static) in Java are virtual.
All class methods (static) are NOT.
This is why your case happens.
This is also, why the Java compiler will complain (warn) that if you access a static method via an object, that you should call via the distinct class, because calls to the "static method of a object" could be ambiguous, because it could be two static methods with the same signature that get called.
Extending your Example:
package stackoverflow.staticcalls;
public class BaseClass {
public void method() {
System.out.println("method() called");
method2();
}
public void method2() {
System.out.println("method2() called");
}
static public void sayHello() {
System.out.println("BaseClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class ChildClass extends BaseClass {
public void method2() { // compiler warning: The method method2() of type ChildClass should be tagged with #Override since it actually overrides a superclass method
System.out.println("method2() from BaseClass");
}
public void originalCallToBaseMethod2() {
super.method2(); // will run BaseClass.method2()
}
static public void sayHello() {
System.out.println("ChildClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class Main {
public static void main(final String[] args) {
final ChildClass obj = new ChildClass();
System.out.println("\nCalling obj.method(); ...");
obj.method();
System.out.println("\nCalling obj.sayHello(); ...");
obj.sayHello(); // compiler warning: The static method sayHello() from the type ChildClass should be accessed in a static way
System.out.println("\nCalling ChildClass.sayHello(); ...");
ChildClass.sayHello(); // the proper call
System.out.println("\nCalling BaseClass.sayHello(); ...");
BaseClass.sayHello(); // but you can also explpicitly call the other method
System.out.println("\nCalling obj.originalCallToBaseMethod2(); ...");
obj.originalCallToBaseMethod2(); //
}
}
Here you see the examples to what I said.
Note: In the last call in Main.main() we still can call BaseClass.method2(), but not directly. We have to be within ChildClass to do that, and it's done via the super keyword/reference.
A little off-topic note, to complete addressing patterns:
If you're inside an inner class and need to call to a overshadowed name in the outer class, you can use Outer.this.method():
package stackoverflow.staticcalls;
import stackoverflow.staticcalls.OuterInner.Outer.Inner;
public class OuterInner {
class Outer {
void method() {
System.out.println("OuterInner.Outer.method()");
}
class Inner {
void method() {
System.out.println("OuterInner.Outer.Inner.method()");
}
void callOuter() {
Outer.this.method();
}
}
}
public static void main(final String[] args) {
final OuterInner oi = new OuterInner();
final Outer outer = oi.new Outer();
final Inner inner = outer.new Inner();
System.out.println("\nCalling inner.method(); ...");
inner.method();
System.out.println("\nCalling inner.callOuter(); ...");
inner.callOuter();
}
}
As I have gone through some of the programming sites which explains anonymous inner class in java.
But, I still have doubts that how it really works and on the conclusions which I made below.
Here is code :
public class Implementing {
public static void main(String[] args) {
SuperClass a = new SuperClass() { // ... 1st
public void call () { // ... 2nd
System.out.println("Method call");
}
public void call2 () { // creating new method in anonymous inner class
System.out.println ("New call2 Method in Anonymous Class");
}
};
a.call(); // ... 3rd
try {
a.getClass().getMethod("call2",null).invoke(a,null); // ... 4th
} catch (Exeception e) {
System.out.println(e);
}
}
}
class SuperClass {
public void call() {
System.out.println("Super Class");
}
}
What I understand is this :
At 1st :-
Anonymous inner class is sub-class.
we are creating instance of anonymous inner class as well as we
are extending the class SuperClass.
we are running constructor of SuperClass, but we created object
of anonymous class of type SuperClass.
polymorphism at work.
Actually, we are doing this at 1st :
* 1. anonymousClass extends SuperClass
* 2. anonymousClass a = new SuperClass()
* 3. { }; // our anonymous class field
At 2nd : - overrides SuperClass call Method().
At 3rd : - calling call() Method by object 'a'.
At 4th : - accessing new method call2() Method in anonymous inner class.
So, my these conclusions are right or wrong ? If wrong why they are wrong ? Please Explain.
Your code creating an Anonymous Class:
public static void main(String[] args) {
SuperClass a = new SuperClass() { // ... 1st
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
};
...
}
is the same as this code creating a Local Class:
public static void main(String[] args) {
class LocalClass extends SuperClass {
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
}
SuperClass b = new LocalClass();
...
}
except that the class is unnamed, aka anonymous.
Since you're doing this from a static method, and you're not using any local variables, they are both the same as this Static Nested Class:
static class NestedClass extends SuperClass {
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
}
If you look at the compiled .class files, you'll see they are all just classes:
SuperClass.class <-- Your superclass
Implementing.class <-- Your main class
Implementing$1.class <-- Anonymous class
Implementing$1LocalClass.class <-- Local class
Implementing$NestedClass.class <-- Nested class
I'm new to Java and is trying to learn the concept of anonymous class. Could someone please tell me how I can invoke the 'awesomeMethod' from the main method of the LocallClassExample?
public class LocalClassExample {
interface Awesome {
public void awesomeMethod();
}
class AwesomeClass {
public int finalInt= 10;
Awesome a1 = new Awesome() {
#Override
public void awesomeMethod() {
System.out.println(finalInt);
}
};
}
public static void main(String[] args) {
}
}
Consider this:
new AwesomeClass().a1.awesomeMethod();
will invoke the method awesomeMethod() on the member variable a1 (which is something Awesome) of the newly created instance of AwesomeClass.
It will get more tricky once your main is outside of your AwesomeClass - and more so once it's outside of the package. In these cases you'd have to provide a getter like
public Awesome getAwesome() {
return a1;
}
Which would when invoked still execute the method as defined in your anonymous class.
Try to use this to create inner class object as:
public static void main(String[] args) {
LocalClassExample.AwesomeClass oi = new LocalClassExample().new AwesomeClass();
oi.awesomeMethod();
}
I have a class called "Design", and I am writing the following code to extend the class to include a new function called sayHello(). However it doesnt seem to be working. Am I only allowed to ovveride existing functions in that way?
Design design1 = new Design() {
public void sayHello() {
System.out.println("hello");
}
};
design1.sayHello(); // this gives an error "function not found"
So that is logical.
You are overriding a super class and assigning it to the instance variable of super class.
As the instance variable is of super class type, you can access only those methods which are available in super class.
You can do that if your "Design" class is an interface. You could create an anonymous inner class.
Example:
public interface Design{
public void sayHello();
}
public class Test
{
public static void main(String args[])
{
Design d = new Design(){
#Override
public void sayHello(){
return "Hello World!";
}
};
System.out.println(d.sayHello());
}
}
I was looking at this topic:
java Access parent method from imported child class
But I'm still not sure the proper terminology for what I'm trying to do.
I have an Instance of Test and I want to call a method from the "parent" that created the instance.
public class Main {
public Main {
Test test1 = new Test();
}
public void showMessage(String message) {
System.out.println(message);
}
}
public class Test {
public Test {
//how do I call Main.showMessage("test is running")?
}
}
The answer in the topic I listed above was:
Assuming the "parent" is a class you're extending and the method you're calling is NOT static, the following should do the trick:
super.toggleVisibility();
If it's a static method - it's even Simpler:
Main.showMessage();
The issue:
I'm pretty sure I can't use super() cause I'm not extending a class. And I'm not sure if Main.showMessage(); will work because I haven't referenced the parent Main within the Test class.
You can pass an instance of Main into Test, and I'd use an interface to help decouple things:
public class Main implements Parent {
public Main() {
Test2 test2 = new Test2(this);
}
public void showMessage(String message) {
System.out.println(message);
}
public static void main(String[] args) {
new Main();
}
}
interface Parent {
void showMessage(String message);
}
class Test2 {
public Test2(Parent parent) {
parent.showMessage("I am running from in Test");
}
}
Create an instance of the desired class and call the desired method:
public class Test {
public Test() {
//how do I call Main.showMessage("test is running")?
Main main = new Main();
main.showMessage("test is running");
}
}
As noted by #BrianRoach, by your current code, this will generate a StackOverflowError since it is an infinite loop (Main instance that creates a Test instance in its constructor that creates a Test instance in its constructor ...)
So, another option may be passing a Main class instance to Test constructor:
public class Test {
public Test(Main main) {
main.showMessage("test is running");
}
}
Then, in Main constructor:
public Main() {
Test test1 = new Test(this);
}