Java get String from subclass - java

Imagine I have this:
public class Animal {
private String racaAnimal;
private String corAnimal;
public String getCorAnimal() {
return this.corAnimal;
}
public String getRacaAnimal() {
return this.racaAnimal;
}
public Animal getAnimaisCliente(int indice) {
return this.animaisCliente[indice];
}
}
public class Estimacao extends Animal{
private String nomeAnimal;
public String getNomeAnimal() {
return nomeAnimal;
}
}
public class Cliente{
private Animal[] animaisCliente;
}
Constructors aren't showing but they are working fine.
I have one arraylist that holds all Cliente
ArrayList<Cliente> clientes = new ArrayList<Cliente>();
And a animal is created like this
Estimacao animaisEstimacao = new Estimacao(nomeAnimal,racaAnimal,corAnimal);
and then its added to the array of Animal in Cliente
Now if I do this:
System.out.println(" Raça: " + clientes.get(0).getAnimaisCliente(0).getRacaAnimal());
It works.
But how can i get nomeAnimal from class Estimacao?
If i put
System.out.println(" Nome: " + clientes.get(0).getAnimaisCliente(0).getNomeAnimal());
it do not works.
From a subclass we can get things from the super class but the other way arroud? is it possible?

You need to cast your Animal to Estimacao. But obviously, if you don't want to risk an exception, make sure your Animal is of the right class before:
Animal animal = clientes.get(0).getAnimaisCliente(0);
if (animal instanceof Estimacao) {
System.out.println(" Nome: " + ((Estimacao) animal).getNomeAnimal());
}

Think of it this way: an instance of a subclass is also an instance of the superclass. But an instance of the superclass is not necessarily an instance of the subclass. Thus the superclass methods are always available in both, but the subclass methods are only available in the subclass.
If you are sure you have an instance of the subclass, you can cast it explicitly and call the subclass-specific method on it, but you need to take care in doing so.

Try
System.out.println(" Nome: " + ((Estimacao) clientes.get(0).getAnimaisCliente(0)).getNomeAnimal());

In addition to the answers provided above, you may want to just consider the general design of your classes. If the nomeAnimal is something that the Animal class should really be aware of then it might make sense to push it up (even the name of the variable suggests its Animal-ness).
If not, then you may want to further consider leveraging polymorphism by adding a displaySpecificInfo() to the Animal class and either making it abstract, or adding an empty implementation in the Animal class. That would allow you to call it from where your current - failing - print call is, and then have the current line in the derived class's implementation. This would save the need for the cast (not that there's anything wrong with casting), as well as create a more OO/Encapsulation-compliant implementation.
Edit:
Excellent note by #Guillaume and my apologies for potentially peeling back more layers of the OO onion then you are interested in! :)

Cast the Animal to a Estimacao to access the methods defined in Estimacao

It is not possible directly as you are asking. However, you could add getNomeAnimal() in your base class (Animal), that would return null or an empty string - then the instances which are of Estimacao class will return the correct values.

This is a misplaces usage in your animal class:
this.animaisCliente[indice] // animaisCliente is not an attribute of Animal

No you can't do it unless you cast the Animal type object to Estimacao type. Only after the cast, the getNomeAnimal() will be available to you. But this is a bad thing to do. If your array contains a mix of Animal type and Estimacao type objects then it will fail with ClassCastException.

Related

Is it possible to extend instance of Class

For example i have class Animal, and class Cat (Bird, Dog, Fish ...) which extends Animal. Now I want to declare class Pet, which is also Animal, and I want it to be built from any existing Animal, e.g. Cat.
So I need constructor like this:
class Pet extends Animal{
private String nickname;
private Animal kind;
Pet(Animal a, String nickname){
<...>;
this.nickname = nickname;
}
}
EDIT:
I want something like this:
Cat cat = new Cat();
Animal pet = new Pet(cat, "Foo");
if (pet instanceof Pet){
if (pet.kind instanceof Cat){
Pet.sayMeow();
}
}
Is that means that I just need Animal()(which is protected) constructor in <...> ?
Even after your edit, your intentions aren't really clear to me. It seems as if you're simply looking to find a way that allows you, at runtime, to say: "This cat was a stray before but it just became someone's pet now!".
If that's right, you could go for a very simple and straight forward solution -
add this feature right to the Animal class:
public class Animal {
private boolean isPet = false;
private String nickname = "";
public Animal() {
/*...*/
}
public makeStray() {
isPet = false;
nickname = "";
}
public makePet(String nickname) {
isPet = true;
this.nickname = nickname;
}
public boolean isPet() {
return isPet;
}
public void makeNoise() {
/* Override in child classes */
}
}
According to your example, you could then simply do:
Animal cat = new Cat();
cat.makePet("Foo");
if (cat.isPet()) { // Apparently, only pet cats ever meow.
cat.makeNoise(); // Cats will meow, dogs will bark, ...
}
Note, however, that this way of coding can quickly bloat up a class. It really depends on what you're planning to do with it other than this. I'd say this is the quick 'n' dirty solution.
For more sophisticated solutions, check the other answer(s).
EDIT1: As Fildor correctly pointed out, having a method sayMeow() isn't such a good idea. Better have a makeNoise() method in Animal and override it in the child classes to get the specific behavior for the different kind of Animals. Now, if you never want to actually create an instance of the Animal class, you could also make the class abstract, as well as the makeNoise() method. This would ensure that every child class has to implement the makeNoise() method. Or maybe you are fine with the default behavior of mute animals if the method isn't overridden.
EDIT2: This answer to a related questions might shed more light on your situation. It is about C#, but the principles translate to Java.
What you describe is perfectly possible and commonly known as "Decorator Pattern".
Link-Only answers are bad, I will elaborate later when I have more time.
Meanwhile, Wikipedia has more Info: Decorator Pattern.
1 Cat cat = new Cat();
2 Animal pet = new Pet(cat, "Foo");
3 if (pet instanceof Pet){
4 if (pet.kind instanceof Cat){
5 Pet.sayMeow();
6 }
7 }
This has the disadvantage that you need to use instanceOf. Usually, you would have your Animal class have a method - let's call it makeNoise. Probably abstract. You Animal-Implementations ( Cat, Dog... ) then would override that method to make their respective noise ("Bark","Miow" ...).
In the snippet, it seems only Pets can make noises ... that makes it a little bit more complicated because there would be various ways to do that.
You could have the decorator save a sound and override the makeNoise to make that sound. Like so:
Cat catInstance = new Cat();
catInstance.makeNoise(); // Default impl: NOP => "" - no sound.
Animal pet = new Pet( catInstance, "Mieow" );
pet.makeNoise(); // => "Mieow"
The point of all this is: You want to avoid using instanceof. You don't care if the Animal is a Cat a Dog, a Pet-Cat or a Pet-Dog. They shall make their correct sounds if and when told to. So you could have a Collection of "Animal"s and tell them all to "makeNoise" and each will remain silent, bark or mieow without you having to care for if they are pets or which specific child of Animal.
EDIT: Reading my answer again, it is more like a Policy (Strategy pattern) than a Decorator.
The Policy changes how something is done, while the Decorator would add the feature.
So to be a true Decorator, it would mean that makeNoise would be in the interface of Pet. Which means you couldn't call that method on Animals.
That is why I change my suggestion from "Decorator" to "Strategy" pattern.
The example above still holds. You would kind of have a "default" Strategy and inject the "Pet"-Strategy by using a Decorator-Like implementation approach.
Of course all of this could also be done differently to implement the pattern more strictly.
At last, if( x instanceof X) ... always jingles the "Visitor"-Bell, too.

Why does Java call the overridden method even when object is upcasted?

I have the following classes :
public abstract class Animal
{
private String species;
public Animal(String ll)
{
species = ll;
}
public abstract void speak();
public String toString()
{
return "Species: " + species;
}
}
The 2nd class:
public class Raven extends Animal
{
String name;
public Raven(String emri)
{
super("Raven");
name = emri;
}
public void speak()
{
System.out.println("krra krra");
}
public String toString()
{
return super.toString() + "\nName : "+ name ;
}
}
and the test class :
public class TestAnimals
{
public static void main(String args[])
{
Raven blabla = new Raven("Ziosh");
Animal a = blabla;
System.out.println(a.toString());
}
}
When I execute the test class, I get :
Species: Raven
Name: Ziosh
What I don't understand is why does Java use the "new" toString() method, even after we "upcast" the Raven object to Animal ?
Thanks.
Because that's what polymorphism is all about: you can call a method of an object without knowing the actual concrete type of the object, and the appropriate method, defined in this concrete type, will be called.
This works exactly like real objects: if I give you a car, even if you don't know it's actually a hybrid car, the car will behave like a hybrid car when you drive it.
In your example, a and blabla are two references to the same object, which is a Raven instance. So this object *speak*s and *toString*s like a Raven.
When you call a method in java, even if it's cast to the super type, it always looks for the most overridden method to call.
From http://docs.oracle.com/javase/tutorial/java/IandI/override.html
The distinction between hiding a static method and overriding an instance method has important implications:
The version of the overridden instance method that gets invoked is the one in the subclass.
The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
Raven blabla = new Raven("Ziosh");
Animal a = blabla;
Here, a and blabla reference the exact same object, as you can confirm with:
System.out.println(a == blabla);
// prints "true"
As such, a is really a Raven, so naturally it will talk like a Raven, even if you label it an Animal.
Consider another explanation in human terms. Letting the implementation to be executed on an object of a subclass could be actually very dangerous. Imagine a Bicycle class, and its more specialized BicycleWithLittleWheels. The thing about the latter, the little wheels are quite fragile, and if you try to ride it too fast, they could break. If you let somebody ride that bicycle as if was a regular bicycle, completely obvious of the little wheels, he may break it. By similar logic, you probably shouldn't use a high-precision dental drill the same way as a sledgehammer.
This is why, intuitively, you shouldn't let a specialized object be treated as its more general form. Sure, in some cases, it may make sense to use a specialized object as if it was something more general, but not always. How could the compiler distinguish the safe cases from the unsafe cases? That would be too difficult. So to stay on the safe side, the language won't let you do this.
Java always uses the method of the instance as describe in this post:
java override method invocation

How to downcast a Java object?

I am trying to understand Java's polymorphism, and I have one question about downcasting an object.
Let's say for this example I have two subclasses Dog and Cat that inherit from a superclass Animal
From what I understood, the only way to downcast an object is if this Object is already of the good type, like this:
Animal a = new Dog();
Dog d = (Dog) a;
This works right?
But what if I want to create a regular animal without knowing what it would be, and then cast it when I know, how can I do that?
Animal a = new Animal();
Dog d = (Dog) a;
This will throw a ClassCastException at runtime right?
The only way I found to do that is to create a new Dog constructor that creates a dog from a regular animal:
Animal a = new Animal();
Dog d = new Dog(a);
with
public Class Dog extends Animal{
public Dog(Animal a){
super(a);
}
}
So my question is, how am I supposed to do this?
Am I doing it the best way?
Am I not supposed to do this at all, if I have to it means my program is not well conceived?
Is there a better way I missed?
Thanks a lot!
nbarraille
If you want to create an instance of a type that may vary depending upon non-local conditions, use an Abstract Factory (as described in the Design Patterns book).
In it's simplest form:
interface AnimalFactory {
Animal createAnimal();
}
class DogFactory implements AnimalFactory {
public Dog createAnimal() {
return new Dog();
}
}
Note also there is a difference between the static type of a reference and the dynamic type of the object. Even though you have an Animal reference, if the original object is a Dog, it still behaves like a Dog.
You should only cast to a class that the object really is, so if you have a Dog that extends Animal you can cast it to an Animal (because it is one) but you shouldn't cast an Animal to a Dog because not all Animals are Dogs. The Dog class may well have extra fields that are not implemented by the Animal class and so the cast doesn't make sense (what do you initialise those values to?).
Java is a strongly typed language, and that means you can only cast an object to a type it extends from (either a superclass or an interface).
Even if you "fake it", e.g. copy all a classes methods and fields, you just can't cast an object to a type it doesn't extend.
public class Foo{
public String phleem;
public void bar(){
}
}
public class Bar{
public String phleem;
}
public interface Baz{
public void bar();
}
Given the above code, you can't cast a Foo object to either a Bar or a Baz, although the class structure seems to imply that you could. There is no inheritance involved, so a ClassCastException is thrown.
Here you are talking about downcasting, so in this scenario always superclass should be used as a reference and child object should be pointed by that.
This usd basically in factory patter.

Java: Is the following a class or an object?

public class Animal
{
public Animal()
{
System.out.println("Animal");
}
}
public class Mammal extends Animal
{
public Mammal()
{
System.out.println("Mammal");
}
}
Is this an object or a class? If not, what would be an example of an Object?
These are classes.
new Animal() would be an object, i.e. an instance of a class.
Both Animal and Mammal are classes.
Animal a = new Animal();
The code above will result in a reference, a, that refers to an object of type Animal. Since Mammal extends Animal, you'd also be allowed to write:
Animal a = new Mammal();
Your reference type would still be Animal, but this time it's referring to an object of type Mammal.
The Theory of Forms typically refers to Plato's belief that the material world as it seems to us is not the real world, but only a shadow of the real world. Plato spoke of forms in formulating his solution to the problem of universals. The forms, according to Plato, are roughly speaking archetypes or abstract representations of the many types and properties (that is, of universals) of things we see all around us.
Epistemology (From: wikipedia)
To explain it with Plato: The class is a form, 'a shadow'. The 'universals', those many types and properties are the objects.

How to by-pass inheritance in java when invoking a method

class Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Super " + s;
}
}
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
if suppose in main,
Super s = new Sub();
s.anotherMethod("Test");
Output will be, Sub Test
Can you anyone help me in telling how to get output Super Test with the given sequences in main.
And let me explain why I want this, say I have a class which has method test() and it can be overriden by sub classes, in some cases I want the overriden test() and in some cases I want the test() of super class itself, there are many ways to do this, best suggestions will be helpful.
Why would you ever want to do that ??
The whole point of polymorphism is to call the right method without the need to know which kind of instance you've got ...
Whenever I find myself asking (or being asked) a question like this, I know, categorically, that I have made a mistake in my design and/or my object definitions. Go back to your object hierarchy and check, double-check and triple-check that every inheritance relationship represents an "IS-A", and not a "HAS-A" or something even weaker.
And let me explain why I want this,
say I have a class which has method
test() and it's can be overriden by
sub classes, some cases I want the
overriden test() and in some cases
test() of super class itself, there
are many ways to do this, it will be
helpful if anyone can be best
solution.
If your subclass overrides test(), then it overrides test() - this is the whole point of object inheritance. You just call methods on the object, which are dynamically resolved to the appropriate implementation based on the object's runtime class. That's the beauty of polymorphic typing, in fact, the caller doesn't have to know about any of this at all, and the subclasses determine how their behaviour differs from the superclass.
If you sometimes want it to act as its superclass method and sometimes want it to act as its subclass method, then you need to provide the context required to do this. You could either define two test-type methods; one which is never overridden and so always returns the superclass' behaviour (you can even mark the definition with final to ensure it's not overridden), and your normal one which is overridden as appropriate by the subclasses.
Alternatively, if there is some contextual information available, you can let the subclasses decide how to handle this; their implementation(s) could check some proeprty, for example, and based on that decide whether to call super.test() or proceed with their own overridden implementation.
Which one you choose depends on conceptually whether your main method (i.e. the caller), or the (sub)class objects themselves, are going to be in the best position to judge whether the superclass' method should be called or not.
But in no case can you override a method and expect it to magically sometimes not be overridden.
You would have to go the route of:
Super s = new Super();
s.anotherMethod("Test");
...but that will defeat the purpose of inheritance if you also need whatever Sub's got. You could hack it like below but this seems an unelegant way to do it.
class Sub extends Super {
public String anotherMethod( String s, boolean bSuper ) {
if( bSuper )
return super.retValue(s);
else
return retValue(s);
}
public String retValue(String s) {
return "Sub " + s;
}
}
From class Sub you can call super.anotherMethod("bla"), but you cannot access the method of the superclass in your main method - that would be against the whole idea of using subclasses.
The runtime type of s is Sub, so you're only ever calling methods on that class.
Whilst I agree with the other posters that this is not the best idea in the world, I believe it could be done with a little bit of tinkering.
If your child class was defined as:
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public void yetAnotherMethodString s) {
super.retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
and then call this new method in your main you would be able to print out "Super Test".
Doesn't seem like a very good plan tho. If you want access to parent functionality from a child class then don't override your parent method, just write a new one!
I'm hesistant to post this as an answer, since the question is quite horrible - but static methods would do roughly what the OP seems to want. Specifically, they are resolved on the compile-time declared class of the variable, not on the class of the instance held within that variable at runtime.
So modifying the original example:
class Super {
public static void staticMethod(String s) {
System.out.println("Super " + s);
}
}
class Sub extends Super {
public static void staticMethod(String s) {
System.out.println("Sub " + s);
}
}
public static void main(String[] args) {
Super s = new Sub();
s.staticMethod("Test");
}
then main() will print out "Super test".
But still don't do this until you understand why you want to, and you recognise that you are introducing subclasses and then gratuitously working around the point of them being there. Most IDEs for example will flag the above example with lots of warnings, saying that you shouldn't call static methods on instance variables (i.e. prefer Super.staticMethod("Test") instead of s.staticMethod("Test")), for exactly this reason.
You cannot modify Sub or Super directly? If you could control what instance of Sub is used you could do something like:
Super sub = new Sub() {
#Override
public String retValue() {
// re-implement Super.retValue()
}
};
otherObject.use(sub);
Of course this requires you to have or be able to reproduce the source code of Super.retValue() and for this method not to use anything you can't access from an anonymous child. If the API is this badly designed though, you might do well to think about changing it out for something else.
Can you anyone help me in telling how
to get output "Super Test" with the
given sequences in main.
Don't overwrite anotherMethod() and retValue() in Sub in the first place.
In Sub.anotherMethod(), return super.retValue(s) instead of retValue(s).

Categories

Resources