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).
Related
How do I access the property of a child class instead of the abstract class, when handling objects by their parent/abstract class? Like in this example:
public class WordCategories {
public static abstract class Noun {
public static final String TYPE = null;
//... and so on, methods
}
public static class Person extends Noun {
public static final String TYPE = "Person";
// ...
}
}
/* ... then we build a collection with members like: */
nouns.add(new WordCategories.Person("Bill Clinton");
/* now later we need to access a mixed list of nouns: */
for(WordCategories.Noun n: nouns) {
if(n.TYPE.equals("Person") ){ // this is always null
}
Obviously I could just specify (WordCategories.Person) n but that assumes that it is a Person. I need the cast to come from the parent class, and it would be most elegant if it did not involve interpreting the TYPE constant or the use of reflection, for that matter.
You don't have to use reflection at all. If you understand what type it is you like, you can use instanceof to get the specific class instance you care about.
for(WordCategories.Noun n: nouns) {
if(n instanceof WordCategories.Person) {
// cast to WordCategories.Person and perform whatever action you like
WordCategoriesPerson actualPerson = (WordCategories.Person) n;
}
}
This trumps the usage of the field to determine the object type, since the class contains enough metadata for you to want to use in this scenario. While many people would also discourage the use of instanceof due to performance (and frankly, if you wanted a list containing WordCategories.Person, just ask for one), its use in this instance would be cleaner than forcing each child class of WordCategories.Noun to create a method to inform us of what type it is.
static fields are always looked up by static type, so it doesn't matter what you assign to n; n.TYPE will always be WordCategories.Noun.TYPE. Heck, n could even be null:
System.out.println(((WordCategories.Noun) null).TYPE); // Doesn't cause an exception.
There is no way to get n.TYPE to behave the way you want with a static TYPE field. You will need to either make it non-static (and make all your objects bigger in the process), or you will need to change the way you access this data.
Instead of trying to access this through a static field, I recommend using an instance method:
public class WordCategories {
public static abstract class Noun {
public static final String TYPE = null;
public abstract String getType();
//... and so on, methods
}
public static class Person extends Noun {
public static final String TYPE = "Person";
public String getType() {
return TYPE;
}
// ...
}
}
...
for(WordCategories.Noun n: nouns) {
if(n.getType().equals("Person") ){
...
}
}
Try the test case:
public static void main(String[] args) {
Base sub1 = new Sub();
System.out.println(sub1.TYPE); // will print 'BASE'
Sub sub2 = new Sub();
System.out.println(sub2.TYPE); // will print 'SUB'
}
static class Base {
static String TYPE = "BASE";
}
static class Sub extends Base {
static String TYPE = "SUB";
}
If you access static field by the instance, it is decided by instance's declare Class, not the instance's real Class.
In your code for(WordCategories.Noun n: nouns) {, n's declare Class is Noun,so whatever n's real Class is,n.TYPE will only be null.
So, either use directly Class to access static fields, or use non-static field or method. Your usage is not wise, you should just take a different way.
Maybe you just need a non-static method:
public String getType() {
return TYPE;
}
I have some problems using this keyword. If I have a couple of classes implementing another class, how can I use their values without calling the class itself? I explain.
//this is my first class
public class Foo extends FooHelper{
public int fooInt;
public String fooString;
//getter/setter below
}
//this is my second class
public class Foo2 extends FooHelper{
public double fooDouble;
public float fooFloat;
}
//this is my main method, i'm using it for calling the value.
//I omit all the thrash code before.
//This is how i want to call the method:
//imagine before there are onCreate, activity,...
Foo foo = new Foo().GetFooInt();
//this is the class extended from the firsts
public class FooHelper{
public void GetFooInt(){
//here is my problem, i need to call the Foo class and the fooInt value.
//I want also to be able to edit the Foo object, for example:
if(((Foo)this).getFooInt() == 0){
(Foo) this.setFooInt(5);
}
}
}
This is what i want to achieve, acces a class which extends another class with the only this keyword from the extended class. How can I do it?
EDIT:
I badly explained i think.
My problem is that i want to access my Foo object inside the FooHelper, not FooHelper's method inside Foo object.
Example:
after using this code:
Foo foo = new Foo();
foo.HelperClassMethod();
I need (in HelperClass) to access Foo object which invoked it.
public HelperClass<Foo> {
public void HelperClassMethod(){
//HERE i need to use the "foo" object which invoked this method
}
}
I added the <Foo>, probably I was missing it, is this correct? and how can i use this foo object in the method from the helper class? thanks all
EDIT2: i totally failed on my question i thinkm lets ignore the above code and just check below:
I Have to access an object inside the extended class's method.
I have this class:
public class Foo extends FooToExtend{
public int fooInt;
}
the class which is extended is this:
public class FooToExtend{
public void MethodOne(){
//HERE i need to access the calling object
}
}
now, in my main activity, I want to do this:
Foo foo = new Foo();
foo.MethodOne();
My doubt is how i can access foo object i created in main inside my MethodOne.
I have to change my FooToExtend in
public class<Foo> FooToExtend{
...
}
but I don't still know how to access the foo object inside it.
I see 2 problems here, understanding this keyword, and extending clases
PROBLEMS WITH this KEYWORD
Imagine you have a class and you are executing some code: keyword this refers to the class itself, if you where the object this would be the equivalent to me. Check here and here longer explanations, examples and tutorials.
PROBLEMS WITH extend
Also you must extend from top (interfaces or abstract classes) to bottom (extended) classes and implement in bottom part:
//this is the PARENT (FIRST) class extended from the CHILDREN (SECOND)
public abstract class FooHelper{
public abstract void GetFooInt();
}
//this is the CHILD (SECOND!!!) class
public class Foo extends FooHelper{
public int fooInt;
public String fooString;
#Override
public void GetFooInt() {
// are you sure you getFooInt method can return a null???
if(this.getFooInt() == null){
this.setFooInt(5);
}
//getter/setter below
}
EDIT 1
Oh ok, this was useful. one more question, a way is to use abstract, as you said, but is there a way to do the same without implementing it all times? just for info, my objective is to use Foo.FooHelperMethod() and be able in "FooHelperMethod()" to access Foo class. I hope i explained it, i don't know how to do it.. if it's impossible i will use abstract as you suggested :)
Sure, this is inheritance, simply don't declare abstract the parent, and implement the methods AND the attributes there, all the children will have this methods and attributes by extending the parent class.
Lets see this example:
//this is the PARENT (FIRST) class extended from the CHILDREN (SECOND)
class FooHelper {
int theIntCommonValue;
public int getTheIntCommonValue() {
return theIntCommonValue;
}
public void setTheIntCommonValue(int theIntCommonValue) {
this.theIntCommonValue = theIntCommonValue;
}
}
// CHILDREN CLASS, look how calling this.getTheIntCommonValue() (the parent method)
// doesn't throw any error because is taking parent method implementation
class Foo extends FooHelper {
public void getFooInt() {
if (this.getTheIntCommonValue() == 0)
this.setTheIntCommonValue(5);
}
}
class Foo2 extends FooHelper {
public void getFooInt() {
if (this.getTheIntCommonValue() == 3)
this.setTheIntCommonValue(8);
}
}
EDIT2:
My doubt is how i can access foo object i created in main inside my MethodOne.
ANSWER:
Passing the object as a parameter. But then, you need static class, not an extended one, lets see an
EXAMPLE:
Foo.java
public class Foo {
public int fooInt;
}
FooHelper.java
public static class FooHelper {
public static void methodOne(Foo foo){
//HERE i need to access the calling object
// for example, this?
if (foo.fooInt == 2)
}
}
Now, how do you execute it?
Main.java
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
FooHelper.methodOne(foo);
}
NOTES
conventions say, methods in java start in LOWECASE and class name starts in UPPERCASE.
you must put both classes in sepparated files in order to allow static public class
I'm not sure I completely understand. But it looks as though you want GetFooInt to perform something differently depending on the class that extended it. So I think the best here to check the instanceof.
public class FooHelper{
public void GetFooInt(){
if(this instanceof Foo)
{
((Foo) this).fooInt = 5;
}
}
}
By the situation you want to named one class "Helper" I assume you will use it as a helper-class.
public class Helper {
public static int screenHeight = 500;
}
public class AnyOtherClass {
testSomething() {
System.out.println(Helper.screenHeight);
Helper.screenHeight = 510;
System.out.println(Helper.screenHeight);
}
}
For some basic understanding: this is the keyword you use in a non-static context to access the variables and methods of the Object you're currently inside. Proper use of this example:
public class SomeClass {
private int someInt;
public void setSomeInt(int someInt) {
this.someInt = someInt;
}
}
In this example the this is necessary because the local variable (/parameter) someInt has the same name as the global class variable someInt. With this you access the class varaible of the Object you're "in".
Example of unnecessary use of this:
public class SomeClass {
private int someInt;
public int squareSomeInt() {
return this.someInt * this.someInt;
}
}
Here you don't need the keyword this since there is no local variable called someInt.
On the other hand super is a keyword which accesses the variables and methods of the parent class (the class, your class is derrived from). Example:
public class SomeClass {
private int someInt;
public int squareSomeInt() {
return someInt * someInt;
}
}
the derrived class:
public class Other extends SomeClass {
public int squarePlusSquare() {
return super.squareSomeInt() + super.squareSomeInt();
}
}
I'm building a base/parent class in Java that's going to have several methods for creating the class itself and I'm wondering if there's any way to have the parent class return instances of the child class instead of returning instances of the parent class that then have to be cast to the child?
For example, here's my parent class:
public abstract class SFObject
{
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<SFObject> CreateListFromQuery(Connection connection, String query)
{
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
If I create a child class based on my SFObject class, the two functions in my child class will still return an SFObject (that needs to be cast to my child class type) or a list of SFObjects (that need to be individually cast to my child class type). Is there any way (maybe using Reflections) to have my child class returns instances of itself as itself and not as SFObjects?
What you are describing is known as a covariant return type.
Class A {
A getInstance() { ... }
}
Class B extends A {
#Override
B getInstance() { ... }
}
This has been allowed since Java 1.5.
If you place the child class object inside of the parent object, methods called will run from the child class. But it will look like the parent object on the surface
public class A{
method 1(){//do some stuff}
method 2(){//do some stuff}
}
public class B extends A{
method 1(){super.method 1()
//do some other stuff}
method 2(){super.method 2()
//do some other stuff}
}
public class test{
A a = new B();
//any method called on 'a' will come from the child class
// But 'a' is the parent object
}
Not sure if I really understand your Problem correct because it sounds to me lke this:
class p
{
public static p createParent()
{
return new p();
}
public static c createChild()
{
return new c();
}
}
Of course it doesn't have to be static, just thought of some kind of factory.
Exactly for this functionalities are proposed the factory methods, as you already implemented. In the child class you can change the return type without offending the method declaration. A sample for your case would be something like:
public abstract class SFObject {
// Variables
protected String mID;
protected String mName;
// Function called to create ourselves from a DiffObject
public abstract SFObject CreateFromDiffObject(DiffObject object);
// Function called to create a list of ourselves from a query
public List<? extends SFObject> CreateListFromQuery(Connection connection, String query) {
// Run the query and loop through the results
ArrayList<SFObject> objects = new ArrayList<SFObject>();
for (DiffObject object : connection.Query(query))
objects.add(CreateFromDiffObject(object));
return objects;
}
}
class SFObjectChild extends SFObject {
#Override
public SFObjectChild CreateFromDiffObject(DiffObject object) {
SFObjectChild result = new SFObjectChild();
//...
return result;
}
#Override
public List<? extends SFObjectChild> CreateListFromQuery(Connection connection,
String query) {
return null;//..;
}
}
This is acceptable because the return type of the children class is still a kind of (hierarchical speaking) the parent.
Be aware of java code conventions (methods in camel case starting with low, e.g. createFromDiffObject).
If we have class A & B, and class A's constructor is private, and we want to use an instance of A in B, how to do that ? I see an answer that says "provide a static method or variable that allows access to an instance created from within the class " but I didn't understand that.
The code pattern you seek is called the Factory Method.
The class provides a static method that returns an instance of its own class. Private constructors are visible to all methods (including static ones) of the class, so the static method can invoke the private constructor on the caller's behalf.
Here's an example of this pattern in action:
public class A {
private A() {
}
public static A create() {
return new A();
}
}
This is often employed in conjunction with the Singleton Pattern, which would change the above example to this:
public class A {
private static A INSTANCE = new A();
private A() {
}
public static A getInstance() {
return INSTANCE;
}
}
A needs to have a public method that provides an instance of the class A, eg:
class A {
/*Constructors and other methods omitted*/
public static A getInstance() {
return new A();
}
}
Alternatively, if B is an inner class of A (or vice-versa), then B can directly reference the constructor eg:
public class A {
private A() {}
public static class B {
private A instanceOfA = new A();
public B() {}
}
}
A class that only has private constructors is designed so that other classes cannot instantiate it directly. Presumably there is a sound reason for this. The class may provide a factory method for instantiating the class ... or getting an existing instance of the class.
If you need to change the design, the best way is to modify the class; e.g. by making a constructor visible, or by adding a factory method. If you can't do that, I think it is possible to use reflection to break the visibility rules and create an instance using a private constructor. However, I'd only do this as a last resort ... and not before carefully analysing the consequences for the overall application.
Private constructors are intended to make a class not to have any instance. But the content can be accessed from child class using super(). Implementation is like this:
public class ClassA {
private int val;
private ClassA(int val)
{
this.val = val;
}
public int getVal() {
return val;
}
}
public class ClassB extends ClassA {
public ClassB(int val) {
super(val); } }
...
ClassB b = new ClassB(4);
System.out.println("value of b: " + b.getVal());
As an example see class Calendar. To get an instance you must not call its constructor but use a static method:
Calendar rightNow = Calendar.getInstance();
source
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Implement a final class without the “final” keyword
I want to create an immutable class in Java without using the final keyword.
I think smt like should work fine
class Immutable {
private int i;
public static Immutable create(int i){
return new Immutable(i);
}
private Immutable(int i){this.i = i;}
public int getI(){return i;}
}
But final is preferable.
The final keyword won't make your class inmutable. It will avoid your class to be extended from another class.
public final class Foo {
//....
}
public class Bar extends Foo {
//COMPILATION ERROR!
}
An adecuated class design is what will make you class inmutable, as you can see at duffymo answer.
Note that you can declare as final the fields that you will initialize at the constructor:
class Foo {
private final int state
public Foo(int v) {
this.state=v;
}
//....
}
The difference is that, while at duffymo example, the value ccould be changed from inner routines (i.e, a method adds one to the value, kind of a counter), at my example you wouldn't be able to do so.
Let's try to avoid absolutely the use of the final keyword:
public class Foo {
private int state;
private Foo(int v) {
this.state=v;
}
public static Foo getInstance(int value) {
return new Foo(value);
}
}
You only can get an instance of Foo accesing the Foo.getInstance method.
But anyway, you can extend the Foo class and make it mutable
I was wrong here. I won't compile, as you can acceess the Foo constructor.
public class Bar extends Foo {
private int ohNopes;
//COMPILATION ERROR!
public Bar(int v) {
this.ohNopes=v;
}
}
So, it seems it can be done, after all.
The problem with an immutable class not being final is that, subclasses may not be immutable.
Here is an example from the Java API, java.lang.String is immutable and final, if a string is passed to one of your methods you can be sure that it will remain in a consistent state.
the following will not compile because String is final:
public class MyString extends java.Lang.String {
public MyString(String original) {
Super(original);
}
#Override
public String toString() {
return String.valueOf(System.currentTimeMillis());
}
On the other hand, java.ma.BigDecimal itself is immutable, but it is not final and allowed to be subclassed. This opens up a range of issues. If a BigDecimal is passes to one of your methods you can't rely on the fact that no one has overridden BigDecimal like you can with String. subclasses of BigDecimal could potentially replace its methods with others which give unpredictable results.
The following will compile because BigDecimal is not immutable:
public class MyBigDecimal extends java.math.BigDecimal {
public MyBigDecimal(double val) {
super(val);
}
private int count = 0;
// override intValue which changes the state of this instance
#Override
public int intValue() {
return count++;
}
// rinse and repeat for the rest of the BigDecimal methods...
}
You cannot rely on he state of BigDecimal instances passed into your code, you should make Defensive copies of non final classes if you need to rely on their immutability.
I can't imagine why you object to using final, but here's a class that will get the job done. I know there are subtleties regarding serialization and reflection, but this can't be changed without special shenanigans:
public class Immutable
{
private int value;
public Immutable(int v)
{
this.value = v;
}
public int getValue() { return this.value; }
}
The class should set all its values in the constructor, and provide no setters (methods that modify class members).
You can create a class then create a .jar and use the jar as resource.