Lets say I have a concrete class Class1 and I am creating an anonymous class out of it.
Object a = new Class1(){
void someNewMethod(){
}
};
Now is there any way I could overload the constructor of this anonymous class. Like shown below
Object a = new Class1(){
void someNewMethod(){
}
public XXXXXXXX(int a){
super();
System.out.println(a);
}
};
With something at xxxxxxxx to name the constructor?
From the Java Language Specification, section 15.9.5.1:
An anonymous class cannot have an
explicitly declared constructor.
Sorry :(
EDIT: As an alternative, you can create some final local variables, and/or include an instance initializer in the anonymous class. For example:
public class Test {
public static void main(String[] args) throws Exception {
final int fakeConstructorArg = 10;
Object a = new Object() {
{
System.out.println("arg = " + fakeConstructorArg);
}
};
}
}
It's grotty, but it might just help you. Alternatively, use a proper nested class :)
That is not possible, but you can add an anonymous initializer like this:
final int anInt = ...;
Object a = new Class1()
{
{
System.out.println(anInt);
}
void someNewMethod() {
}
};
Don't forget final on declarations of local variables or parameters used by the anonymous class, as i did it for anInt.
Here's another way around the problem:
public class Test{
public static final void main(String...args){
new Thread(){
private String message = null;
Thread initialise(String message){
this.message = message;
return this;
}
public void run(){
System.out.println(message);
}
}.initialise(args[0]).start();
}
}
I know the thread is too old to post an answer. But still i think it is worth it.
Though you can't have an explicit constructor, if your intention is to call a, possibly protected, constructor of the super class, then the following is all you have to do.
StoredProcedure sp = new StoredProcedure(datasource, spName) {
{// init code if there are any}
};
This is an example of creating a StoredProcedure object in Spring by passing a DataSource and a String object.
So the Bottom line is, if you want to create an anonymous class and want to call the super class constructor then create the anonymous class with a signature matching the super class constructor.
Yes , It is right that you can not define construct in an Anonymous class but it doesn't mean that anonymous class don't have constructor. Confuse...
Actually you can not define construct in an Anonymous class but compiler generates an constructor for it with the same signature as its parent constructor called. If the parent has more than one constructor, the anonymous will have one and only one constructor
You can have a constructor in the abstract class that accepts the init parameters. The Java spec only specifies that the anonymous class, which is the offspring of the (optionally) abstract class or implementation of an interface, can not have a constructor by her own right.
The following is absolutely legal and possible:
static abstract class Q{
int z;
Q(int z){ this.z=z;}
void h(){
Q me = new Q(1) {
};
}
}
If you have the possibility to write the abstract class yourself, put such a constructor there and use fluent API where there is no better solution. You can this way override the constructor of your original class creating an named sibling class with a constructor with parameters and use that to instantiate your anonymous class.
If you dont need to pass arguments, then initializer code is enough, but if you need to pass arguments from a contrcutor there is a way to solve most of the cases:
Boolean var= new anonymousClass(){
private String myVar; //String for example
#Overriden public Boolean method(int i){
//use myVar and i
}
public String setVar(String var){myVar=var; return this;} //Returns self instane
}.setVar("Hello").method(3);
Peter Norvig's The Java IAQ: Infrequently Answered Questions
http://norvig.com/java-iaq.html#constructors - Anonymous class contructors
http://norvig.com/java-iaq.html#init - Construtors and initialization
Summing, you can construct something like this..
public class ResultsBuilder {
Set<Result> errors;
Set<Result> warnings;
...
public Results<E> build() {
return new Results<E>() {
private Result[] errorsView;
private Result[] warningsView;
{
errorsView = ResultsBuilder.this.getErrors();
warningsView = ResultsBuilder.this.getWarnings();
}
public Result[] getErrors() {
return errorsView;
}
public Result[] getWarnings() {
return warningsView;
}
};
}
public Result[] getErrors() {
return !isEmpty(this.errors) ? errors.toArray(new Result[0]) : null;
}
public Result[] getWarnings() {
return !isEmpty(this.warnings) ? warnings.toArray(new Result[0]) : null;
}
}
It doesn't make any sense to have a named overloaded constructor in an anonymous class, as there would be no way to call it, anyway.
Depending on what you are actually trying to do, just accessing a final local variable declared outside the class, or using an instance initializer as shown by Arne, might be the best solution.
In my case, a local class (with custom constructor) worked as an anonymous class:
Object a = getClass1(x);
public Class1 getClass1(int x) {
class Class2 implements Class1 {
void someNewMethod(){
}
public Class2(int a){
super();
System.out.println(a);
}
}
Class1 c = new Class2(x);
return c;
}
Related
I wrote this simple class in java just for testing some of its features.
public class class1 {
public static Integer value=0;
public class1() {
da();
}
public int da() {
class1.value=class1.value+1;
return 5;
}
public static void main(String[] args) {
class1 h = new class1();
class1 h2 = new class1();
System.out.println(class1.value);
}
}
The output is:
2
But in this code:
public class class1 {
public static Integer value=0;
public void class1() {
da();
}
public int da() {
class1.value=class1.value+1;
return 5;
}
public static void main(String[] args) {
class1 h = new class1();
class1 h2 = new class1();
System.out.println(class1.value);
}
}
The output of this code is:
0
So why doesn't, when I use void in the constructor method declaration, the static field of the class doesn't change any more?
In Java, the constructor is not a method. It only has the name of the class and a specific visibility. If it declares that returns something, then it is not a constructor, not even if it declares that returns a void. Note the difference here:
public class SomeClass {
public SomeClass() {
//constructor
}
public void SomeClass() {
//a method, NOT a constructor
}
}
Also, if a class doesn't define a constructor, then the compiler will automatically add a default constructor for you.
public void class1() is not a constructor, it is a void method whose name happens to match the class name. It is never called. Instead java creates a default constructor (since you have not created one), which does nothing.
Using void in the constructor by definition leads it to not longer be the constructor.
The constructor specifically has no return type. While void doesn't return a value in the strictest sense of the word, it is still considered a return type.
In the second example (where you use the void), you would have to do h.class1() for the method to get called because it is no longer the constructor. Or you could just remove the void.
This is arguably a design flaw in Java.
class MyClass {
// this is a constructor
MyClass() {...}
// this is an instance method
void MyClass() {...}
}
Perfectly legal. Probably shouldn't be, but is.
In your example, class1() is never getting called, because it's not a constructor. Instead, the default constructor is getting called.
Suggestion: familiarize yourself with Java naming conventions. Class names should start with uppercase.
The reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the run time.
Here is an article explaining this in greater detail:
https://www.quora.com/Why-is-the-return-type-of-constructor-not-void-while-the-return-type-of-a-function-can-be-void
I am a newbie. So, I couldn't find the exact words to explain what I want to do. I will try to explain.
I created a class that extends some base class. In the base class I have some methods using the object specific information to run. I mean that we defined with a constructor.
So, in the class that extends my base class, I created a constructor with super, can I call some base class method in constructor in order to run automatically after object creation.
Like that:
class Base {
String someInfo;
Base(String someInfo) {
this.someInfo = someInfo;
}
String someMethod() {
return someInfo;
}
}
class MClass extends Base {
MClass(String someInfo) {
super(someInfo);
someMethod();
}
}
Your question is more about theory, not practice.
In practice - you can. But you shouldn't do such things. It's about code smell and possibility for hard-to-find bugs. Look at this sample
class Base {
private final String t;
private final int length;
Base(String t) {
this.t = t;
length = this.t.length();// here you'll got NullPointerException
}
}
class Override {
Override() {
super(calculate());
}
String calculate() {
return "Override";
}
}
class OverrideB {
private final String b = "some string";
OverrideB() {
}
String calculate() {
return b;
}
}
In current sample when you'll try to create OverrideB instance you'll got NullPointerException - because b isn't instantiated at current moment (you can check it by yourself - it is about order of constructors calls).
But you have to options to avoid this problem:
private methods (they cannot be overridden, only hidden in sub classes)
final methods (same case as for private, but they can't be even hidden and they available for all subclasses)
PS according to class names conventions you should name your mClass as MClass.
A static method belongs to the class rather than object of a class.
A static method can be invoked without the need for creating an instance of a class. What does it mean?
It means that, rather than needing to create a new instance from the class and then calling the function like:
Foo f = new Foo();
f.bar();
you can instead access it directly from the class like:
Foo.bar();
That obviously means that you can't use any non-static field or method of the object from a static method, of course.
ClassObject classObj = new ClassObject();
classObj.doSomething();
vs.
ExampleClass.staticMethod();
First one needs an instance of ClassObject to call doSomething(). The second one doesn't.
Here is an example of a class with a static method and standard method.
public class MyClass {
public static void staticPrintMe() {
System.out.println("I can be printed without any instantiation of MyClass class");
}
public void nonStaticPrintMe() {
System.out.println("I can be printed only from an object of type MyClass");
}
}
And here is the code to call both methods:
MyClass.staticPrintMe(); // Called without instantiating MyClass
MyClass myClassInstance = new MyClass(); // MyClass instantiation
myClass.nonStaticPrintMe(); // Called on object of type MyClass
As you can see the static method is invoked without any object of type MyClass.
Take the java.lang.Math class as an example. In this line of code:
double pi = 2 * Math.asin(1);
I've referred to the Math class, but the asin method is static. There's no instance of the class created, the class just acts as a placeholder for this utility function.
A corollary of this is that a static method may not access any per-instance data - it can only access class variables that are also declared static.
Look at this example. Defining a class with both an static method and an instance method:
public class MyClass {
public MyClass() {
// do something
}
public static staticMethod() {
// do something
}
public void instanceMethod() {
// do something
}
}
Usage:
MyClass anInstance = new MyClass();
// static method:
MyClass.staticMethod();
// instance method:
anInstance.instanceMethod();
// this is possible thought discoraged:
anInstance.staticMethod();
// this is forbidden:
MyClass.instanceMethod();
To invoke static method you do not need to build a class instance (i.e object).
For example:
class Multiplier {
public static double multiply(double arg1, double arg2) {
return arg1 * arg2;
}
}
static method does not use class instance information, and you can use the method as:
Multiplier.multiply(x, y);
non-static method uses class instance information and depends on it.
for example:
class Pony {
private Color color;
private String name;
public Pony(Color color, String Name) {
this.color = color;
this.name = name;
}
public void printPonyInfo() {
System.out.println("Name: " + this.name);
System.out.println("Color: " + this.color);
}
}
Pony pony1 = new Pony(Color.PINK, "Sugar");
Pony pony2 = new Pony(Color.BLACK, "Jupiter");
and when you call:
pony1.printPonyInfo();
pony2.printPonyInfo();
You get name and color for every pony object. You cannot call Pony.printPonyInfo() because printPonyInfo() does not know, what to print. It is not static. Only when you have created Pony class instance, you can call this method, that depends on the class instance information.
When we call a method, we need an instace of a class like this.
class SomeClass {
public void test() {}
}
SomeClass obj = new SomeClass();
obj.test();
'obj' is an instance of SomeClass.
Without an instance like 'obj', we can't call the test method.
But the static method is different.
class SomeClass2 {
public static void testStatic() {}
}
We don't call the testStatic method like above case of SomeClass.
SomeClass2 obj = new SomeClass2();
obj.testStatic(); // wrong
We just call with only class type.
SomeClass2.testStatic();
A friend of mine was asked that question in his on-phone job interview a couple of days a go.
I don't have a clue. can anyone suggest a solution?
(His job interview is over. just out of curiosity now )
10x.
Mark constructor as private
Provide a static method on the class to create instance of a class. This will allow you to instantiate objects of that class
I don't know what they mean exactly mean by a final class. If they mean a class that cannot be extended by inheritence, than clearly this cannot be done, except by marking that class with final (or sealed, or whatever the language keyword is).
But if the mean final as in immutable, such that a derived class can't modify the value of the fields in the class,than the base class should have all of the fileds and accessor methods private.
Create a private constructor without parameters?
public class Base
{
private Base()
{
}
}
public class Derived : Base
{
//Cannot access private constructor here error
}
Make all the constructors of that class as private to stop inheriting, Though not recommended.
public class Immutable {
private int val;
public Immutable(int v)
{
this.val = v;
}
public int getVal() { return this.val; }
}
You can make your class immutable without using final keyword as:
Make instance variable as private.
Make constructor private.
Create a factory method which will return the instance of this class.
I am providing immutable class here in Java.
class Immutable {
private int i;
private Immutable(int i){
this.i = i;
}
public static Immutable createInstance(int i){
return new Immutable(i);
}
public int getI(){return i;}
}
class Main {
public static void main(string args[]){
Immutable obj = Immutable.createInstance(5);
}
}
Static classes can't be inherited from
Why are we not able to override an instance variable of a super class in a subclass?
He perhaps meant to try and override the value used to initialize the variable.
For example,
Instead of this (which is illegal)
public abstract class A {
String help = "**no help defined -- somebody should change that***";
// ...
}
// ...
public class B extends A {
// ILLEGAL
#Override
String help = "some fancy help message for B";
// ...
}
One should do
public abstract class A {
public String getHelp() {
return "**no help defined -- somebody should change that***";
}
// ...
}
// ...
public class B extends A {
#Override
public String getHelp() {
return "some fancy help message for B";
// ...
}
Because if you changed the implementation of a data member it would quite possibly break the superclass (imagine changing a superclass's data member from a float to a String).
Because you can only override behavior and not structure. Structure is set in stone once an object has been created and memory has been allocated for it. Of course this is usually true in statically typed languages.
Variables aren't accessed polymorphically. What would you want to do with this that you can't do with a protected variable? (Not that I encourage using non-private mutable variables at all, personally.)
class Dad{
public String name = "Dad";
}
class Son extends Dad{
public String name = "Son";
public String getName(){
return this.name;
}
}
From main() method if you call
new Son().getName();
will return "Son"
This is how you can override the variable of super class.
Do you mean with overriding you want to change the datatype for example?
What do you do with this expression
public class A {
protected int mIndex;
public void counter(){
mIndex++;
}
}
public class B extends A {
protected String mIndex; // Or what you mean with overloading
}
How do you want to change the mIndex++ expression without operator overloading or something like this.
If you have the need to override an instance variable, you are almost certainly inheriting from the worng class.
In some languages you can hide the instance variable by supplying a new one:
class A has variable V1 of type X;
class B inherits from A, but reintroduces V1 of type Y.
The methods of class A can still access the original V1. The methods of class B can access the new V1. And if they want to access the original, they can cast themself to class A (As you see dirty programming provokes more dirty progrtamming).
The best solution is to find another name for the variable.
you can override a method,that is all right
but what do you mean by overriding a variable?
if you want to use a variable at any other place rather than super class
u can use super.
as in
super(variable names);
why do you want to override a variable?
i mean is there any need?
we can not overriding structure of instance variables ,but we ovverride their behavior:-
class A
{
int x = 5;
}
class B extends A
{
int x = 7:
}
class Main
{
public static void main(String dh[])
{
A obj = new B();
System.out.println(obj.x);
}
}
in this case output is 5.