I am a Java beginner.
Can anyone explain why is it printing output 2?
interface Foo {
int bar();
}
public class Beta {
class A implements Foo {
public int bar() {
return 1;
}
}
public int fubar(final Foo foo) {
return foo.bar();
}
public void testFoo()// 2
{
class A implements Foo {
public int bar() {
return 2;
}
}
System.out.println(fubar(new A()));
}
public static void main(String[] args) {
new Beta().testFoo();
}
}
That is because you redefined Class A here:
class A implements Foo {
public int bar() {
return 2;
}
}
System.out.println(fubar(new A()));
So when you do return foo.bar(); you return 2
Because the innermost definition of A is in the testFoo() method, and its method bar() return 2.
You may also find the answer to my question from today interesting.
When you say, System.out.println(fubar(new A()));
the class A created is the one defined inside testFoo().
There are many places in java where you can hide a broader name with a more local name. This is true of parameters vs member variables, class names etc. In your case, you are hiding Beta.A with the A you defined in the method.
Related
The isAbsolute method does not have a body in the path interface, but I can run it in the following code. How is this possible?
Path path= Paths.get("D:\\Example\\1.txt");
System.out.println(path.isAbsolute());//prints true
Imagine following code:
public interface Foo {
public boolean bar();
}
public class Fooz implements Foo {
#Override
public boolean bar() {
return false;
}
}
And:
public Foo getFoo() {
return new Fooz();
}
public static void main(String[] args) {
Foo myFoo = getFoo();
System.out.println(myFoo.bar()) //false
}
If you are looking for actual implementation of this function, I advise looking thru the source code of JVM of your choosing. Example of one such implementation can be found in UnixPath.java on OpenJDK github repo.
I would like to add additional implementation to an overriding subclass method without completely overriding the superclass one. This is what I got to so far, but it doesn't seem to work. I would like the output to be "superclass return" followed by "subclass return". Here's the code:
public class A {
public String send() {
return "superclass return";
}
}
public class B extends A{
public String send() {
super.send();
return "subclass return";
}
}
public class Driver {
public static void main(String[] args) {
B b = new B();
System.out.println(b.send());
}
}
Output: subclass return
Am I using the wrong syntax super.send()? The intended output should be:
superclass return
subclass return
You have lost the return value of the super send() method and that is why you cannot see it in the output. To be able to see both, you need to modify the child implementation to something like this:
public String send() {
String value = super.send();
return value + "subclass return";
}
You aren't doing anything with the return value of the super class. Try this:
public class A {
public String send() {
return "superclass return";
}
}
public class B extends A{
public String send() {
return super.send() + "subclass return";
}
}
public class Driver {
public static void main(String[] args) {
B b = new B();
System.out.println(b.send());
}
}
Or if you want the line break:
return super.send() + "\nsubclass return";
Problem
I'm trying to use Java generics to replace classes with similar methods. All of the examples that I've found cover simple examples, but I'm not sure if Java Generics are intended to be used this way.
I have 2 parent classes, and 2 child classes that have almost identical methods. Both parent classes derive from different classes as well. Ultimately, I want to be able to use one block of code to create and manipulate one of the parent classes, then its child class without a lot of switch statements or other flow control with duplicate code.
This is what I had in mind, even though I haven't beeen able to get it to work this way yet, whether it be syntax, or just not a feature of Generics.
Parent Classes
public class FooParent
{
private FooChild fooChild;
public FooChild getChild()
{
return fooChild;
}
}
public class BarParent
{
private BarChild barChild;
public BarChild getChild()
{
return barChild;
}
}
Child Classes
public class FooChild
{
public void print()
{
System.out.println("I'm a foo child");
}
}
public class BarChild
{
public void print()
{
System.out.println("I'm a bar child");
}
}
Generic Classes
public class GenericParent<T>
{
private T self;
public GenericParent(T self)
{
this.self = self;
}
public GenericChild getChild()
{
return new GenericChild(self.getChild());
}
}
public class GenericChild<T>
{
private T self;
public GenericChild(T self)
{
this.self = self;
}
public void print()
{
self.print();
}
}
How I want to use them
public static void main(String args[])
{
GenericParent parent;
// Only the initialization of the parent variable needs specialized code
switch(args[0])
{
case "foo":
parent = new GenericParent(new FooParent());
break;
case "bar":
parent = new GenericParent(new BarParent());
break;
}
// From here on out, it's all generic
parent.getChild().print();
}
Usage and desired output
java genericExample foo
> I'm a foo child
java genericExample bar
> I'm a bar child
Final Questions
Maybe "child" and "parent" are misnomers, because I know they're not actually inherited, but the bottom line is, the one class returns its "child" with certain methods. So this is a lot of code for a problem that may not actually be solvable this way, but hopefully you can answer me this:
Is this something that Java Generics can accomplish?
If not, is there a solution to this problem in Java?
Thanks!
Edit
My "Foo" and "Bar" classes are uneditable by me. My ultimate question is: can I store one instance of either class in a single variable without using a common parent class?
I think you want polymorphism, not generics:
public class test {
public class FooParent implements hasPrintableChildren
{
private FooChild fooChild;
public FooChild getChild()
{
return fooChild;
}
}
public class BarParent implements hasPrintableChildren
{
private BarChild barChild;
public BarChild getChild()
{
return barChild;
}
}
public class FooChild implements canPrint
{
public void print()
{
System.out.println("I'm a foo child");
}
}
public class BarChild implements canPrint
{
public void print()
{
System.out.println("I'm a bar child");
}
}
public interface hasPrintableChildren{
public canPrint getChild();
}
public interface canPrint{
public void print();
}
public static void main(String args[])
{
hasPrintableChildren parent;
// Only the initialization of the parent variable needs specialized code
switch(args[0])
{
case "foo":
parent = new FooParent();
break;
case "bar":
parent = new BarParent();
break;
}
// From here on out, it's all generic
parent.getChild().print();
}
}
OP clarified that he would be interested in the reflection option:
public static void main(String args[]) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
Object parent;
// Only the initialization of the parent variable needs specialized code
switch(args[0])
{
case "foo":
parent = new FooParent();
break;
case "bar":
parent = new BarParent();
break;
}
// From here on out, it's all generic
Object child = parent.getClass().getMethod("getChild").invoke(parent);
child.getClass().getMethod("print").invoke(child);
}
Note: I would not recommend this sort of hard coded reflection. Code like this generally stinks of a bigger design problem.
Your parent seems a wrapper, a wrapper is a container, so yes it may be something that can benefit from a type parameter.
But I can't see any type parameter except in the constructor signature (and what is self? No bounds, no hints, no anything...), so using a generic type doesn't buy anything to you here. It's no use to introduce a type parameter if the methods you are interested in return void and declare an empty parameter list.
Here's the guidance: if methods in your classes would benefit from having a type parameter, ie if a type parameter is useful in any method return type or in the signature, then genericize your class. Otherwise, stick with what you currently have.
No. This is not usually something you would use Generics for, this is something you would use an Interface or an Abstract class for, and in your example, probably anonymous inner classes.
Here is an example that pretty much shows all that:
Main.java
public class Main {
public static void main(String args[])
{
AbstractParent parent;
// Only the initialization of the parent variable needs specialized code
switch(args[0])
{
case "foo":
parent = new FooParent();
break;
default:
parent = new BarParent();
break;
}
// From here on out, it's all generic
parent.getChild().print();
}
}
Child.java
public interface Child {
void print();
}
AbstractParent.java
public abstract class AbstractParent {
protected Child child;
public Child getChild() {
return child;
}
}
BarParent.java
public class BarParent extends AbstractParent {
public BarParent() {
child = new Child() {
#Override
public void print() {
System.out.println("I'm a bar child");
}
};
}
}
FooParent.java
public class FooParent extends AbstractParent {
public FooParent() {
child = new Child() {
#Override
public void print() {
System.out.println("I'm a foo child");
}
};
}
}
With some of the new language features in Java 8, you can do even cooler things. But let's leave that for another time.
Yes, generics together with polymorphism can help you:
public class Foo {} // declared elsewhere
public class Bar {} // declared elsewhere
public abstract class GenericParent<T> {
private T self;
public GenericParent(T self) {
this.self = self;
}
protected T getSelf() {
return self;
}
public abstract GenericChild<T> getChild();
}
public class FooChild extends GenericChild<Foo> {
public FooChild(Foo foo) {
super(foo);
}
}
public class BarChild extends GenericChild<Bar> {
public BarChild(Bar bar) {
super(bar);
}
}
public class FooParent extends GenericParent<Foo> {
public FooParent(Foo foo) {
super(foo);
}
public FooParent() {
this(new Foo());
}
#Override
public GenericChild<Foo> getChild() {
return new FooChild(getSelf());
}
}
public class BarParent extends GenericParent<Bar> {
public BarParent(Bar bar) {
super(bar);
}
public BarParent() {
this(new Bar());
}
#Override
public GenericChild<Bar> getChild() {
return new BarChild(getSelf());
}
}
You also have to change your main method slightly:
public static void main(String args[]) {
GenericParent<?> parent;
// Only the initialization of the parent variable needs specialized code
switch(args[0]) {
case "foo":
parent = new FooParent();
break;
case "bar":
parent = new BarParent();
break;
}
parent.getChild().print();
}
Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}
Is there a best practice for enumerations in java? For example, I have the following:
class Foo {
public static final int OPTION_1 = 'a';
public static final int OPTION_2 = 'b';
public void doSomething(String name, int option) {
...
}
}
void test() {
Foo foo = new Foo();
foo.doSomething("blah", Foo.OPTION_2);
}
so the user can choose to use one of the static ints defined in Foo, but they could also supply any other int they want, there's no compile-time checking on it. Is there some way around this in java, some other way of doing this to restrict the end developer to choose from only the defined option types?
Thanks
class Foo {
public enum Option{First, Second}
public void doSomething(String name, Option option) {
...
}
}
void test() {
Foo foo = new Foo();
foo.dosomething("blah", Foo.Option.Second);
}
Since Java 1.5 there is the enum keyword which makes typesafe enumerations
Your code would look like this then :
class Foo {
public enum Option = { OPTION_1, OPTION_2 };
public void doSomething(String name, Option option) {
...
}
}
void test() {
Foo foo = new Foo();
foo.doSomething("blah", Foo.Option.OPTION_2);
}
This is fully supported by the type system so the compiler will enforce the user not to become to creative when passing options.
You can read more here
There are enum types in Java (as of J2SE 5.0). Read the tutorial.
public enum Option{
OPTION_1, OPTION_2 //All caps by convention
}
class Foo {
public void dosomething(String name, Option option) {
...
}
}
void test() {
Foo foo = new Foo();
foo.dosomething("blah", Option.OPTION_2);
}
you even can add method into enum, check it out at sun document http://download.oracle.com/javase/tutorial/java/javaOO/enum.html
This will allow you to set the value of the enum
enum Option{
ONE('a');
TWO('b');
private Option(int x){
value = x;
}
private int value;
}
class Foo {
public void doSomething(String name, Option option) {
...
}
}
void test() {
Foo foo = new Foo();
foo.dosomething("blah", Option.ONE);
}