Initializing objects using a super class instead of the subclass - object

I recently saw this example code and I didn't know how I'd be able to easily find the answer to this question I had. In the code the Dog object, Cow object and Snake object are all declared as Animal objects. So is it valid to declare an object using a more generic class? For instance, could I declare any object as an Object (since all classes are subclasses of the object class)? What are the advantages/disadvantages of declaring specific or more general? Is it all for ease of readability?
class Animal {
void whoAmI() {
System.out.println("I am a generic Animal.");
}
}
class Dog extends Animal {
void whoAmI() {
System.out.println("I am a Dog.");
}
}
class Cow extends Animal {
void whoAmI() {
System.out.println("I am a Cow.");
}
}
class Snake extends Animal {
void whoAmI() {
System.out.println("I am a Snake.");
}
}
class RuntimePolymorphismDemo {
public static void main(String[] args) {
Animal ref1 = new Animal();
Animal ref2 = new Dog();
Animal ref3 = new Cow();
Animal ref4 = new Snake();
ref1.whoAmI();
ref2.whoAmI();
ref3.whoAmI();
ref4.whoAmI();
}
}
The output is
I am a generic Animal.
I am a Dog.
I am a Cow.
I am a Snake.

You could instantiate every other class with object, but not primitives, though even they have wrappers that make them classes.
It's just not good object oriented practice because you want the program to be as fail safe as possible.
Put more varied methods into those classes and that's when you start to see the problems.
lets say Dog also has the method chewButt().
Animal dog = new Dog();
dog.chewButt();
No problem there. But that's not all you're allowed to do.
Animal dog = new Cow();
that compiles...
dog.chewButt();
now we have a problem. Cow can't reach its butt.
You want to be as stringent as possible when declaring the superclass but loose enough to get your job done fast. A reason you may want to be looser is something like this.
dogs and snakes are a little too different. I'mma create a new subclass Mammal that extends from Animal. I put dog and cow and whatever else in it.
now I can be assured I can do:
Mammal mouse = new Mouse();
mouse.suckleYoung();
cat.suckleYoung();
whale.suckleYoung();
but if I accidentally try:
Mammal snake = new Snake();
I want the compiler to complain now before I dig myself into a coding hole.
I hope that helps. Experience will definitely burn the points into your brain soon enough.
Edit: referencing comment: I still don't get what reasons there would be that I wouldn't always just declare my dog object like "Dog dog = new Dog();" vs. how it is in the example code "Animal dog = new Dog();
It's because your function working on dog is also assured to work with all Animals (dogs, cats, lizards). If you went with the other route you would have to go through the trouble of writing a separate function for each class of animal. What's worse is that every function you made would have the same code. Instead write the methods once in Animal and every extended class has that set of methods. Imagine having realized that the method you wrote was slightly wrong, you had to change one line but you had to do it in every animal's module because you didn't take the time to create an Animal superclass.

Related

Suggestions how to break up projects with #XmlSeeAlso limiting me

I'd like to start breaking apart a large domain project into various smaller sub projects. The issue is that I have an external project that has some code that needs to unmarshal some xml into a top level base class that all the subprojects can share as a common base. This would be fine, except that I will need an #XmlSeeAlso on the base class that would include every possible subclass (so it seems.) This seems to make it impossible for me to break up the projects in the way I planned.
For example, using animals just for illustration.
Without the XmlSeeAlso on Animal defining the subclasses, I'm pretty much stuck.
//Core project jar
public abstract class Animal {
}
//Mammals jar
#XmlSeeAlso({ Dog.class, Cat.class})
public abstract class Mammal extends Animal {
}
//Birds jar
#XmlSeeAlso({ Sparrow.class, Hawk.class})
public abstract class Bird extends Animal {
}
//Third party jar
//use Bird or Mammal xml
input = new ByteArrayInputStream(birdXml.getBytes());
JAXBContext jc = JAXBContext.newInstance(Animal.class);
u = jc.createUnmarshaller();
//return Animal - FAILS since Animal would need the XmlSeeAlso of subclasses
Animal animal = (Animal)u.unmarshal(input);
I didn't realize that JAXBContext.newInstance can take an array of classes. So in my third party jar I just need to load them all into some common Array and pass them in there to the newInstance method ... JAXBContext.newInstance(myClassesArray);

Groovy - Is it possible to pass a class as a parameter?

This is just a very basic example of what I want to do. There's a bit more that goes on in the foobar method, but it's the gist of what I'm doing. It obviously doesn't work, since it fails to compile, but I'm wondering if I'm just passing the class incorrectly or using the 'className' parameter in the wrong way. I know I can rework it to take the string of the class name and just match it, but it seems a shame to do that. This would be so nice and DRY.
class Foo {
String name
}
class Bar {
String name
}
def foobar(field, className) {
def instance = className.findByName(jsonParams.field)
if(!instance) {
instance = new className(name: jsonParams.field)
}
return instance
}
foobar(foos, Foo)
foobar(bars, Bar)
I don't know much Java or Groovy, so I'm not sure what's possible vs impossible yet. Feel free to just tell me "No." I've tried googling and haven't found anything that really answers the question for me. A simple no would be great at this point haha.
Yes, it is possible to pass class as argument - in Groovy, classes are first class citizens (see this thread for more detail).
This construct: instance = new className(name: jsonParams.field) actually tries to create an instance of class named className, not of the class referenced by this variable. To make it compile, you need to call Class.newInstance:
class Foo {
String name
}
class Bar {
String name
}
def foobar(String name,Class clazz) {
def instance = clazz.findByName(name)
if(!instance) {
instance = clazz.newInstance(name:name)
}
return instance
}
foobar('foo', Foo)
foobar('bar', Bar)
​
I'm not entirely sure what you want to achieve with the findByName method, though - neither Foo nor Bar have a static method named findByName as far as I can tell.

Why does Groovy sometimes not require a return type (or even def) on methods?

I am asking "why is this possible in Groovy?" for the following two code blocks. Maybe I should have created two separate questions, but these seem closely related.
First,
class Dog
{
public speak() {
return "Bark"
}
}
Notice how speak() doesn't have a return type, and I didn't say def. Yet, the code works as if I included def.
Second,
#interface MyAnnotation {
}
interface Canine{
#MyAnnotation
speak()
}
Notice how the speak() method doesn't have a return type, but it works when I put an annotation on the method.
Why do both of these code blocks work (i.e., no errors when I use them)? Why does the first one work iff I put public before it, and why does the second one work iff I put an annotation on it? And where is this documented?
EDIT:
Here is a runnable script that demonstrates both oddities:
#interface MyAnnotation { }
interface Canine{
#MyAnnotation
speak()
}
class Dog implements Canine
{
public speak() {
return "Bark"
}
}
Dog fido = new Dog()
println fido.speak()
Groovy is designed to be flexible and permissive. As long as you use either def, a return type, public, or an annotation, and you have () at the end (and the name doesn't match the enclosing class), the interpreter figures out that it's a method declaration and it lets you do it. If you don't care about the return type enough to indicate it, Groovy is also fine with not caring about it. That's the design philosophy.
This syntax isn't documented anywhere I can find. I would guess that indicates this syntax is subject to change. I would hesitate to rely on this and would stick to using def or a return type, if only for the sake of clarity.

How to dynamically create collections of derived objects?

This question may appear to have been answered before but I have been unable to find exactly what I need. Here is my situation:
// Base class
interface IAnimal {};
public abstract class Animal : IAnimal{}
// Derived classes
interface IDog {}
public class Dog : Animal, IDog { }
interface ICat { }
public class Cat : Animal, ICat { }
interface ITiger { }
public class Tiger : Animal, ITiger { }
interface ILion { }
public class Lion : Animal, ILion { }
// Collection Classes
interface IPets { }
public class Pets
{
IDog dog = new Dog();
ICat cat = new Cat();
}
interface ICircus { }
public class Circus
{
ITiger tiger = new Tiger();
ILion lion = new Lion();
}
I would like to create the collections at run time in an generic Event class by reading in a list animals from xml that would make up the collection. What would be the correct way to accomplish this?
Thanks in advance.
This is kind of an answer to my own question. Maybe this will help others.
I chose a very generic example to illustrate my situation because I have uses for this in many places in Windows Forms, XNA and Silverlight that are all very different.
When I used the Activator, I found out that it assumes the executing assembly. My method is in a library so I had to load a different assembly. Next I had to make sure that I had the right namespace. My base class is in a library and the derived classes are in another namespace so this will require refactoring to properly create the list.
Another problem I found was that the Activator assumes a constructor with no parameters. In my test case all my derived classes are XNA game components with a parameter of type Game.
Have to do some refactoring to test out the interfaces and how the game objects are to interact.
Will be back to this list when I have something further.
Does this sort of example help? (It's from some of my code I happened to have handy.) The key point here is the use of reflection in Activator.CreateInstance(...).
public static List<dynamic> LoadChildEntities(XElement entityElt)
{
var children = new List<dynamic>();
foreach(XElement childElt in entityElt.Elements("entity"))
{
// Look up the C# type of the child entity.
string childTypename = "MyNamespace." + Convert.ToString(childElt.Attribute("type").Value);
Type childType = Type.GetType(childTypename);
if(childType != null)
{
// Construct the child entity and add it to the list.
children.Add(Activator.CreateInstance(childType, childElt));
}
else
{
throw new InvalidOperationException("No such class: " + childTypename);
}
}
return children;
}
If you want a list of IAnimal instead, it wouldn't be too tricky to change.

Subsonic and sub tables

I love NHibernate's ability to have one table to store multiple types based on a discriminator. When I fetch an RegularItem, it will come back as the sub type of the discriminator is correct.
Does SubSonic have this ability?
Do you mean, you have a table with different values stored in it and, dependend on a value you want to return different objects?
e.g. you have a table pet
id type name
---------------------
1 dog bello
2 cat scott
3 cat tiger
and you want to get dog and cat objects from it?
I have a similar case, and I solved it by creating a Dog class and a Cat class that both inherit from subsonic's autogenerated pet class and implement my IPet interface stub, in conjunction with a factory method, where I cast my objects to the new Type:
public Class Dog : Pet, IPet { }
public Class Cat : Pet, IPet { }
public Interface IPet { }
public static IPet GetAllPets()
{
List<IPet> pets = new List<IPet>();
foreach Pet pet in PetCollection.FetchAll()
{
IPet newpet;
if (pet.Type == "dog")
newpet = new Dog();
else if (pet.Type == "cat")
newpet = new Cat();
else throw new InvalidOperationException("Unknown pet type " + pet.Type);
pet.CopyTo(newpet);
newpet.MarkOld();
pets.Add(newpet);
}
}
Typed from memory, not guaranteed to compile. But the theory should be clear.
The short answer is no, SubSonic does not have this feature built-in. You might be able to sort of recreate that with ExecuteTypedList<>, but it would be a lot of manual work (you'd probably be rewriting most of the functionality of the NH feature).

Resources