Why can this object access methods of it's parent class? - java

This question is taken from an AP Computer Science practice test.
public class Bird
{
public void act()
{
System.out.print("fly");
makeNoise();
}
public void makeNoise()
{
System.out.print("chirp");
}
}
public class Dove extends Bird
{
public void act()
{
super.act();
System.out.print("waddle");
}
public void makeNoise()
{
super.makeNoise();
System.out.print("coo");
}
}
Suppose the following declaration appears in a class other than Bird or Dove:
Bird pigeon = new Dove();
What is printed as a result of the call pigeon.act()?
I thought the answer would be "fly chirp", but the textbook says that the answer is "fly chirp coo waddle". I thought that 'pigeon' could only access methods available in Bird? I was under the impression that, if the user wanted to access methods in Dove, 'pigeon' would have to be cast to Dove.
Would Bird pigeon = new Bird(); give the same output? How about Dove pigeon = new Dove();?

Long story short, when you access act method of pigeon, its override from Dove is called.
I thought that 'pigeon' could only access methods available in Bird?
That is certainly true, at least, for situations when no casting is applied. However, method act is available on the class Bird, the statically known type of pigeon, so the call compiles fine.
However, accessing methods is only about being able to call them. What methods do when you call them is decided at runtime based on the dynamic type of pigeon. This is where method overriding comes into play, because Dove overrides Bird's methods, but in addition it also calls Bird's methods. That is why the code hits all four printouts.
Would Bird pigeon = new Bird(); give the same output?
No, the output would be different, because in this case both dynamic and static types of pigeon would be the same, i.e. Bird, so only Bird's implementations would be invoked.

the class Dove does override the methods act and makeNoise of class Bird. Overriding means changing the behavior of a method visible to the sub-class, (in your case Dove). Methods are visible to a sub-class if they have a public or protected access modifier or if they have a package private access modifier and the sub-class belongs to the same package as the super-class does.
pigeon is an instance of Dove.
calling pigeon.act() results in calling Dove.act.
Dove.act calls super.act which is Bird.act.
Bird.act prints fly and calls makeNoise on pigeon resulting in calling Dove.makeNoise.
Dove.makeNoise calls super.makeNoise which is Bird.makeNoise.
Bird.makeNoise print chirp.
Dove.makeNoise prints coo after calling super.makeNoice

What you experience here is polymorphism in action. And instead of answering your various questions directly; I will simply explain the case you are observing.
You call act() on an instance of Dove; that causes a call to super; printing "fly".
That super method then calls makeNoise() ... on "itself". But as said: "itself" is a Dove object; thus you get the Dove noise! "coo"!
Then the Dove implementation ends; and prints "waddle".
The essence is: the exact version of a method that is invoked is determined at runtime and it only depends on the exact type of the object the method is invoked on.
The above gives you all the information you need to answer your other questions yourself. In that sense: don't request answers; ask for explanations; and use those to solve the puzzle yourself!

From your question "I thought that 'pigeon' could only access methods available in Bird? I was under the impression that, if the user wanted to access methods in Dove, 'pigeon' would have to be cast to Dove." This is actually true.
Lets try to find the mssing link in the understanding.
When we have code like Bird pigeon = new Dove(); where Dove extends Bird we have actual object of Dove and reference type is of Bird. As the object is of Dove so it has the methods, both inherited from super class as well as the ones which are added.
Another important point is all the overriden methods have only one instance. Its Overriden meaning the behavior of the same method has been modified, its not an additional separate method. There is only one copy of inherited method not both. Its the overloaded methods which are separate, just the names are same but signature is different. This is the reason you get the behaviour of Dove when you invoke any overriden method.
This one is simple super , using it a sub class can access the accessible (visible) entities (instance properties and methods) of its super class. If a sub class uses super keyword to invoke a method then its the method of the parent class which gets invoked. But again this can be considered that the author of the sub class did it intentionally. Once the class is written and Objects of such class is created then on the object using . (dot operator) users can only invoke whats there in the object. If any method has used super keyword its part of the behavior of the object. Users of the Sub class object can not invoke behavior of the parent class method if its overridden in sub class.
Lastly yes if you wish to invoke any additional method of Dove (Sub class ) using a reference of Bird (Super class) then you need to cast it to Dove.

Related

Why do we need abstract methods?

I have been studying abstract methods lately and I can't understand why do we need them?
I mean, after all, we are just overriding them. Do you know its just a declaration? Why do we need them?
Also, I tried understanding this from the internet and everywhere there's an explanation like imagine there's an abstract class human then there're its subclasses disabled and not disabled then the abstract function in human class walking() will contain different body or code. Now what I am saying is why don't we just create a function in the disabled and not disabled subclasses instead of overriding. Thus again back to the question in the first paragraph. Please explain it.
One of the most obvious uses of abstract methods is letting the abstract class call them from an implementation of other methods.
Here is an example:
class AbstractToy {
protected abstract String getName();
protected abstract String getSize();
public String getDescription() {
return "This is a really "+getSize()+" "+getName();
}
}
class ToyBear extends AbstractToy {
protected override String getName() { return "bear"; }
protected override String getSize() { return "big"; }
}
class ToyPenguin extends AbstractToy {
protected override String getName() { return "penguin"; }
protected override String getSize() { return "tiny"; }
}
Note how AbstractToy's implementation of getDescription is able to call getName and getSize, even though the definitions are in the subclasses. This is an instance of a well-known design pattern called Template Method.
The abstract method definition in a base type is a contract that guarantees that every concrete implementation of that type will have an implementation of that method.
Without it, the compiler wouldn't allow you to call that method on a reference of the base-type, because it couldn't guarantee that such a method will always be there.
So if you have
MyBaseClass x = getAnInstance();
x.doTheThing();
and MyBaseClass doesn't have a doTheThing method, then the compiler will tell you that it can't let you do that. By adding an abstract doTheThing method you guarantee that every concrete implementation that getAnInstance() can return has an implementation, which is good enough for the compiler, so it'll let you call that method.
Basically a more fundamental truth, that needs to be groked first is this:
You will have instances where the type of the variable is more general than the type of the value it holds. In simple cases you can just make the variable be the specific type:
MyDerivedClassA a = new MyDerivcedClassA();
In that case you could obviously call any method of MyDerivedClassA and wouldn't need any abstract methods in the base class.
But sometimes you want to do a thing with any MyBaseClass instance and you don't know what specific type it is:
public void doTheThingsForAll(Collection<? extends MyBaseClass> baseClassReferences) {
for (MyBaseClass myBaseReference : baseClassReferences) {
myBaseReference.doTheThing();
}
}
If your MyBaseClass didn't have the doTheThing abstract method, then the compiler wouldn't let you do that.
To continue with your example, at some point you might have a List of humans, and you don't really care whether they are disabled or not, all you care about is that you want to call the walking() method on them. In order to do that, the Human class needs to define a walking() method. However, you might not know how to implement that without knowing whether the human is or isn't disabled. So you leave the implementation to the inheriting classes.
There are some examples of how you'd use this in the other answers, so let me give some explanation of why you might do this.
First, one common rule of Object Oriented Design is that you should, in general, try to program to interfaces rather than specific implementations. This tends to improve the program's flexibility and maintainability if you need to change some behavior later. For example, in one program I wrote, we were writing data to CSV files. We later decided to switch to writing to Excel files instead. Programming to interfaces (rather than a specific implementation) made it a lot easier for us to make this change because we could just "drop in" a new class to write to Excel files in place of the class to write to CSV files.
You probably haven't studied this yet, but this is actually important for certain design patterns. A few notable examples of where this is potentially helpful are the Factory Pattern, the Strategy Pattern, and the State Pattern.
For context, a Design Pattern is a standard way of describing and documenting a solution to a known problem. If, for example, someone says "you should use the strategy pattern to solve this problem," this makes the general idea of how you should approach the problem clear.
Because sometimes we need a method that should behave differently in its instances.
For example, imagine a class Animal which contains a method Shout.
We are going to have different instances of this Animal class but we need to implement the method differently in some cases like below:
class Animal:
/**
different properties and methods
which are shared between all animals here
*/
...
method shout():
pass
class Dog extends Animal:
method shout():
makeDogVoice()
class Cat extends Animal:
method shout():
makeCatVoice()
dog = new Animal
cat = new Animal
dog.shout()
cat.shout()
So dog shouts like dogs, and cat shouts like cats! Without implementing the shared behaviors twice
There is a different behavior of shouting in these instances. So we need abstract classes.
Suppose you don't know about implementation and still want to declare a method then we can do that with the help of abstract modifier and making it an abstract method. For abstract method only declaration is available but not the implementation. Hence they should end with ;
Example:
public abstract void m1(); // this is correct
public abstract void m1(){ ... } // this is wrong
Advantage: By declaring abstract method in parent class we can provide guideline to child classes such that which methods are compulsory to implement.
Example:
abstract class Vehicle{
abstract int getNoOfWheels();
}
Class Bus extends Car{
public int getNoOfWheels(){
return 4;
}
}
If you want the short answer, think of this:
You have an abstract class Car.
You implement 2 classes that extend it, Ferrari and Mercedes.
Now:
What if you did one of the following, for the method drive(), common to all cars:
1) changed the visibility of the method,
2) changed the name of the method from driving to Driving,
3) changed the return type, from a boolean to an int
Think about it. It might not seem to make any difference right, because they are different implementations?
Wrong!
If I am iterating through an array of cars, I would have to call a different method for each type of car, thereby making this implementation of abstract useless.
Abstract classes are there to group classes with a common template, that share common properties. One way this helps would be the looping over the array:
Abstract methods ensure that all cars declare the same method,
and therefore, any object of a subclass of Car will have the method drive(), as defined in the abstract class, making the for loop mentioned easy to implement.
Hope this helps.

Why is overriding in JAVA working somewhat differently that from C++?

I have some background in C++ and know some Java too (apparently far from enough).
When I see overriding behavior in Java or C++, it does not seem to differ much. Given below example in JAVA:
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
}
}
In Java, you use a base class reference, in C++ you use a base class pointer, and depend on the type of instance it points to (a base class object instance or a subclass instance), you can achieve polymorphism.
The above is based on you call the instance method using a base class reference or pointer, right?
Now I see this example in Java.
What is the order of the Constructors in this Java Code?
Basically it says if a base class function is overriden, then in the process of creating a subclass object, even the base class initialization portion will be affected. See below explanation I copied from above link:
new Son()
=>
Son._init
=> first every constructor calls super()
Father._init
Object._init
who() => is overridden, so prints "son" !!!!!
tell(name) => name is private, so cannot be overridden => "father"
who() => "son"
tell(name) => "son"
Why should this happen? I mean does this conform to how polymorphism should be use? When making base class portion of initialization, why use overrided function from subclass?
In Java doc http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5, I only find this:
"Unlike C++, the Java programming language does not specify altered rules for method dispatch during the creation of a new class instance. If methods are invoked that are overridden in subclasses in the object being initialized, then these overriding methods are used, even before the new object is completely initialized. "
But I don't know the reason behind it, and it feels strange.
Any thoughts?
This is one of the extremely rare cases where C++ is trying to protect you from shooting yourself in the foot more than Java does. (Or at least it has the noble intention to do so.)
You are very likely to shoot yourself in the foot in any language if you try invoking an overridable (virtual) method M of your base class B from within the constructor of B. That's because M is likely to be overridden in derived class D, but at the moment that B is being constructed, D has not been constructed yet. So, D.M is being invoked before the constructor of D has been invoked. That can spell disaster.
So, Java simply allows this to happen, use at your own risk. (If you have sufficient warnings enabled, your compiler will tell you that you are living life dangerously.)
C++ does not prohibit this either, but it slightly changes its behaviour so as to contain the damage, so to speak: when you invoke a virtual method from within a constructor, it does not really invoke it as a virtual method, (with a VMT lookup,) but it invokes it directly, as a non-virtual method.
(Either that, or from within the constructor of B it simply uses class B's VMT instead of D's VMT. Which, come to think of it now, makes sense. But I am not sure about that, it has been a long time since I last troubleshot this behaviour of C++.)

In Java what is the difference between "invoke a constructor" and "execute a constructor"?

I really don't have an example, but I get confused between the two terms, as sometimes one is used and sometimes the other is used.
When a constructor is "invoked" is it also "executed"? Are they interchangeable?
Also, the word "call" is used a lot, as in "call a constructor".
And then there is "constructor completes".
I'm sure I'm not alone in my confusion, so an explanation with an example would be very helpful for many of us newbies trying to make sense of all of the terms.
I am using the Bates and Sierra book and here is the section that got me thinking about it:
"But what really happens when you say new Horse() ?
(Assume Horse extends Animal and Animal extends Object.)
1. Horse constructor is invoked. Every constructor invokes the constructor
of its superclass with an (implicit) call to super(), unless the constructor
invokes an overloaded constructor of the same class (more on that in a
minute).
2. Animal constructor is invoked (Animal is the superclass of Horse).
3. Object constructor is invoked (Object is the ultimate superclass of all
classes, so class Animal extends Object even though you don't actually
type "extends Object" into the Animal class declaration. It's implicit.) At
this point we're on the top of the stack.
4. Object instance variables are given their explicit values. By explicit values,
we mean values that are assigned at the time the variables are declared,
like "int x = 27", where "27" is the explicit value (as opposed to the
default value) of the instance variable.
5. Object constructor completes.
6. Animal instance variables are given their explicit values (if any).
7. Animal constructor completes."
The terms "invoke", "execute", and "call" mean the same thing and are interchangeable. What is meant by "constructor completes" is that the constructor finishes its invocation, or execution, or call, whatever your prefer.
Yes, they all mean the same thing. You might want to survey information on the topic from a few different sources whenever a textbook gets confusing. A very good place to look would be the official Java Tutorials, e.g. on constructors, which always has plenty of simple examples.
Technically, you "call"/"invoke" a method, it then gets "executed" and then "completes". And technically, if you have polymorphism there is an additional step "lookup which method should really be executed" between the "call"/"invoke" and "executed" steps.
"Invoke" is the same as "call" is the same as "execute", when talking about constructors or any other method.
A constructor is just another method, albeit a special one.
Best way to understand is by giving a sample of code:
class Animal {
public Animal(){}
}
class Horse extends Animal {
public Horse(){
super();//this line will be added by the compiler even if you didn't type it.
}
public Horse(String name){
this(); //this line will call the default constructor.
}
}
invoking the constructor is creating an instance from its class:
Horse horse = new Horse();
calling the constructor is done by:
super();//in our case it will call Animal constructor
or
this();//this will call the default constructor of the same class.
and you execute the constructor by calling or invoking it.
Iam pretty sure they are the same once the object is created or made the constructor is automatically called or invoked or indeed executed.

Misunderstanding Dynamic Binding

From what I understand about dynamic binding, the JVM, at runtime, looks at the actual type of an object and searches for an implementation in that class and works its way up through the inheritance levels.
For example if we have: Vehicle v = new Car();
Assuming that the class Car extends Vehicle, we can see that the reference variable type is Vehicle and the object type is Car.
If we were to say: v.start():
The JVM would look for the start method implementation first in the Car class and then in the Vehicle class.
An example of this is in this code:
public class scratch{
public static void main(String [] args){
Vehicle v = new Car();
v.start();
}
}
class Vehicle{
public void start(){
System.out.println("Vehicle class");
}
}
class Car extends Vehicle{
public void start(){
System.out.println("Car class");
}
}
The output of this code, as expected is: "Car class"
This is my question: If I take out the start method from class Vehicle, completely erase it, the program won't run anymore. From what I understand about dynamic binding, the JVM should still look at the actual type of the object (which in this case is Car) and still run the car implementation of the start method. However, it does not do this.
Why?
The problem with removing start() from Vehicle has to do with polymorphism. In Vehicle, if you define start() here, then that is what says that all Vehicles, even subclasses, have that method.
If you remove start() from Vehicle(), then it can't be guaranteed that any Vehicle has a start() method, even though we know it's a Car that does have start(). What if there is a HorselessCarriage class that extends Vehicle but doesn't define start()? Then, there is no start() method. For that reason, if there's no start() method on Vehicle, you can't call start() on a Vehicle variable.
The whole point of being able to call start() on a Vehicle is to ensure that any Vehicle implementation has a start() method to call.
UPDATE
The JVM takes the runtime type of the object and looks for a method matching the signature of the method call. If not found, it walks up the inheritance tree to the superclass and looks for the method there.
More details are given in the JLS, Section 15.12.4.4:
Let X be the compile-time type of the target reference of the method
invocation. Then:
If class S contains a declaration for a non-abstract method named m
with the same descriptor (same number of parameters, the same
parameter types, and the same return type) required by the method
invocation as determined at compile time (§15.12.3), then:
If the invocation mode is super or interface, then this is the method
to be invoked, and the procedure terminates.
If the invocation mode is virtual, and the declaration in S overrides
(§8.4.8.1) X.m, then the method declared in S is the method to be
invoked, and the procedure terminates.
If the invocation mode is virtual, and the declaration in S does not
override X.m, and moreover X.m is declared abstract, then an
AbstractMethodError is thrown.
Otherwise, if S has a superclass, this same lookup procedure is
performed recursively using the direct superclass of S in place of S;
the method to be invoked is the result of the recursive invocation of
this lookup procedure.
Here, S appears to be the runtime type of the object.
In nutshell, JVM need one endpoint to begin the search for the reference of the start method, not matter the object type have a method that you want to invoke, JVM need a mirror to ensure you are trying to call an existing method.
When you have the start() method in the Vehicle class, Car is Overriding that method. When you remove the start() method from Vehicle, you are no longer overriding that method. So calling v.start() has no method to call. This is why you should use #Override, so that it is clear in the code what is happening. In order to call start() on Car in the case where there is no start() method in Vehicle, you'd first have to cast the vehicle to the Car class.
But once you remove the method, Vehicle no longer has any "start" functionality: it is an unknown method in the Vehicle class, and you are accessing it through a Vehicle reference. To make java do what you want, you could do
abstract class Vehicle
{
public abstract void start();
}
Your code should then work again, because all children of Vehicle are now guaranteed a start method. But as it stands in your example, once the start method is removed, there's no guarantee that some previous statement hasn't created some other Vehicle descendant, e.g., Motorcycle without a start method and assigned it to your v reference.
I think a simple way to see the problem is to introduce a method. Here's how the method is defined:
public void callStart(Vehicle vehicle) {
vehicle.start();
}
This method lets you pass in a concrete Car or a concrete Vehicle.
Lets pretend that Java lets you compile this code. If Java let you do this for a Vehicle without a start() method, then you'd have to discover the error at runtime. But Java saves you some time by letting you know when you've compile that you have an error.
This is different from some dynamic languages like Javascript. If this were JavaScript you could pass in a concrete Vehicle and then you'd have to discover your error at runtime. Another difference is that in JavaScript, you could pass in a concrete Car and it would work without error. This is called duck typing and is a feature Java doesn't have.

Bates and Sierra java scjp chapter 2 has-a

public class Horse extends Animal {
private Halter myHalter = new Halter();
public void tie(LeadRope rope) {
myHalter.tie(rope); // Delegate tie behavior to the
// Halter object
}
}
public class Halter {
public void tie(LeadRope aRope) {
// Do the actual tie work here
}
}
Is the tie method in Horse class overriding the tie method in the Halter class? Why is the tie method declaration and signature almost exactly the same?
No, it is not overriding the method in Halter, because Horse does not extend Halter.
This is an example of a delegate (as mentioned in the comment). Maybe also of the Facade pattern (put all horse-business in one place, even though it could be done by going through all the other classes directly).
This is the difference between IS-A and HAS-A relationships. A horse has a halter (but it is no halter).
Why is the tie method declaration and signature almost exactly the same?
Because they do the same thing: Tie the receiver to the lead rope.
As it happens, you can tie both halters and horses to ropes. But in other aspects they are quite different animals (only one of them is, in fact, an animal).
Some people will argue that this could be abstracted away in a Tieable interface. Then calling code could tie lead ropes to both horses and halters (and possibly other things), without needing to know about either.
No it is not overriding the tie method as you see Horse doesn't extend Halter class.
The method name is kept same so that you can call the Halter class tie method from an instance of Horse class with the same name.
It just wraps the method call to tie method of Halter class inside a method (which has same signature) from Horse class.

Categories

Resources