I have created base class animal and child class as cat.
In main, I want to create obj of PARENT class and call the method of child class.
So, is it possible or not?
I have also used instanceOf to just check relationship
public class Animal
{
public void eats()
{
System.out.println("Animal Eats");
}
}
public class Cat extends Animal
{
public void walks()
{
System.out.println("Cat Walks");
}
}
public class AnimalMain
{
public static void main(String args[])
{
Animal a=new Animal();
display(a);
}
public static void display(Animal a)
{
a.eats();
if(a instanceof Cat)
((Cat)a).walks();
}
}
Your code should work fine. The if condition will result in false, so your animal will not walk().
Animal animal = new Animal();
This animal will have all the behaviours of Animal, i.e. eat(), but none of the behaviours of the sub-class Cat, i.e. walk().
If you want your animal to have all the behaviours of Animal as well as all the behaviours of Cat, you need to instantiate the Cat class.
Animal animal = new Cat();
Now your animal will eat and walk.
Yes, it will. You are changing the type, so it will work.
Related
class Animal {
String type;
int size;
public Animal(String name, int size)
{
this.type = name;
this.size = size;
}
public Animal ()
{
}
public void run() {
System.out.println("I can run!");
}
}
class Cat extends Animal {
String color;
public void meow() {
System.out.println("I can meow!");
}
}
public class HelloWorld{
public static void main(String []args){
Animal cat = new Cat();
cat.meow();
cat.run();
}
}
Why is it when I try to create a new Cat object from the superclass Animal, I get an error with the .meow() part of the code. Specifically "error: cannot find symbol cat.meow();" . Aren't I creating a Cat object so shouldn't it have access to the methods in there?
Animal is the base class. If you extend Animal you can add additional methods and instance variables in that class, which you actually did correctly.
As soon as you instantiate a child class (class that extends the base class, e.g.: new Cat()) but assign it to the type of the base class (Animal) you can only call the methods that are available there, i.e. in your case you could only call methods that are declared in the Animal class.
Lets assume you have a class Animal :
public class Animal {
public void makeSound() {
System.out.println("Default sound");
}
}
Now you create a class Cat that extends Animal:
public class Cat extends Animal {
private int catProperty = 5;
//Override method of base class
public void makeSound() {
System.out.println("Meow");
}
public int getCatProperty(){
return this.catProperty;
}
}
An another class called Dog that extends Animal:
public class Dog extends Animal {
private int dogProperty = 8;
//Override method of base class
public void makeSound() {
System.out.println("Woof");
}
public int getDogProperty(){
return this.dogProperty;
}
}
Since Animal is the base class you can now create an array of type Animal which holds Cats and Dogs.
Animal[] animals = new Animal[2];
animals[0] = new Cat();
animals[1] = new Dog();
for (Animal animal : animals) {
animal.makeSound();
}
Each of the animals (Cat and Dog) will now print the proper sound.
In case you really need to call a child class specific method, you have to cast the object back to an instance of that child class. In that case you have to be sure of what type the child class is.
E.g.:
for (Animal animal : animals) {
// Calls overriden method
animal.makeSound();
// This is illegal. Method getCatProperty is not declared in Animal
animal.getCatProperty();
// This is illegal. Method getDogProperty is not declared in Animal class
animal.getDogProperty();
/*
* IF YOU HAVE TO CALL CHILD CLASS SPECIFIC METHODS, DO IT LIKE THIS:
*/
// Checks if animal is of type Cat
if (animal instanceof Cat) {
// Casts animal to instance of Cat
Cat cat = (Cat) animal;
// Calls specific Cat instance method
System.out.println(cat.getCatProperty());
}
// Checks if animal is of type Dog
if (animal instanceof Dog) {
// Casts animal to instance of Dog
Dog dog = (Dog) animal;
// Calls specific Dog instance method
System.out.println(dog.getDogProperty());
}
}
Just as a sidenote: If you plan not to directly create instances of Animal (Animal a = new Animal()), you should declare the class itself and the methods that should be overriden by child classes as abstract.
public abstract class Animal {
public abstract void makeSound();
}
Also, in case that base class only has methods and no instance variables that should be available to the child classes, it's probably better use an interface instead of a (abstract) class.
public interface Animal {
public abstract void makeSound();
}
The interface then has to be implemented (not extended) by the concrete class.
public class Cat implements Animal {
public void makeSound() {
System.out.println("Meow");
}
}
Hope this helps!
Animal cat = new Cat()
The compiler "forgets" that you created a Cat instance.
Your sourcecode says: I have a variable named cat that is an instance of Animal.
There is no method meow() on the Animal class.
If you want to call a subclass method, you need a subclass instance:
Cat cat = new Cat();
cat.meow();
or you need to cast. Basically you tell the compiler: "I know better than you".
Animal cat = new Cat();
( (Cat) cat).meow();
The point is: java is statically typed. In python, the interpreter would just see if that cat thingy has a method called meow() that it could call. Doesn't work like that in Java.
I am very new to reflections and I would like to get some advices/help. I am trying to get the subclass names using reflection in the base class. I have multiple subclasses (Cat, Dog, Frog etc..) and all of them extend the base class (Animal).
What I want to do is getting the class names from the subclasses themselves and pass them through the constructors so the Animal does not have to instantiate dozens of subclasses. Below is an example of what I am NOT trying to do.
If there is a way to just dynamically get the subclasses names without going through the pain of instantiating every single subclass, I would love to see it. Your help is much appreciated.
class Dog extends Animal {
private String s;
public Dog() {
s = "Bark";
}
public void method() {
System.out.println("Dogs " + s);
}
}
class Cat extends Animal {
private String s;
public Cat() {
s = "Meow";
}
public void method() {
System.out.println("Cats " + s);
}
}
class Animal {
public static void main(String args[]) throws Exception {
Dog dog = new Dog();
Cat cat = new Cat();
Class cls = dog.getClass();
System.out.println("The name of class is " + cls.getName());
Constructor constructor = cls.getConstructor();
System.out.println("The name of constructor is " + constructor.getName());
}
}
I do not see why you want the names of the subclasses. If the problem is to instantiate a class based on its name it would be better to use an Abstract Factory pattern. You can create an enumeration that contains the animal that you knows
enum ANIMALS {
DOG, CAT
}
You can create the Animal interface
public interface Animal {
}
the classes extending Animal as default classes
public class Dog implements Animal {
}
then finally the AnimalAbstractFactory as
public class AnimalAbstractFactory {
public enum ANIMALS {
DOG, CAT
}
public Animal createAnimal(ANIMALS animal) {
switch (animal) {
case DOG:
return new Dog();
case CAT:
return new Cat();
}
return null;
}
}
Notes that now you do not need to know the subclass to instantiate an animal. Note also that createAnimal returns an Animal not the subclass. I hope it helps.
why do I have to write like this
animal a = new cat();
cat b = (cat)a;
b.makesound();
a.makesound();
but not like this
animal a = new cat();
animal b = new cat();
a.makesound();
b.makesound();
they give the same outputs
This is the entire code.
public class DownCasting
{
public static void main(String args[])
{
animal a = new cat();
cat b = (cat)a;
b.makesound();
a.makesound();
}
}
class animal
{
public void makesound()
{
System.out.println('w');
}
}
class cat extends animal
{
public void makesound()
{
System.out.println("meow");
}
}
so downcasting just give an object second name? or it has other uses?
In the second variant, you create two cats.
In the first, you assign the additional name b to the already existing animal a.
so downcasting just give an object second name? or it has other uses?
You might want to have a list of animals, f.ex. a dog:
class dog extends animal
{
public void makesound()
{
System.out.println("woof");
}
}
could be combined in the same list with cats.
Casting is the process of forcefully making a variable behave as a variable of another type. If a class shares an IS-A or inheritance relationship with another class or interface, their variables can be cast to each other’s type.
public class DownCasting
{
public static void main(String args[])
{
animal a = new cat();
cat b = (cat)a;
b.makesound();
a.makesound();
}
}
class animal
{
public void makesound()
{
System.out.println('w');
}
}
class cat extends animal
{
public void makesound()
{
System.out.println("meow");
}
}
In the line animal a = new cat(); you are using a variable of type Animal to refer an object of type Cat, and a.makesound(); will print "meow" because with inheritance, the instance methods bind at runtime.
However, if you try to do cat b = a; (without casting) the Java Compiler will try to use a variable of type Cat to reference an object of type Animal, and that is not possible (you cannot use a variable of a sub-class to reference (execute) methods from a super-class), so it is necessary cast the variable to indicate to the java compiler that it can be sure that despite a is a variable of type Animal, is actually a Cat.
Let me give you an example to make this more clear:
I have your two classes with some modifications:
class animal
{
public void makesound()
{
System.out.println('w');
}
void sleep(){
System.out.println("ZZZ");
}
}
class cat extends animal
{
public void makesound()
{
System.out.println("meow");
}
void play(){
System.out.println("I´m playing");
}
}
both classes now have a method that the other class does not have.
Now let's use it:
public class DownCasting
{
public static void main(String args[])
{
animal a = new cat();
}
}
If I do a.play(); it will give me a compilation error because Java searchs for the method play() inside the Animal Class and cannot find it... Why java does that? as I already said: "With inheritance, the instance methods bind at runtime", so if I want to call that method I have to cast the a variable... ((Cat)a).play();
But what happen if you try to do it the other way around?
Cat c = new Animal(); //This line will never compile...
So, I can cast it like this in order to make it compile:
Cat c = (Cat)new Animal();
c.play();
BUT, in runtime it will throw a java.lang.ClassCastException why?, because you cannot use a variable of a sub-class to reference (execute) methods from a super-class.
To sum up, remember that the type of the object reference variable and the type of the object being referred to may be different.
But there are rules on how different these can be.
To this topic I will recommend you OCA Java SE 7 Programmer I Certification Guide: Prepare for the 1ZO-803 exam specifically the chapter 6.
why do I have to write like this
to answer this question you need to know first what can make a sound?
the cat or the animal?
you do this :
animal a = new cat();
a.makesound();
when the method makesound is declared in animal
if not then you need to cast
In other words how to force a method to only use subclasses of the given input parameter which is a superclass?
Example:
public class Animal {
...
}
public class Dog extends Animal {
...
}
public class Cat extends Animal {
...
}
public class Test {
...
public void makeSound(Animal animal) throws Exception{
if(animal instanceof Dog){
System.out.println("bark");
} else if (animal instanceof Cat) {
System.out.println("meow");
} else {
throw new Exception ("Not valid subclass of Animal");
}
}
}
The code above seems somehow wrong, is there a better, more efficient or generic way?
To avoid doing the instanceof check for each subtype, you can create an abstract makeSound() method in Animal class, and override in all the subclasses. I would make the Animal class abstract, as it really is an abstract entity in your scenario:
abstract class Animal {
abstract void makeSound();
}
class Dog extends Animal {
void makeSound() { System.out.println("Bark"); }
}
class Cat extends Animal {
void makeSound() { System.out.println("Meow"); }
}
and then in Test class, just invoke makeSound on Animal reference. It will call appropriate overridden method based on actual instance:
public void makeSound(Animal animal){
animal.makeSound();
}
Now, everytime you add a new subtype of Animal, you just need to override makeSound() in that class. With abstract method, you will be forced to do that. And keep the Test#makeSound() method unmodified.
class Test {
public static void main(String[] args) {
Animal a = new Dog();
Dog d = new Dog();
d.makeNoise(); // output "Sub"
a.makeNoise(); // output "Sub" then what is use of calling this. why not call d.makeNoise() only.
}
}
abstract class Animal {
public void makeNoise() {
System.out.println("Super");
}
}
class Dog extends Animal {
#Override
public void makeNoise() {
System.out.println("Sub");
}
}
We had 15 minutes discussion over this topic(15 minutes is too long I guess) I explained interviewer about how dynamic polymorphism will be achieved with the help of a.makeNoise(); but still she was saying both are giving same output.
a.makeNoise(); output "Sub" then what is use of calling this. why not call d.makeNoise() only
I went to interface also but still question was if subclass reference is giving same output then why to use superclass reference.
Interviewer question was, what difference a.makeNoise(); makes? why not call d.makeNoise(); only when both are giving same output?
What could be the possible correct answer?
Animal a = new Dog(); // this animal is a dog
Dog d = new Dog(); // this dog is a dog
A dog is a dog, however you declared it.
a.getClass() equals d.getClass() equals Dog.class.
On the other hand:
Animal a = new Animal(); // this animal is an animal
a.makeNoise(); // prints "Super"
The example below illustrates dynamic polymorphism. Both a and d are declared to be Animals, but d is actually a dog.
Notice that when I call makeNoise on the Animal d, java will know that d is actually a dog and not just any animal.
class Test {
public static void main(String[] args) {
Animal a = new Animal();
Animal d = new Dog();
d.makeNoise(); // output "Bark" - d is an animal that barks
a.makeNoise(); // output "Squawk" - a is an animal that squawks
}
}
class Animal {
public void makeNoise() {
System.out.println("Squawk");
}
}
class Dog extends Animal {
#Override
public void makeNoise() {
System.out.println("Bark");
}
}
This is the reason-
Animal a = new Dog();
Animal is dog so noise would be same :)
If create another animal, say Cat, with that method, and point animal to Cat, you should get a different noise.
Your simplified example does not present the case well enough.
Collection<Animal> caged = getCagedAnimals();
for (Animal a : caged)
a.makeNoise();
As there are many types of animals (classes), each makes a different noise. We do not need any typecasting to obtain different behavior, so to say. Imagine the horrors which would happen if we would want each animal to make a noise without polymorphism:
for (Animal a : caged) {
if (a instanceof Dog)
((Dog)a).woof(); // or, ((Dog)a).makeNoise()
else if (a instanceof Cat)
((Cat)a).meow(); // or, ((Cat)a).makeNoise()
else {...}
}
Let us have an object of type T. We are trying to invoke toString() (defined by Object class)
Dynamic method invocation proceeds as follows (actually, a virtual method table is used):
C = T
do
if (C defines toString()) {
call T.toString()
break
}
C = superclass of C
while (C != null)
throw new NoSuchMethodError();
Now, if we have
Object obj = new T();
and we call
obj.toString();
we are actually calling toString() of class T.
consider there are 3 classes
animal
dog
cat
cat and dog are sub classes of animal.
class Test {
public static void main(String[] args) {
Animal a = new Animal();
int user_input=userinput(); //returns 1 for cat and 2for dog
switch(user_input)
{
case 1:Animal d=new Cat();
break;
case 2: Animal d=new Dog();
break;
}
d.makeNoise(); // output "Bark"/"meow" as per user input(dynamic linking)
a.makeNoise(); // output "Squawk" - a is an animal that squawks
}
}
class Animal {
public void makeNoise() {
System.out.println("Squawk");
}
}
class Cat extends Animal {
#Override
public void makeNoise() {
System.out.println("meow");
}
}
class Dog extends Animal {
#Override
public void makeNoise() {
System.out.println("Bark");
}
}
class Account {
public static void main(String[] args) {
Animal a = new Dog();
Dog d = new Dog();
d.makeNoise();
a.makeNoise();
a = new Cat();
a.makeNoise();
}
}
abstract class Animal {
public void makeNoise() {
System.out.println("Super");
}
}
class Dog extends Animal {
public void makeNoise() {
System.out.println("Sub");
}
}
class Cat extends Animal {
}
See the above modified example and the observations
We have an abstract class Animal with an implementation for makeNoise (let me say default implementation here)
We have a Dog class which is of Type animal but has a customized makeNoise methods
We have a Cat Class which is of Type animal but has no customized makeNoise methods. it uses default makeNoise of Animal type.
if I use Animal a = new Dog() and a.makeNoise(), then I can remove my makenoise method from Dog class whenever I wish with no changes to any other class. It will still compile and execute without any error.
if I use Dog d = new Dog() and d.makeNoise(), then I cannot remove my makenoise method from Dog class whenever I wish. if I do, I also need to change the main class for the application to compile.
i will give one general ex:- personA has one bank account he has all permissions on that account(withdraw,deposit,loanetc). personB wants to deposit money into personA account in this time he wants to access personA's account but we have to provide deposit permissions only.
class perosnB
{
public void deposit()
{
................
}
}
class personA extends personB
{
public void deposit()
{
......
}
public void withdraw()
{
......
}
}
personA p=new personB();
PersonB p2=new personB();
by using p object we can access only withdraw method. by using p2 we can access deposit also.
weather personA class is abstract or not. if personA is abstract class creating object for personA class is not possible( personA p=new personA()) . personA p=new personB() is possible.
Animal a = new Dog();
a is a a reference of type Animal but it refers to the object of type Dog.
Here Dog overrides makeNoise() method of Animal class.
class Animal {
public void makeNoise() {
System.out.println("Squawk");
}
}
class Dog extends Animal {
#Override
public void makeNoise() {
System.out.println("Bark");
}
}
Since object is of Dog class JVM will bind Dog class' makeNoise() method to the object and binding will be done at runtime.
so the Output of
a.makeNoise();
will be
sub