Anonymous inner classes in Java - java

Got some incomprehensible exercise in my book.
"Create a class with a non-default constructor (one with arguments) and no default constructor (no "no-arg" constructor). Create a second class that has a method that returns a reference to an object of the first class. Create the object that you return by making an anonymous inner class that inherits from the first class."
Can anyone come out with a source code?
Edit:
I don't understand what the final source code should look like. And I came with this one:
class FirstClass
{
void FirstClass( String str )
{
print( "NonDefaultConstructorClass.constructor(\"" + str + "\")" );
}
}
class SecondClass
{
FirstClass method( String str )
{
return new FirstClass( )
{
{
print( "InnerAnonymousClass.constructor();" );
}
};
}
}
public class task_7
{
public static void main( String[] args )
{
SecondClass scInstance = new SecondClass( );
FirstClass fcinstance = scInstance.method( "Ta ta ta" );
}
}

Honestly, the exercise is quite concise unless you do not know or understand the definition of an inner class. You can find an example of an anonymous inner class here:
http://c2.com/cgi/wiki?AnonymousInnerClass
Otherwise, this concise example illustrates the problem:
/** Class with a non-default constructor and no-default constructor. */
public class A {
private int value;
/** No-arg constructor */
public A() {
this.value = 0;
}
/** Non-default constructor */
public A(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
/** Class that has a method that returns a reference to A using an anonymous inner class that inherits from A. */
public class B {
public B() { ; }
/** Returns reference of class A using anonymous inner class inheriting from A */
public A getReference() {
return new A(5) {
public int getValue() {
return super.getValue() * 2;
}
};
}
}

Related

Can outclass specify inner class with InnerClassNameOuter directly rather than ClassName.InnerClassName

In Inner classes of Thinking In Java,
If you want to make an object of the inner class anywhere except from
within a non-static method of the outer class, you must specify the
type of that object as OuterClassName.InnerClassName, as seen in
main().
But I find use InnerClassName directly still works in main.
public class Parcel2 {
class Contents {
private int i = 42;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo){
label = whereTo;
}
String readLabel(){ return label; }
}
public Destination to(String s){
return new Destination(s);
}
public static void main(String[] args){
Parcel2 q = new Parcel2();
/* Destionation d = q.to("Borneo"); still works.*/
Parcel2.Destination d = q.to("Borneo");
}
}

Need to initialize a static final field in the subclasses

I asked a question, but it was very dirty, and a lot of people didn't understand. So, I need to declare a final static field, that is only going to be initialized in the subclasses. I'll show an example:
public class Job {
public static final String NAME;
}
public class Medic extends Job {
static {
NAME = "Medic";
}
}
public class Gardener extends Job {
static {
NAME = "Gardener";
}
}
Something like this. I know this code is not going to work, since the NAME field in the Job class needs to be initialized. What i want to do is to initialize that field individually in each subclass (Medic, Gardener).
You need this
public enum Job {
MEDIC(0),
GARDENER(1);
/**
* get identifier value of this enum
*/
private final byte value;
private Job(byte value) {
this.value = value;
}
/**
* get identifier value of this enum
* #return <i>int</i>
*/
public int getValue() {
return this.value;
}
/**
* get enum which have value equals input string value
* #param value <i>String</i>
* #return <i>Job</i>
*/
public static Job getEnum(String value) {
try {
byte b = Byte.parseByte(value);
for (Job c : Job.values()) {
if (c.getValue() == b) {
return c;
}
}
throw new Exception("Job does not exists!");
} catch (NumberFormatException nfEx) {
throw new Exception("Job does not exists!");
}
}
/**
* get name of this job
*/
public String getName() {
switch (this) {
case MEDIC:
return "Medic";
case GARDENER:
return "Gardener";
default:
throw new NotSupportedException();
}
}
}
Why not declare an abstract method in the base class?
public abstract class Job {
public abstract String getJobName();
}
Then you can return individual names in each implementation:
public class Medic extends Job {
#Override
public String getJobName() {
return "Medic";
}
}
public class Gardener extends Job {
#Override
public String getJobName() {
return "Gardener";
}
}
It does not make a lot of sense to have a final static field.
You cannot do this. The static field has the only once instance per class where it's declared. As both Medic and Gardener share the same Job superclass, they also share the same NAME static field. Thus you cannot assign it twice.
You cannot assign it even once in subclass as it's possible that Job class is already loaded and initialized, but no subclasses are loaded yet. However after class initialization all the static final fields are required to be initialized.

How to read and write to variables of an abstract class

Put simply, I have an abstract class containing several variables and methods. Other classes extend this abstract class, yet when I try to read the private variable in the abstract class by calling getter methods inside the abstract class, it returns null as the value of the variable.
public class JavaApplication {
public static void main(String[] args) {
NewClass1 n1 = new NewClass1();
NewClass2 n2 = new NewClass2();
n1.setVar("hello");
n2.print();
}
}
public class NewClass1 {
public String firstWord;
public void setVar(String var) {
firstWord = var;
}
public String getVar () {
return firstWord;
}
}
public class NewClass2 extends NewClass1{
public void print() {
System.out.println(makeCall());
}
public String makeCall() {
return getVar();
}
}
Still prints out null.
Until the String is initialized, it will be null. You should probably have a constructor in the abstract class to set it.
public abstract class Command
{
String firstWord; // = null
protected Command(){}
protected Command( String w )
{
firstWord = w;
}
//...
}
public class Open extends Command
{
public Open()
{
this( "your text" );
}
public Open( String w )
{
super( w );
}
// ...
}
If you need to modify the firstWord string everytime execute() is called then it may not be necessary to use a constructor with a String parameter (I added a default constructor above). However, if you do it this way then either
You must make sure setFirstWord() is called before getFirstWord(), or,
Handle the case when getFirstWord() returns null. This could be by simply using a default value (maybe determined by each subclass) or something else, like failing to execute.
As I do not know all the details of your implementation I cannot tell you further information.

List<Structure> in java

How I can instantiate a object in the List e.g
i like to search for begin in the file , if it finds then add the store the code after it. here is the example
public abstract class Structure
{
private List<Structure> structureList = new ArrayList<Structure>();
protected void setStructure(Filemanager file, String line)
{
/*
* set all values at the object structure
*/
line = file.getSourceLine();
while (!line.contains("END_"))
{
if (line.contains("TRANSLATE"))
{
}
else if (line.contains("BEGIN_OBJECT"))
{
structureList.add(new FunctionalStructure(line));
}
else
{
setValue(line);
}
line = file.getSourceLine();
}
}
protected abstract void setValue(String line);
}
public abstract class FunctionalStructure extends Structure
{
private String name;
public FunctionalStructure(String line)
{
super();
this.name = line.substring(line.indexOf("\"")+1, line.lastIndexOf("\""));
}
public String getName()
{
return this.name;
}
public List<Structure> Startfunctional()
{
return null;
}
protected abstract void setValue(String line);
}
I have problem in in instantiate structureList.add(new FunctionalStructure(line));
Can anyone please tell what is wrong in the above line
I think that FunctionalStructure must be an abstract class (which presumably extends Structure). You cannot instantiate an abstract class.
This is why you get the error like:
Cannot instantiate the type FunctionalStructure
If you created the FunctionalStructure class, perhaps you accidentally marked it as abstract. Assuming it implements the setValue(String) method, you could remove the abstract modifier from the class declaration.
Alternatively, use a suitable concrete class extending FunctionalStructure in the API you are using.
Alternatively, use an anonymous inner class:
structureList.add(new FunctionalStructure(line){
public void setValue(String value) {
// your implementation here
}
});
you might find example below helpful to understand the concept :-
package pack;
public class Demo {
public static void main(String[] args) {
MyGeneric<A> obj = new MyGeneric<A>() ;
//obj.add(new C()) ; //don't compile
obj.testMethod(new A()) ; //fine
obj.testMethod(new B()) ; //fine
}
}
class A{}
class C{}
class B extends A{}
class MyGeneric<T>{
public void testMethod(T t) {
}
}
EDIT : So, there must be a IS-A relation between Structure and FunctionalStructure to successfully compile the code.

Don’t call subclass methods from a superclass constructor

Consider the following code
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package example0;
/**
*
* #author yccheok
*/
public class Main {
static class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public String getVar() {
return "String from A";
}
}
static class B extends A {
private final String bString;
// Before B ever constructed, A constructor will be called.
// A is invoking a overriden getVar, which is trying to return
// an initialized bString.
public B() {
bString = "String from B";
}
#Override
public String getVar() {
return bString;
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
B b = new B();
}
}
Currently, in my mind, there are two ways to avoid such problem.
Either making class A final class.
static final class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public String getVar() {
return "String from A";
}
}
Or
Making getVar method final
static class A {
private final String var;
public A() {
var = getVar();
// Null Pointer Exception.
System.out.println("var string length is " + var.length());
}
public final String getVar() {
return "String from A";
}
}
The author trying to suggest ways to prevent the above problem. However, the solution seems cumbersome as there are some rules to be followed.
http://benpryor.com/blog/2008/01/02/dont-call-subclass-methods-from-a-superclass-constructor/
Beside making final and the author suggested way, is there more ways to prevent the above problem (Don’t call subclass methods from a superclass constructor) from happen?
Making getVar method final
This is definitely what you need to do.
If you're relaying on the functionality of a method to initialize an object, you shouldn't let subclasses broke that method.
Answering your question, other way to prevent it is to make getVar private in A.
See this simplified version of your code:
// A.java
class A {
private final String var;
public A(){
var = getVar();
var.length();
}
private String getVar(){
return "This is the value";
}
}
class B extends A {
private final String other;
public B(){
other = "Other string";
}
public String getVar(){
return other;
}
}
class Main{
public static void main( String [] args ) {
new B();
}
}
BTW, why did you put those as static nested classes, just to create confusion?

Categories

Resources