How to access a method of Extended Class from nested class? - java

I have two nested classes inside a class with the outer class extending another class. The structure is something like this.
public class EXTENSION_CLASS
{
public int Get_Value()
{
return(100);
}
}
public class OUTER extends EXTENSION_CLASS
{
public static class NESTED1
{
public void Method1()
{
int value=0;
value=Get_Value();
System.out.println("Method1: "+value);
}
}
public static class NESTED2
{
NESTED1 Nested1_Instance=new NESTED1();
public void Method2()
{
Nested1_Instance.Method1();
}
}
public void run()
{
NESTED2 Nested2_Instance=new NESTED2();
Nested2_Instance.Method2();
}
public static void main (String[] args)
{
OUTER New_Class=new OUTER();
New_Class.run();
}
}
I'm expecting the output: "Method1: 100". But, am getting the output: "OUTER.java:16: error: non-static method Get_Value() cannot be referenced from a static context value=Get_Value();". How can i make this working?
Cheers !
Rajesh.

Remove the static modifier from the declaration of NESTED1 and NESTED2, like so:
public class NESTED1

If you want keep the nested classes static, you will have to create an instance of OUTER in the Method1() to access Get_Value().
public void Method1()
{
int value=0;
OUTER outer = new OUTER();
value=outer.Get_Value();
System.out.println("Method1: "+value);
}

You're trying to make a static reference to a non-static member.
This means that you're trying to access a instance member from a static member of the class.
To fix the issue, remove the static modifier from both the NESTED1 and NESTED2 clases.
Alternately, if you do not wish to remove the static modifier, you will have to create an object of the OUTER or EXTENSION_CLASS classes and then invoke Get_Value() using the object.
For example:
public void Method1()
{
int value=0;
EXTENSION_CLASS ext = new EXTENSION_CLASS ();
value=ext.Get_Value();
System.out.println("Method1: "+value);
}
OR
public void Method1()
{
int value=0;
OUTER outer = new OUTER();
value=outer.Get_Value();
System.out.println("Method1: "+value);
}

The error says every thing. You can not call non-static methods from static methods / class.
To make it work, Simply add static keyword to 'Get_Value' method in EXTENSION_CLASS.

Related

Is there any way to create object of method-local inner class in main method?

I was wondering if there is any way to create a method-local inner class object in main() method with the help of Outerclass object.
public class Outerclass {
// instance method of the outer class
void my_Method() {
int num = 23;
// method-local inner class
class MethodInner_Demo {
public void print() {
System.out.println("This is method inner class "+num);
}
} // end of inner class
// Accessing the inner class
MethodInner_Demo inner = new MethodInner_Demo();
inner.print();
}
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.my_Method();
}
}
Edit-1:
I was exploring the way to instantiate a method-local inner class in the main method ( I know the method-local inner class is not visible to the main method) but still, is there any workaround?
public class Outerclass {
// instance method of the outer class
void my_Method() {
int num = 23;
// method-local inner class
class MethodInner_Demo {
public void print() {
System.out.println("This is method inner class "+num);
}
} // end of inner class
}
public static void main(String args[]) {
Outerclass outer = new Outerclass();
//inner-class object is created while calling my_Method()
// TBH IDK how to do this
outer.my_Method().new MethodInner_Demo();
}
}
Class MethodInner_Demo is a local class, not an inner class, since it is declared in the body of a method. See e.g. The Java™ Tutorials.
A local class can only be seen by code in the method where is it declared.
If you want to be able to create an instance of the class from another method, then you need to move the class outside the method, so it becomes an actual inner class.
You can then create an instance, assuming you're "authorized", as defined by the public, protected, and private access modifiers. You do that by qualifying the new operator with an instance of the outer class.
In your case, we also need to add a field to carry the value of num.
public class Outerclass {
// instance method of the outer class
void my_Method() {
int num = 23;
// Accessing the inner class
Inner_Demo inner = new Inner_Demo(num);
inner.print();
}
// inner class
class Inner_Demo {
private final int num;
Inner_Demo(int num) {
this.num = num;
}
public void print() {
System.out.println("This is inner class "+num);
}
} // end of inner class
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.my_Method();
// Accessing the inner class
int num = 42;
Inner_Demo inner = outer.new Inner_Demo(num);
inner.print();
}
}
The type of the method local class is invisible to main. However, you can create that instance and pass it to main.
public class OuterClass {
Object createInnerClass() {
int num = 23;
class InnerClass {
#Override
public String toString() {
return "I'm InnerClass. num=" + num;
}
}
return new InnerClass();
}
public static void main(String args[]) {
OuterClass outer = new OuterClass();
Object obj = outer.createInnerClass();
System.out.println(obj);
}
}
output:
I'm InnerClass. num=23

Method Local Inner classes program

I am just learning Java concepts.
Can anyone let me know why i am not able to run this program?
package innerClasses;
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
class Inner {
public void m2() {
System.out.println(i);
}
}
}
public static void main(String[] args) {
Test t = new Test();
Test.Inner in = t.new Inner();
t.m1();
}
}
Can anyone let me know why i am not able to run this program?
The most basic reason is because of scope. In order to do
Test.Inner in = t.new Inner();
Inner must be defined in Test, but it is instead defined in m1 scope.
The class Inner is declared inside the method m1(), what makes it not available outside this method.
Your code has to look like the following to be able to run, although it will not print anything...
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
}
class Inner {
public void m2() {
System.out.println(i);
}
}
public static void main(String[] args) {
Test t = new Test();
Test.Inner in = t.new Inner();
t.m1();
}
}
Replacing t.m1(); by in.m2(); will output 10.
EDIT
In case you have to create the inner class inside the method, make it like
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
class Inner {
public void m2() {
System.out.println(i);
}
}
// this is what makes it run
Inner myInner = new Inner();
myInner.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1();
}
}
to compile and run.
IMHO this is not a good way to go...
A method inner class is only visible to that method only so you can't use this at any other location.
for using this class you have to declare it outside of the method.
You cannot compile it as the scope of Inner class is the m1 method.
If you want to be able to create instances of Inner class you can define it directly inside the Test:
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
}
// On the Test class level
class Inner {
public void m2() {
System.out.println(i);
}
}
public static void main(String[] args) {
Test t = new Test();
Test.Inner in = t.new Inner();
t.m1();
in.m2(); // prints 10
}
}
Another feature provided by Java is to use anonymous classes. It can be created by implementation of some Interface:
// Define an interface to be able to implement it inside the method
interface Inner {
void m2();
}
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
// Implement interface and call method on it
// Functional style:
((Inner) () -> System.out.println(i)).m2();
// Legacy style:
new Inner() {
#Override
public void m2() {
System.out.println(i);
}
}.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1(); // prints 10 twice
}
}
or extending some class:
// A class we going to extend
class Inner {
void m2() {
System.out.println(11);
}
}
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
// Extend inner class and call method on it
new Inner() {
void m2() {
System.out.println(i);
}
}.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1(); // prints 10, not 11
}
}
So the best way for you depends on what code design do you want to get finally.
Your class Inner is what the JLS calls a Local Class (14.3. Local Class Declarations).
The scope of a Local Class is defined as (6.3. Scope of a Declaration):
The scope of a local class declaration immediately enclosed by a block (§14.2) is the rest of the immediately enclosing block, including its own class declaration.
The scope of a local class declaration immediately enclosed by a switch block statement group (§14.11) is the rest of the immediately enclosing switch block statement group, including its own class declaration.
In your case it is declared in a block, which is the body of your method. So the scope where your class is visible is the rest of this method body.
As the type Inner is not visible in main(), you cannot use it there. You could create instances of it and use them within m1(), though.
The very basic reason for compile time error is "Scope".
As per your code, class Inner is defined inside method m1 (this class is called Local class/method local class),so if you observe the scope of method variable, its within the declared method only and we cannot access any method variable outside that method and this is reason, the scope of class Inner is limited to the m1 method
so if you want to instantiate class Inner and invoke its methods then you must do it in m1 method (in code , you are trying to create class Inner object outside method m1, which is not possible) hence the code would be
public class Test {
int i = 10;
static int j = 20;
public void m1() {
int k = 30;
final int m = 40;
class Inner {
public void m2() {
System.out.println(i);
}
}
Inner in = new Inner();
in.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1();
}
}
some more info , the local classes can be used when any repeated functionality is required inside a method (as nested methods are not allowed in java, so we can create inner class) and off course if we are not interested to create class level method for example
class Outer {
public void cal() {
class Inner {
public void sum(int x, int y) {
System.out.println("sum : "+(x+y));
}
}
Inner i= new Inner();
i.sum(10, 20); //sum is repeatdly needed in between code
i.sum(100, 200);
i.sum(1000, 2000);
i.sum(10000, 20000);
}
}
public class TestClass {
public static void main(String[] args) {
new Outer().cal();
}
}

How to access outer class method local variable in local inner class?

public class MyClass {
int x=9;
public static void main(String args[]) {
MyClass myClass = new MyClass();
myClass.test();
}
public void test(){
int x=10;
class InnerClass{
int x = 11;
void print(){
int x = 12;
System.out.println(x);
System.out.println(this.x);
System.out.println(MyClass.this.x);
System.out.println("MyClass => test() => x :" + "?");
}
}
InnerClass innerClass = new InnerClass();
innerClass.print();
}
}
How to call MyClass test() method local variable x inside the InnerClass print() method. What i can write in place of ? in last System.out.println() method in order to get the value of test() x.
Unfortunately in Java you can't.
The only way to access the x in MyClass::test would be to rename both variables in your inner class and in your inner class method into something else.
There is no need though to rename the outer class field x as InnerClass::print would consider the variable in the most-inner scope.
Although this snippet is for demonstration purposes, better practice would have you have different and more significant names for each variable.
That works fine for me:
public class Outerclass {
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.outerMethod();
}
// method of the outer class
void outerMethod() {
int num = 23;
// method-local inner class
class MethodInnerClass {
public void print() {
System.out.println("This is method inner class "+num);
}
}
// Accessing the inner class
MethodInnerClass inner = new MethodInnerClass();
inner.print();
}
}
To print outer class variable use
MyClass.this.x

Visibility of inner class variables

I have a code-
public class Hello
{
void create()
{
Inner obj=new Inner();
obj.r=100; //Able to access private variable x
obj.display(); //displays 100
}
class Inner
{
private int r=45;
void display()
{
System.out.println("r is : "+r);
}
}
public static void main(String[] args)
{
Hello ob=new Hello();
ob.create();
}
}
In the above code,by creating an instance of the inner class,we are able to access the private variable defined in that class.But this is not in the case of inheritance.Why it is so?For e.g.,in this code-
class One
{
private int x;
void getData()
{
x=10;
}
void display()
{
System.out.println("x is : "+x);
}
}
class Two extends One
{
int y;
void putData()
{
One o=new One();
o.x=13; //Error
}
}
public class File
{
public static void main(String[] args)
{
Two to=new Two();
to.putData();
}
}
What is the exact reason behind it?Thanks in advance...
See the Java Language Specification.
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Meaning that a top-level class can access the private members of it's nested classes.
Or said another way: Private means private to the top-level class and all it's nested classes, not private to the nested class itself.

inner class and how to access them

I have the following code with a nested class called out1
class sample{
public int a=5;
class out1{
void main1(){
System.out.println("this is out1");
}
}
void call(){
//access main1() method on class out1
}
}
public class innerclass{
public static void main(String args[]){
sample ob=new sample();
System.out.println(ob.a);// access field a on class sample
//access call() on class sample
}
}
does anyone know on how to access inner class out1 and is it possible to access this inner class without using call() method on class sample?
You can create inner class out1 object as
ob.new out1();
This is my way how to access inner classes. I made a get method in class sample which returns an object of class out1:
public class innerclass {
public static void main(String args[]) {
sample ob = new sample();
ob.getOut1().call(); // calling the call() method in innerclass out1
}
}
class sample {
public int a = 5;
out1 getOut1() {
return new out1();
}
class out1 {
public void main1() {
System.out.println("this is out1");
}
public void call() {
main1();
}
}
}
And try to make classes with uppercase letter and also use camelcase like: Sample, InnerClass, Out1.
You can access the innerclass by new of outer.new of inner.
To call inner class method from outer class you need to create an object of the inner class.Otherwise you have to make the inner class as well as the method static.
class Sample{
public int a=5;
class Out1{
void main1(){
System.out.println("this is out1");
}
}
void call(){
new Out1().main1();
}
}
public class Innerclass{
public static void main(String args[]){
Sample ob=new Sample();
System.out.println(ob.a);// access field a on class sample
Sample.Out1 out1=new Sample().new Out1();
Out1.main1();
ob.call();
//access call() on class sample
}
}
And class names should start with capital letter by convention.
Inner classes can be static.
If you do not define your inner class as static, then you have to create an instance of it (an object) in order to use it.
Here is an example use case of static and member (non static) classes:
public class Tester {
public static void main() {
Outer outerTest = new Outer();
outerTest.test();
outerTest.publicInnerInstance.sayHello();
Outer.InnerStaticClass.sayHello();
}
}
class Outer{
class InnerMemberClass{
public void sayHello(){
System.out.println("Hello");
System.out.println("I'm an instance of 'InnerMemberClass'.");
}
}
static class InnerStaticClass{
public static void sayHello(){
System.out.println("Hello.");
System.out.println("I'm a static class 'InnerStaticClass'.");
}
}
public InnerMemberClass publicInnerInstance;
//'Outer' constructor
public void Outer(){
publicInnerInstance = new InnerMemberClass();
}
public void test(){
InnerStaticClass.sayHello();
InnerMemberClass instance = new InnerMemberClass();
instance.sayHello();
}
}

Categories