• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Inner Classes Question

 
Ranch Hand
Posts: 60
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is from certification book by Kathy K. and Bert B. (Chapter 8, Q4)

which two create an anonymous inner class from within class Bar? (choose two)

A. Boo f = new Boo(24){};
B. Boo f = new Bar(){};
C. Boo f = new Boo(){String s;};
D. Bar f = new Boo(String s){};
E. Boo f = new Boo.Bar(String s){};

Answer: B, C

Can anyone explain this. what i understand, anonymous class means no name, but these answers suggest its simply creating an instance of a class, doesn't seem like declaring a new class. It is really confusing to me.

This is the book's explanation:

"B is correct becuase anonymous inner classes are no different from any other class when it comes to polymorphism. that means you are always allowed to declare a reference variable of the superclass type and have that reference variable refer to an instance of a subclass type, which in this case is an anonymous subclass of Bar. Since Bar is a subclass of Boo, it all works. C uses correct syntax for creating an instance of Boo."

but i didn't get where is the anonymous class.

Thanks
[ September 09, 2004: Message edited by: Barry Gaunt ]
 
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you create an anonymous inner class, you essentially call the constructor of an existing class -- but after the constructor's arguments (where you would normally have just a semicolon), you insert a new class definition in brackets.

From this, you get is an object that is automatically a subclass of the class whose constructor you called, and that object is automatically upcast from the anonymous type to the class whose constructor you called.

Consider this example...



In the above code, we have two top-level classes: Named1 and Named2. And inside Named2, we have two methods: makeNamed1() and makeAnonymous().

In the method makeNamed1(), we simply declare that we're making a new object of type Named1, and then call the constructor.

But in the method makeAnonymous(), we declare that we're making a new object of type Named1, then call the constructor, but then -- before the essential semicolon -- we slip in a class definition. The object we get (with the anonymous class definition) automatically extends Named1 and is upcast to type Named1.

So now we have an object called anon, which appears to be of type Named1. But when we call someMethod(), polymorphism kicks in and the overridden method body (in the anonymous class definition) is executed.
 
marc weber
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To answer this question more directly...

In option C, the anonymous class definition is in the brackets following the call to the constructor Boo(). This anonymous class defines one member, String s. Note that the anonymous type is automatically upcast to type Boo.

In option B, the anonymous class definition is in the empty brackets following the call to the constructor Bar(). Here, the anonymous type is automatically upcast to type Bar, and then upcast again to the declared type, Boo (which is the parent of Bar).

Options A, D, and E are not calling valid constructors because the arguments don't match. Note that we're calling a constructor here -- not defining one, as options D and E suggest with their argument lists. In D, there's an additional problem of trying to convert a Boo to a Bar without an explicit cast (which would fail at runtime anyway; because a Bar is a Boo, but a Boo is not a Bar). And E is also trying to confuse us with an "outer.inner" type name misapplied to base and subclass.
[ September 09, 2004: Message edited by: marc weber ]
 
Piyush Jain
Ranch Hand
Posts: 60
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Marc.

That makes it very clear.

Anonymous class will have a {}; instead of a ; when a new instance is created for a class.
 
Cowgirl and Author
Posts: 1589
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Geez... I don't have anything better to add because Marc did a great job.

But I feel obligated to add another example, since it was my confusing answers that led you to the question.

You're right about the semicolon vs. curly braces:

Dog d = new Dog(); <-- makes new instance of Dog.

Dog d = new Dog() { } <-- makes a new anonymous class, that *extends* Dog, and also creates an instance of that new anonymous type and assigns it to the variable "d".

And it works with an interface, of course:

interface Pet {
void beFriendly();
}

Pet p = new Pet() { } <-- makes a new anonymous class that *implements* Pet, and also creates an instance of that new anonymous Pet implementation class and assigns it to the variable "p".

The biggest giveaway is that you can NEVER make a new instance of an interface, of course. You can't say:

Pet p = new Pet(); <-- will not work because Pet cannot be instantiated.

So when you see:

new Pet()

You must look for what comes after the parens. It's either a semicolon or curly braces, and if it's a semicolon, and Pet is an interface, then you KNOW this is a compiler error. If it's curly braces, then you know that you are actually making a new anonymous class that *implements* the Pet interface, and instantiating *that*, rather than trying to instantiate the Pet interface.

cheers (and thanks Marc)
Kathy
 
Ranch Hand
Posts: 230
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just extrapolating to Kathy's findings ... Be careful enough to spot that, when you create an anonymous class that implements the interface, you should hold implementation for the methods in the interface.

I have showed it, in the below example by writing a small program that uses the interface defined by Kathy! Check this out!

interface Pet
{
void beFriendly();
}

public class AnonymousDemo
{
public static void main(String args[])
{
Pet p = new Pet() { };
//implementation not provided for the methods of the interface - Will not compile

Pet p = new Pet() { public void beFriendly() { } }; //Proper
}
}
 
Time flies like an arrow. Fruit flies like a banana. Steve flies like a tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic