This is what I'm trying to do (in Java 1.6):
public class Foo {
public Foo() {
Bar b = new Bar();
b.setSomeData();
b.doSomethingElse();
this(b);
}
public Foo(Bar b) {
// ...
}
}
Compiler says:
call to this must be first statement in constructor
Is there any workaround?
You could implement it like this:
public class Foo {
public Foo() {
this(makeBar());
}
public Foo(Bar b) {
// ...
}
private static Bar makeBar() {
Bar b = new Bar();
b.setSomeData();
b.doSomethingElse();
return b;
}
}
The makeBar method should be static, since the object corresponding to this is not available at the point you are calling the method.
By the way, this approach has the advantage that it does pass a fully initialized Bar object to the Foo(Bar). (#RonU notes that his approach does not. That of course means that his Foo(Bar) constructor cannot assume that its Foo argument is in its final state. This can be problematical.)
Finally, I agree that a static factory method is a good alternative to this approach.
You can implement the "default constructor" as a static factory method:
public class Foo {
public static Foo createFooWithDefaultBar() {
Bar b = new Bar();
b.setSomeData();
b.doSomethingElse();
return new Foo(b);
}
public Foo(Bar b) {
// ...
}
}
Like it says, a call to this() must be the first thing to happen in a constructor. Is there any reason this wouldn't work?
public class Foo {
public Foo() {
this(new Bar());
Bar b = getBar();
b.setSomeData();
b.doSomethingElse();
}
public Foo(Bar b) {
// ...
}
}
Related
I've inherited some code, and I'm trying to refactor it in an attempt to clean it up.
This is a simplified case of how I received the code:
public class Foo
{
private void doSomething()
{
someOtherAction(Foo.this);
}
protected class FooChildClass
{
protected void anotherAction()
{
createDialogBox(Foo.this);
}
}
}
//totally not related to class Foo even though most code is duplicated
public class Bar
{
private void doSomething()
{
someOtherAction(Bar.this);
}
protected class BarChildClass
{
protected void anotherAction()
{
createDialogBox(Bar.this);
}
}
}
Now, here's the catch - after further examination of the code, Bar is almost a carbon-copy of Foo with some slight changes here and there.
I'd like to condense my code into something like this:
//superclass
public class Foo
{
protected void doSomething()
{
someOtherAction(Foo.this);
}
protected class ChildClass
{
protected void anotherAction()
{
createDialogBox(Foo.this);
}
}
}
//inherits from Foo and only overrides when necessary
public class Bar extends Foo
{
//rely on base implementation of doSomething
//override other functions only when necessary
}
Will my condensed code run successfully? I have a C# background, so I understand a good bit of Java syntax, but C# doesn't have anything similar to ClassName.this.
I'm figuring that ClassName.this is meant to resolve scoping issues by defining what 'this' is intended - and that with my modified code, Bar is indeed a Foo object too - but I figure I would ask to be sure!
Edited original question for clarification
Foo.this is equivalent to this. Therefore your condensed code is Okay with no requirement of being changed.
The following test code is to test your updated program:
Foo f = new Foo();
Foo.ChildClass fc = f.new ChildClass();
f.doSomething();
fc.anotherAction();
Bar b = new Bar();
Bar.ChildClass bc = b.new ChildClass();
b.doSomething();
bc.anotherAction();
The output is:
Foo#52e922
Foo#52e922
Bar#25154f
Bar#25154f
Referring to your most recent edit I composed the following example:
public class Foo {
public void printMe() {
System.out.println("I'm foo");
}
public class Child {
public void printMe() {
Foo.this.printMe();
}
}
}
public class Bar extends Foo {
#Override
public void printMe() {
System.out.println("I'm bar");
}
}
public class Main {
public static void main(String[] args) {
new Bar().new Child().printMe();
}
}
The result was:
I'm bar
Which concludes, that Foo.this.printMe() does not statically refer to the outer class Foo, but to the outer instance of the Child instance, which in this case is an instance of Bar.
For further reading:
The Classname.this syntax is used for inner classes.
You can use the following example to try a bit around and see its effects:
public class Foo {
private int value = 1;
public class Bar {
private int value = 2;
public void printValue() {
System.out.println(Foo.this.value);
}
}
}
Regarding derivation, there's no way to explicitly refer to a certain super type in java, like in C. However, you can refer to your super class using the super keyword.
With java 1.8 and default interface methods, the Classname.super syntax was introduced:
public interface Foo {
default int getValue() {
return 1;
}
}
public interface Bar {
default int getValue() {
return 2;
}
}
public class Impl implements Foo, Bar {
#Override
public int getValue() {
return Bar.super.getValue();
}
}
However, you can still only refer to direct super types. Everything other will be denied by the compiler.
At work I came across the following design in a java project:
Consider interfaces Foo, Bar, and Baz as follows:
interface Bar { public int a(); }
interface Baz { public int b(); }
interface Foo extends Bar, Baz { public int c(); }
Now, consider class FooImpl:
public class FooImpl implements Foo {
private Bar bar;
private Baz baz;
public int a() {
return bar.a();
}
public int b() {
return baz.b();
}
public int c() {
return 0;
}
}
What are the use cases for this kind of class hierarchy? It seems to me that this introduces a lot of boilerplate and does not add much in terms of abstraction, other than breaking up what could be a large file into smaller files.
It allows things like this:
Foo foo = new FooImpl();
useBar(foo);
public void useBar(Bar bar) {
bar.a();
}
Whether this is useful depends on the real context. Your example code with classes and methods with meaningless names does not support a rational judgement.
The other thing to note is your FooImpl is actually implemented as some kind of wrapper for Bar and Baz instances. That's not (strictly speaking) an interface design issue.
I think it's a workaround for multiple inheritance (which is not allowed in Java). You're not showing implementations for Bar and Baz, but let's suppose they exist:
public class BarImpl implements Bar {
#Override
public int a() {
return 1;
}
}
public class BazImpl implements Baz {
#Override
public int b() {
return 2;
}
}
You neither have told us how Bar and Baz attributes are instantiated and set to FooImpl, because, if executed as stated in your question, you'll get a NullPointerException both in FooImpl.a() and FooImpl.b(). Again, let's imagine how this could be achieved:
public class FooImpl implements Foo {
private Bar bar; // better if final
private Baz baz; // better if final
// Constructor to properly initialize bar and baz
public FooImpl(Bar bar, Baz baz) {
this.bar = bar;
this.baz = baz;
}
#Override
public int a() {
return bar.a();
}
#Override
public int b() {
return baz.b();
}
#Override
public int c() {
return 0;
}
}
Wiring everything up:
Bar bar = new BarImpl();
Baz baz = new BazImpl();
Foo foo = new FooImpl(bar, baz);
int one = foo.bar(); // 1
int two = foo.baz(); // 2
In a way, FooImpl is "inheriting" from both BarImpl and BazImpl, though this is achieved by means of delegation.
To do this is really just redirecting fooimpl using its propertie's(bar and baz) "a" method and "b" method
Working in Java.
I have an abstract class as such:
public abstract class Foo {
protected Logger log = null;
// other stuff
public boolean isLoggerSet() {
return (this.log != null) ? true : false;
}
}
Now i extend this class as such:
public class Bar extends Foo {
public Bar() {
this.log = Logger.getLogger(Bar.class);
}
public void someMethod(String[] args) {
Bar b = new Bar();
if(b.isLoggerSet()) {
// do some stuff
}
}
}
The question: Is my Bar.class actually referring to the super.log even though I call this.log since Bar does not have it's own local variable called log? Or would the correct way to implement the isLoggerSet() method be to make it abstract and force Bar.class to implement it itself on it's local copy of log since it's been extended?
Basically I have to say this.log in my Foo class because, it refers to itself. But in Bar class I want to be able to null check log, should I instead be using super.log = in Bar.class?
You have not set your Logger to static, but instead to protected.
Whether you use super or this, they point to the exact same variable in this case.
If there's only one attribute called log in the class hierarchy, it doesn't matter if you say this.log or super.log, it'll refer to the same one - the only one!
this.log is the same super.log. There is only one variable because log is inherited from Foo.
The only one change is required: this.isLoggerSet() should be replaced by b.isLoggerSet()
You cannot call non static method inside static method
Classes are blueprints for making objects. In your case, the blueprint for "Bar" adds on to the blueprint defined in "Foo" (which adds to the blueprint defined in "Object").
Don't let the baseclass confuse you: conceptually here the compiler pulls all the base classes up into one top-level combined class (ignoring the "Object" base):
public class Bar {
protected Logger log = null;
public boolean isLoggerSet() {
return (log != null) ? true : false;
}
public Bar() {
log = Logger.getLogger(Bar.class);
}
public void someMethod(String [] args) {
Bar b = new Bar();
if(b.isLoggerSet()) {
// do some stuff
}
}
}
You would exercise your code like this:
Bar x = new Bar();
x.isLoggerSet(); // Returns true since Bar() constructor just set it
x.someMethod(args);
The first line creates a new object of type "Bar" in memory. This object has a single pointer to a "Logger" object that gets set in the Bar constructor on the first line with "new Bar()".
The next line checks "isLoggerSet". Assuming that "getLogger" returns a live object then the "isLoggerSet" will always return true.
The last line calls "x.someMethod(args)". This method creates a new "Bar" object (whose constructor sets its "log" pointer). Thus the "b.isLoggerSet()" will pass here too.
Here is a slightly modified example:
public abstract class Foo {
protected String name;
public Foo() {
name = "Mr. Foo";
}
}
public class Bar extends Foo {
protected String name;
public Bar() {
name = "Mr. Bar";
}
public void someMethod() {
System.out.println("this.name=" + this.name);
System.out.println("super.name=" + super.name);
}
public static void main(String[] args) {
Bar bar = new Bar();
bar.someMethod();
}
}
Output:
this.name=Mr. Bar
super.name=Mr. Foo
So there are two variables called 'name', one in each class. To access the one in the superclass from within the subclass you need to use 'super.name'.
When creating a Bar() Java checks for a super(...) call to a constructor of the superclass as the first line of the constructor. If it is not there (like above) then 'super();' is invisibly inserted as the first line of the constructor. So I could have written:
....
public Bar() {
super();
name = "Mr. Bar";
}
....
With the same result. However, this is not necessary, Java inserts a super call to the default constructor for you if you don't call a super constructor yourself. In this way constructor chaining is enforced.
If you want to call a super constructor yourself you could also call a non-default constructor, for example:
public abstract class Foo {
protected String name;
public Foo() {
name = "Mr. Foo";
}
public Foo(String name) {
this.name = name;
}
}
public class Bar extends Foo {
public Bar() {
super("Mr. Bar");
}
public void someMethod() {
System.out.println("this.name=" + this.name);
System.out.println("super.name=" + super.name);
}
public static void main(String[] args) {
Bar bar = new Bar();
bar.someMethod();
}
}
Output:
this.name=Mr. Bar // refers to 'name' inherited from Foo
super.name=Mr. Bar // refers to 'name' in superclass, set by the String constructor
// so these both refer to the same variable in this example
Note the default constructor of Foo is not called in this last example.
This is a very odd question, so please bear with me.
I'd like to know if the Java specification guarantees that an overriding method in two subclasses is resolved via identical mechanisms in each. In other words, if I have
public class Foo {
public int frob() {
return 7;
}
}
public class Bar extends Foo {
#Override
public int frob() {
return 8;
}
}
public class Baz extends Foo {
#Override
public int frob() {
return 9;
}
}
and a method somewhere:
public static int quux(Bar b) {
return b.frob();
}
which I know only calls .frob() on b, how safe is it to call quux((Bar)new Baz())?
quux((Bar)new Baz()) will not even compile. (Cannot cast from Baz to Bar since Baz IS-NOT a Bar).
- Bar IS-A Foo, and Baz IS-A Foo.
- But neither Bar is a Baz nor Baz is a Bar, so this casting won't work.
I have two classes. Class A and Class B.
I have a function in Class A that i would like to use in class B. I was thinking about passing a reference of Class A to the constructor of Class B and then call the function after that.
Would that work? Can someone show me an example?
Thanks in advance!
Yes, it will work. And it's a decent way to do it. You just pass an instance of class A:
public class Foo {
public void doFoo() {..} // that's the method you want to use
}
public class Bar {
private Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
public void doSomething() {
foo.doFoo(); // here you are using it.
}
}
And then you can have:
Foo foo = new Foo();
Bar bar = new Bar(foo);
bar.doSomething();
Do something like this
class ClassA {
public ClassA() { // Constructor
ClassB b = new ClassB(this);
}
class ClassB {
public ClassB(ClassA a) {...}
}
The this keyword essentially refers to the object(class) it's in.