I cannot understand how Anonymous Inner Class Fields work [duplicate] - java

I want to define my property and function in anonymous class as under
ExistingExtendableJavaClass aClass = new ExistingExtendableJavaClass() {
public String someProperty;
public String getMyProperty() { return someProperty }
});
But then these calls don't work
aClass.someProperty // not accessible
aClass.getMyProperty() // not accessible
I know because ExistingExtendableJavaClass doesn't have these, but then my anonymous has these. How can I achieve this ?

They are accessible just fine:
new ExistingExtendable() {
public void foo() {}
}.foo();
works great.
But if you write:
ExistingExtendable x = new ExistingExtendable() {
public void foo() {}
};
x.foo();
That does not work. For the same reason this doesn't work:
Object o = new String();
o.toLowerCase(); // nope
The problem is that your anonymous class has no name, thus, you cannot denote its type. We can fix the string example by replacing Object o with String o, but there is no String equivalent.
However, that is the point of an anonymous inner class.
If you want these to be denotable, then you don't want an anonymous inner class. Asking: "I want an anonymous inner class, but I want the new members I declared in them to be accessible" is like asking: "I want a circle, but.. with corners".
You can make method local inner classes, and now you have names:
public void example(String x) {
class IAmAMethodLocalClass extends ExistingExtendableJavaClass {
String someProperty; // making them public is quite useless.
String foo() {
System.out.println(x); // you can access x here.
}
}
IAmAMethodLocalClass hello = new IAmAMethodLocalClass();
hello.someProperty = "It works!";
}
an anonymous inner class is the same as this method local class thing, except it avoids naming the type. In this case, you NEED that name, thus, you can't use the anonymous inner class construct.

Related

Defining custom function/property inside anonymous class

I want to define my property and function in anonymous class as under
ExistingExtendableJavaClass aClass = new ExistingExtendableJavaClass() {
public String someProperty;
public String getMyProperty() { return someProperty }
});
But then these calls don't work
aClass.someProperty // not accessible
aClass.getMyProperty() // not accessible
I know because ExistingExtendableJavaClass doesn't have these, but then my anonymous has these. How can I achieve this ?
They are accessible just fine:
new ExistingExtendable() {
public void foo() {}
}.foo();
works great.
But if you write:
ExistingExtendable x = new ExistingExtendable() {
public void foo() {}
};
x.foo();
That does not work. For the same reason this doesn't work:
Object o = new String();
o.toLowerCase(); // nope
The problem is that your anonymous class has no name, thus, you cannot denote its type. We can fix the string example by replacing Object o with String o, but there is no String equivalent.
However, that is the point of an anonymous inner class.
If you want these to be denotable, then you don't want an anonymous inner class. Asking: "I want an anonymous inner class, but I want the new members I declared in them to be accessible" is like asking: "I want a circle, but.. with corners".
You can make method local inner classes, and now you have names:
public void example(String x) {
class IAmAMethodLocalClass extends ExistingExtendableJavaClass {
String someProperty; // making them public is quite useless.
String foo() {
System.out.println(x); // you can access x here.
}
}
IAmAMethodLocalClass hello = new IAmAMethodLocalClass();
hello.someProperty = "It works!";
}
an anonymous inner class is the same as this method local class thing, except it avoids naming the type. In this case, you NEED that name, thus, you can't use the anonymous inner class construct.

I've got trouble with inner and static inner class at java

Firstly, Thanks everybody that read that topic.
How can if statement become true in test class? I couldnt find any solution.I couldnt write any code in these method.I tried to send from Room class numberOfTiger to class Question's method but I didnt achieve that.
That's question about ,How can I change int variable(numberofTiger) to Cat.Tiger variable.After that if statement become true to invoke (getNumberOfTiger) method.
public class Test {
public static void main(String[] args) {
Animal an = new Animal();
Animal.Cat an1 = an.new Cat();
Animal.Cat.Tiger an2 = an1.new Tiger(3, 900, 2);
if (Animal.Question.getnumberOfTiger(an2) == 3) {
System.out.println("True");
}
}
}
public class Animal {
Cat[] c;
// inner class
class Cat {
Tiger[] t;
// inner class
class Tiger {
private int numberOfTiger;
private int averageOfTigerWeigth;
private int youngTiger;
public Tiger(int numberOfTiger, int averageOfTigerWeigth, int youngTiger) {
super();
this.numberOfTiger = numberOfTiger;
this.averageOfTigerWeigth = averageOfTigerWeigth;
this.youngTiger = youngTiger;
}
static class Question {
static int getnumberOfTiger(Cat.Tiger a) {
return 0;
}
}
}
In addition to either making Cat a static class, or using its instance,
you also need a getter for a.numberOfTiger since it is private, in Tiger class:
public getNumberOfTiger() {
return numberOfTiger;
}
Then:
return a.getNumberOfTiger();
In getNumberOfTiger() you need to return the number of tigers associated with that object. You are currently just returning 0, so it will always evaluate to false.
I see the issue. The Tiger class and the Cat class needs to be static. The reason is, a non-static inner class can call on its outer class (e.g. Cat.this.something). A non-static inner type is called like this:
instanceOfOuterClass.innerClass
whereas a static inner type is called like this:
outerClassName.innerClass
The simplest way to call on a non-static inner type is new Outer().new Inner(); The main issue with beginners in Java is that they try to do this:
new (new Outer()).Inner()
But the actual way to call it is
new Outer().new Inner()
Also, your method is always returning 0 for the count of tigers.

Is it possible to instantiate a class and assign it to a member variable in a single statement in Java?

I'm looking to do something like this in Java:
public OuterClass {
public innerClass = new Object() {
private var1;
public void myMethod() {
...
}
}
}
and use it like this:
OuterClass outer = new OuterClass();
outer.innerClass.myMethod();
The reason is to basiclly namespace some methods within the OuterClass to keep things organised.
I know I could create an instance of innerClass and assign it to a public instance variable of OuterClass but I'm looking for an inline way of doing it like above example. I don't want it to be possible to instantiate the innerClass more than once hence the inline approach.
This woule be similar to the following JavaScript:
var innerObject = new function() {
...
}
What you asked in the question title is possible, but unfortunately not what you really want.
In your code, the line with the declaration of the field innerClass misses a type for the field. With the rest of the code unchanged, there is only one possibility: Object.
So your code would read like this:
public OuterClass {
public Object innerClass = new Object() {
private var1;
public void myMethod() {
...
}
}
}
This is actually possible, but calling the method myMethod is not possible. When you access outer.innerClass, this expression is of type Object, which does not have a method myMethod, so the code won't compile.
You can however introduce an interface MyInnerInterface
interface MyInnerInterface {
void myMethod();
}
and change the type of the field to MyInnerInterface:
public OuterClass {
public MyInnerInterface innerClass = new MyInnerInterface() {
private var1;
public void myMethod() {
...
}
}
}
Then accessing the method is possible. However you have the drawback of the additional interface.
Also this code is unusual and I wouldn't consider it good. If you really want to have an inner class here, don't use an anonymous class, but a real class:
public OuterClass {
public class InnerClass {
private var1;
public void myMethod() {
...
}
}
public InnerClass innerClass = new InnerClass();
}
Still, using an inner class for "scoping" accesses from the outside is something I wouldn't do. Inner classes should usually be an implementing detail of the outer class and not be accessible to the public. Better think about how to separate your API into real co-existing classes (which of course might have references onto each other, and possibly access package-private members).
Have you tried:
public class OuterClass {
public static void main(String[] args) {
OuterClass o = new OuterClass();
o.new InnerClass().method();
}
class InnerClass {
public void method() {
//do something
}
}
}
That uses the syntax you propose, but does not address your requirement that you don't want more than one instance of InnerClass.

Usage of inner class

I can understand what inner class is and how to write program. My question is in what situation do programmers really need inner class?
Sometimes there is some functionality which is best represented as an object, but which is only meaningful within the context of another object, which does not necessarily need to be exposed to the outside world, and which can benefit from having access to the parent classes data (so as to not violate encapsulation).
The best example that I can think of is putting a Node class inside of a LinkedList. Nodes are only meaningful to the LinkedList, so they only exist within one. No one outside of the LinkedList cares about nodes or should have access to them.
An inner class allows us to remove that logic and place it into its own class. So from an object-oriented point of view, we've taken functionality out of where it doesn't belong and have put it into its own class.
Please go through this link....
http://www.javaworld.com/javaworld/javaqa/2000-03/02-qa-innerclass.html
Also as you know in Java exists nested classes, which is static inner clasess.
From previous posts becomes clear when we need to use an inner class but I think you also interested in the question "Why we need nested classes (static inner class)".
The answer is simply, there is the same purpose as for the inner class except few things.
1) The nested class (static inner) is required when we whant to exclude some logic that concerns another object but this logic might be used in outworld.
The simpliest examples is a builders or editors of some object. For example we have class Foo
which may have a lot of optional fields, to construct such object we may decide to introduce a builder class which will do this work.
public class Foo {
private int param1;
private int param2;
private int param3;
private Foo(FooBuilder builder) {
this.param1 = builder.param1;
this.param2 = builder.param2;
this.param3 = builder.param3;
}
public int getParam1() {
return param1;
}
public void setParam1(int param1) {
this.param1 = param1;
}
public int getParam2() {
return param2;
}
public void setParam2(int param2) {
this.param2 = param2;
}
public int getParam3() {
return param3;
}
public void setParam3(int param3) {
this.param3 = param3;
}
public static class FooBuilder {
private int param1;
private int param2;
private int param3;
public FooBuilder() {
}
public FooBuilder withParameter1(int param1) {
this.param1 = param1;
return this;
}
public FooBuilder withParameter2(int param2) {
this.param2 = param2;
return this;
}
public FooBuilder withParameter3(int param3) {
this.param3 = param3;
return this;
}
public Foo build() {
return new Foo(this);
}
}
}
This example illustrates at leas one reason why we need such classes
2) The second difference between inner and static inner classes is that the first one always has pointer to the parent class. Actully compiler creates synthetic field member for the non static inner class of the type of it's parent, exectly of this reason we can access private members of the parent class. The static inner clasess doesn't has such generated field member. For instance we has just simple parent class with declared non static inner class:
public class Foo {
public class FooBuilder {
}
}
but in fact if take into account the byte code it looks like:
public class Foo {
public class FooBuilder {
private Foo generatedNameHere;
}
}
if you want you can figure out this throught generated byte code.
One of the use of inner class is :
Inner class helps in multiple-inheritance. Inner class allows you to inherit from more than one non-interface.
//first case; can implement if two classes are interface
interface A { }
interface B { }
class X implements A, B { }
//second case; you can extend only one class. This case inner class can help to inherit other class as well
class D { }
abstract class E { }
class Z extends D {
void method() {
return new E() { }; //Anonymous inner class
}
}
When you want to specify a class that has sence only in context with the bounded one.
For example you write a MathOperations class that can execute four operations. So the operations can be represented as inner enum MathOps.
When the inner class is not used anywhere except the inbounded one.
You use anonymous inner classes to specify only the operation, for exmple if you want to sort a collection, you specify a Comparable class just for one method compare.
Collections.sort(employments, new Comparator<Employment>() {
#Override
public int compare(Employment o1, Employment o2) {
return o1.getStartDate().before(o2.getStartDate()) ? 1 : -1 ;
}
});
With inner classes you can access private members of the enclosing class.
They are useful for interface implementations that are only used by the enclosing class (event handlers in a application).
They are useful for providing fine grained access and creation control over an interface implementation that is retrieved externally (maybe something like an Iterator implementation).

Why does Java code with an inner class generates a third SomeClass$1.class file? [duplicate]

This question already has answers here:
Why is an anonymous inner class containing nothing generated from this code?
(5 answers)
Closed last year.
If I have an inner class, like this:
public class Test
{
public class Inner
{
// code ...
}
public static void main(String[] args)
{
// code ...
}
}
When I compile it, I expect it should generate two files:
Test.class
Test$Inner.class
So why do I sometimes see classfiles like SomeClass$1.class, even though SomeClass does not contain an inner class called "1"?
The SomeClass$1.class represent anonymous inner class
hava a look at the anonymous inner class section here
You'll also get something like SomeClass$1.class if your class contains a private inner class (not anonymous) but you instantiate it at some point in the parent class.
For example:
public class Person {
private class Brain{
void ponderLife() {
System.out.println("The meaning of life is...");
}
}
Person() {
Brain b = new Brain();
b.ponderLife();
}
}
This would yield:
Person.class
Person$Brain.class
Person$1.class
Personally I think that's a bit easier to read than a typical anonymous class especially when implementing a simple interface or an abstract class that only serves to be passed into another local object.
to build up on hhafez : SomeClass$1.class represents anonymous inner classes.
An example of such a class would be
public class Foo{
public void printMe(){
System.out.println("redefine me!");
}
}
public class Bar {
public void printMe() {
Foo f = new Foo() {
public void printMe() {
System.out.println("defined");
}
};
f.printMe();
}
}
From a normal Main, if you called new Bar().printMe it would print "defined" and in the compilation directory you will find Bar1.class
this section in the above code :
Foo f = new Foo() {
public void printMe() {
System.out.println("defined");
}
};
is called an anonymous inner class.

Categories