Clarification about overriding in Java - java

Using this as an example:
class Animal{
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal{
public void move(){
System.out.println("Dogs can walk and run");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move();// runs the method in Animal class
b.move();//Runs the method in Dog class
}
}
Is it right here to say upon calling b.move() the method "move() under the Dog class" has overridden the "move() under the Animal class" as the Dog object takes precedence when calling the same method when referenced by an Animal type?
Ive noticed many websites don't explain this, rather they just throw out examples without talking through the stuff line by line. Just want to clear up my terminology confusion.
A side note, would it be possible to have a Dog object but invoke move() which is under the Animal class? for example having something like:
Dog doggy = new Dog();
doggy.move()
>>>
Animals can move
>>>
Would this be possible? would ((Animal) doggy).move() accomplish this?

Absolutely, it is correct to say upon calling b.move() the method "move() under the Dog class" has overridden the "move() under the Animal class".
For the second question, you should implement the class Dog as:
public class Dog extends Animal {
public void move(){
super.move();
}
}
For the third question, the answer is "NO".
((Animal) doggy).move()
This is simply 'redundant' and give the output "move() under the Dog class".

You can do it like this
class Animal{
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal{
public void move(){
System.out.println("Dogs can walk and run");
}
public void moveParent() {
super.move();
}
}
public class Main{
public static void main(String args[]){
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move();// runs the method in Animal class
b.move();//Runs the method in Dog class
Dog doggy = new Dog();
doggy.moveParent();
}
}

Use super keyword to call upon the parents member functions or data members.
like: super.move(); in this case you parent function will be called.

From the oracle docs
If two or more independently defined default methods conflict, or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. You must explicitly override the supertype methods.
So basically, if you're in the sub-class calling a method which is in the superclass, you won't be able to call the super-class' method unless you use super.function(). Read up more on it here

It's principle object oriented programming (aka OOP) - polymorphism. Dog, Cat, Elephant are all animal.
Animal d = new Dog();
Animal c = new Cat();
Animal t = new Tiger()
It must not care about, always right. :)

Related

Java A bit confused with Polymorphic concept in Java

Example program:
class Animal {
public void eat() {
System.out.println(" Animal eats");
}
class Dog extends Animal {
public void eat(String s) {
System.out.println(" Dog eats" + s);
}
public class Demo {
public static void main(String args[]){
Animal a = new Dog();
Dog d = (Dog) a;
a.eat();
d.eat("Meat");
}
}
My question is why a.eat("Meat") is not reachable? Since a is Object during the time it's referring to Dog Object, it should allow to call eat("meat").
Can anyone clarify where am I going wrong?
You're trying to call method of subclass Dog through variable of base class Animal.
Java has strong typing, so if you declare variable of class Animal you can access only to methods and fields of Animal and its superclasses.
You can call eat("Meat") from Animal using casting ((Dog) a).eat("Meat") but you should avoid as much as possible such constructions.
Btw, your approach looks like a function overloading rather than polymorphism.
P.S. Maybe this article about strong typing will be helpful for you. And this one about difference between overloading and polymorphism.
Dog d = (Dog) a;
Here you are casting the Animal a to a Dog. However, this does not change the type of a. a is still an Animal hence you can only call eat() without a string.

about downcasting and Polymorphism

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

Java - Upcasting and Downcasting

I Knew there are plenty of articles/questions in stackoverflow describing about upcasting and downcasting in Java. And I knew what is upcasting and downcasting. But my question is not specfic to that.
Upcasting - Conversion from child to parent - Compiler takes care. No cast is required
Downcasting - Conversion from parent to child - Explicit cast is required
public class Animal {
public void getAnimalName(){
System.out.println("Parent Animal");
}
}
public class Dog extends Animal{
public void getDogName(){
System.out.println("Dog");
}
}
public static void main(String[] args) {
Dog d = new Dog();
Animal a = d; // Upcasting
a.getAnimalName();
Animal vv = new Dog();
Dog cc = (Dog)vv;//DownCasting
cc.getAnimalName();
cc.getDogName();
If you look into the Animal and Dog class, each are having their own methods like getAnimalName() and getDogName(). Hence Dog extends Animal(is-a relationship), so we can use the base class(Super Class) methods in the derived class(Subclass)
Consider the below piece of code in the Main Method now,
So here I'm creating a Dog object w.rt Animal. So I can be able to access only the Animal properties(Methods)
Dog d = new Dog();
Animal a = d; // Upcasting
a.getAnimalName();<br>
O/P : Parent Animal<br><br>
Now Let's say, I would like to override the base class methods into the derived class
public class Dog extends Animal{
#Override
public void getAnimalName(){
System.out.println("Parent Animal overridden here");
}
public void getDogName(){
System.out.println("Dog");
}
}<br>
And in Main Method,
Dog d = new Dog();
Animal a = d; // Upcasting
a.getAnimalName();<br>
O/P : Parent Animal overridden here<br><br>
Even though I'm creating a Dog object w.r.t Animal, but here it is printing the base class method which is overridden in the dervied class.
O/P : Parent Animal overridden here<br>
Wondering why it behaves like this. Is this becasue of the override?
Please provide your valuable input's.
When you refer your subclass with parent class, method call on reference pointer calls the subclass method.
Dog d = new Dog();
Animal a = d; // Upcasting
a.getAnimalName();
Here a.getAnimalName(); calls the subclass's getAnimalName() method, as it is inherited from base class, so the parent class's method is called. It is not directly called on base class, rather through subclass's inheritance. When you override, it is instantly invoked from subclass, it does not need to go to parent class to check the existence of the method.
But a side note is that base class reference can't call methods on subclass, which are not defined in base class.
Animal a = d;
this line will make your Animal object 'a' point to the instance of Dog class (Dog d = new Dog();). Therefore when you call the function it will invoke the function in class dog.
You actually created an instance of class Dog Dog d = new Dog();. Then you are making an object of class Animal and making it point to the instance of class Dog Animal a = d;

Difficulty with the concept of java inheritance and overriding [duplicate]

This question already has answers here:
Why bark method can not be called
(5 answers)
Closed 6 years ago.
The Superclass reference variable can hold the subclass object, but using that variable you can access only the members of the superclass, so to access the members of both classes it is recommended to always create reference variable to the subclass.
class Animal {
public void move() {
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Dogs can walk and run");
}
public void bark() {
System.out.println("Dogs can bark");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move(); // runs the method in Animal class
b.move(); // runs the method in Dog class
b.bark();
}
}
output:
TestDog.java:26: error: cannot find symbol
b.bark();
^
symbol: method bark()
location: variable b of type Animal
1 error
What I do not understand here is why is the object 'b' able to access the Dog.move() and not Dog.bark() because the statement mentioned above says it can access only the members of the superclass and not the subclass.Following this logic the output of b.move() should be "Animals can move" and not "Dogs can walk and run".But that is not case.Can anyone help me with this?Thanks in advance!
Congratulations - you just discovered polymorphism.
In Java the classes are bound dynamically. That is if you are invoking a method the implementation of the object is invoked (in your case the Dog) and not the method of the reference type (in your case the Animal).
This allows overwriting methods and replace or fulfill their implementation.
On the other hand, you can only access methods that are available in the type you are referencing, not the implementing type (in your case the Animal). To invoke the methods of the instance, you would have to use it as the reference type (in your case the Dog).
In your question Animal is a parent class which doesn't have bark() method so that method isn't overridden. If you were able to access bark() from parent class without declaring either abstract method or defining it, then that would be violation of the Polymorphism principle.
If you really want to access it that way, then you can either define a abstract public void bark(); in your parent or access that method by typecasting like this
((Dog) b).bark();
This will not compile since Animal does not have a method called bark.
Think of it this way, all dogs are animals, but not all animals are dogs. All dogs bark, but not all animals bark.
This code is wrong, as the line b.bark(); will give you a compiler error, because b is only defined as an Animal, which cannot bark().
If you change Animal b = new Dog(); to Dog d = new Dog(); it will work properly.
You've got inheritance mixed up. Dog can do what Animal can do, not vice versa.
class Animal {
public void move() {
System.out.println("Animals can move");
}
}
class Dog extends Animal {
#Override public void move() {
System.out.println("Dogs can walk and run");
}
public void bark() {
System.out.println("Dogs can bark");
}
public void moveSuper() {
super.move();
}
}
public class TestDog {
public static void main(final String args[]) {
final Animal a = new Animal(); // Animal reference and object
a.move(); // runs the method in Animal class
final Dog d = new Dog(); // Animal reference but Dog object
d.move(); // runs the method in Dog class
d.bark();
d.moveSuper();
}
}

casting a subclass object as superclass

I have some question about upcast/downcast.
I created an abstract super class Animal, subclass Dog and subclass BigDog. and I also give abstract method in Animal, and override it in Dog and BigDog.
abstract public class Animal {
abstract public void greeting();
}
public class Dog extends Animal {
#Override
public void greeting() {
System.out.println("Woof!");
}
}
public class BigDog extends Dog {
#Override
public void greeting() {
System.out.println("Woow!");
}
}
now my test code:
public class TestAnimal {
public static void main(String[] args) {
Animal animal2 = new Dog();
Animal animal3 = new BigDog();
// Downcast
Dog dog2 = (Dog) animal2; //cast Animal class to Dog class, legit
BigDog bigDog2 = (BigDog) animal3; //cast Animal to BigDog, legit;
Dog dog3 = (Dog) animal3; //Animal Class contains BigDog cast into Dog?
dog2.greeting();
dog3.greeting(); //in which class the method is called?
}
}
I understand the relationship between superclass/subclass and how cast works. My question is, however, can you cast a superclass into a specific subclass, knowing there's a class in between? for example, if I have an Animal class object contains a BigDog object, can I cast the object to Dog? what if there are methods in BigDog that do not exist in Dog?
in short, you can certainly say a superclass object is a subclass object, but why can you invert?
On second thought,
I'm guessing this: I'm asking JVM cast an Animal class reference to Dog and link the new Dog reference to the BigDog object, rather than really casting the BigDog object.
So I can invoke all Dog and Animal methods on that Dog reference (to BigDog), but none of the BigDog methods, unless it was overridden in BigDog.
What Java checks when invoking a method is: if the reference (DOG) has the reference, and if the object(BigDog) has an override. if not, Dog method is called, otherwise, BigDog method is called.
Can anyone confirm my guess?
You can always cast to a specific subclass, unless the compiler is smart enough to know for certain that your cast is impossible.
The best way to cast to a subclass is to check if it can be done:
if ( doggy instanceof BigDog ) {
doSomethingWithBigdog( (BigDog) doggy );
} else if ( doggy instanceof SmallDog ) {
doSomethingWithSmalldog( (SmallDog) doggy );
} else {
// Neither a big dog nor a small dog
}
...
private void doSomethingWithBigdog( BigDog dog ) {
...
}
private void doSomethingWithSmalldog( SmallDog dog ) {
...
}
Keep in mind that casting is evil. Sometimes necessary, but often (not always) it can be designed away by implementing methods on the base class, or by not assigning a Dog to an Animal variable but to keep it a Dog.
If I have an Animal class object contains a BigDog object, can I cast the object to Dog? what if there are methods in BigDog that do not exist in Dog?.
Simply you will get compiler error.Since you can't call a method that is not declared in parent and declared in child class using parent reference
There is no method whose signature will match with these method calls :
dog2.greeting(dog3);
dog3.greeting(dog2);
so, Its pretty much a compilation failure.
You need to know about Dynamic Method Dispatch.
here are few links 1,2,3 go through them.
First correct the source code, so it will compile. The proper usage of the methods: dog2.greeting(); and dog3.greeting(); or add method public void greeting(Animal animal);.
dog3.greeting(); - invoking method greeting() for dog3. dog3 has the same reference as animal3. animal3 has reference of BigDog so method greeting() is invoked to the class BigDog and the output is Woow!
When you inherit Dog from class Animal, then class Dog have all methods from class Animal.

Categories

Resources