Hello dear students! Today we are going to learn two very important topics in Object Oriented Programming: Inheritance and Polymorphism. These two topics carry a lot of marks in your Ethiopian university exam. So please read each part carefully and try all the questions I give you. Ready? Let us start!
What is Inheritance?
Inheritance is one of the four pillars of Object Oriented Programming. The word itself tells us the meaning. Just like a child inherits some properties from their parents, in programming, a new class can inherit the properties and behaviors of an existing class.
Think about it this way. Your father has a house, a car, and some money. When you grow up, you get access to all those things without buying them yourself. In the same way, a child class gets all the attributes and methods of its parent class without writing them again.
The class that gives its properties is called the Parent Class (or Superclass or Base Class). The class that receives the properties is called the Child Class (or Subclass or Derived Class).
The main advantage of inheritance is code reusability. You write code once in the parent class, and many child classes can use it. This saves time and reduces errors.
1. Inheritance uses the “is-a” relationship. For example, a Student IS A Person, a Car IS A Vehicle.
2. The keyword used for inheritance in Java is extends. In C++, it is a colon :
3. A child class inherits all NON-private members of the parent class.
4. Private members of the parent class are NOT directly accessible in the child class.
5. Java does NOT support multiple inheritance with classes (a class cannot extend more than one class).
6. Constructors are NOT inherited by the child class.
Syntax of Inheritance in Java
Simple Example of Inheritance
Let me give you a very clear example. Suppose we have a class called Person and we want to create a Student class that inherits from Person.
Output:
Look at this carefully. Inside the Student class, we never declared name and age. We also never wrote the displayInfo() method. But we are using all of them because Student inherited them from Person. This is the power of inheritance!
Question 1: Which keyword is used to inherit a class in Java?
A) implements B) extends C) inherits D) super
Answer: B) extends
The extends keyword is used in Java to create a child class from a parent class. For example, class Student extends Person. The implements keyword is used for interfaces, not classes. The super keyword is used to refer to the parent class, but it is not used for inheritance itself. The word inherits is not a keyword in Java.
Question 2: A child class in Java can directly access which members of the parent class?
A) Only public members B) Only protected members C) Public and protected members D) All members including private
Answer: C) Public and protected members
In Java, a child class can directly access public and protected members of the parent class. Private members are only accessible within the same class. Default (package-private) members are accessible only if both classes are in the same package. So the correct answer is C because both public and protected are always accessible to the child class regardless of the package.
Question 3: What is code reusability in the context of inheritance? Explain with a simple example.
Answer: Code reusability means writing code once in a parent class and using it in multiple child classes without rewriting it. For example, if a Vehicle class has methods like start() and stop(), then Car, Bike, and Bus classes that extend Vehicle can all use these methods. We do not need to write start() and stop() separately in each class. This saves time, reduces code duplication, and makes maintenance easier because if we need to change the start() method, we change it only in one place.
Types of Inheritance
In Object Oriented Programming, there are different types of inheritance. Understanding each type is very important for your exam because questions often come from identifying the type from a diagram or code.
1. Single Inheritance
This is the simplest type. One child class inherits from one parent class. That is it. One parent, one child.
2. Multilevel Inheritance
In multilevel inheritance, there is a chain of inheritance. Class B inherits from Class A, and then Class C inherits from Class B. It is like a grandfather, father, and son relationship.
See how the Dog class has access to methods from both Animal and Mammal? This chain can go as long as you need, but in practice, keeping it short is better for readability.
3. Hierarchical Inheritance
In hierarchical inheritance, one parent class has multiple child classes. Think of one father having many children. Each child inherits from the same parent.
All three child classes (Dog, Cat, Bird) can use the eat() method from Animal, but each child also has its own special method.
4. Multiple Inheritance (Through Interfaces in Java)
Multiple inheritance means one child class inherits from more than one parent class at the same time. Now, here is a very important exam point: Java does NOT support multiple inheritance with classes. This is because of the “Diamond Problem” which we will discuss shortly.
However, Java does support multiple inheritance through interfaces. A class can implement multiple interfaces at the same time.
5. Hybrid Inheritance
Hybrid inheritance is a combination of two or more types of inheritance. For example, combining hierarchical and multilevel inheritance together. In Java, this is only possible through interfaces because of the restriction on multiple inheritance with classes.
1. Java supports Single, Multilevel, and Hierarchical inheritance with classes.
2. Java does NOT support Multiple inheritance with classes (Diamond Problem).
3. Java supports multiple inheritance only through interfaces.
4. C++ supports all types including multiple inheritance with classes.
5. In exam questions, if they show a diamond-shaped diagram, the answer is usually about the Diamond Problem.
Question 4: Which type of inheritance is NOT supported by Java with classes?
A) Single B) Multilevel C) Multiple D) Hierarchical
Answer: C) Multiple
Java does not allow a class to extend more than one class at the same time. This restriction exists to avoid the Diamond Problem. If class A has a method display(), and both class B and class C override it differently, and class D extends both B and C, then calling d.display() becomes ambiguous. Which version should run? Java avoids this problem by not allowing multiple inheritance with classes.
Question 5: Look at the following class structure and identify the type of inheritance:
Answer: Hierarchical Inheritance
In this structure, one parent class (Vehicle) has three child classes (Car, Truck, Bus). When multiple child classes inherit from the same single parent class, it is called hierarchical inheritance. The shape of the diagram looks like a tree with one root and multiple branches.
The Diamond Problem
This is a very common exam question. Let me explain it clearly so you never get it wrong.
The Diamond Problem occurs in multiple inheritance when two parent classes inherit from the same grandparent class, and then a child class inherits from both parent classes. This creates a diamond shape in the diagram.
Now imagine Class A has a method called show(). Both Class B and Class C override this method with their own version. When Class D inherits from both B and C, and we call d.show(), the compiler gets confused. Should it call B’s version or C’s version? This confusion is called the Diamond Problem.
Java solves this by simply not allowing multiple inheritance with classes. C++ solves it using something called “virtual inheritance.” But for your Java exam, just remember: Java avoids the Diamond Problem by not allowing a class to extend more than one class.
The “super” Keyword
The super keyword is very important in inheritance. It is used to refer to the immediate parent class of a child class. You can use it for three main purposes:
1. To access parent class attributes:
2. To call parent class methods:
3. To call parent class constructor:
1. super() must always be the first statement inside the child class constructor.
2. If you do not write super() explicitly, Java automatically calls the no-argument constructor of the parent class.
3. super refers only to the immediate parent, not the grandparent.
4. You cannot use super in a static method or static block.
Question 6: What happens if you write super() as the second statement in a child class constructor?
A) It works fine B) Compile-time error C) Runtime error D) Calls grandparent constructor
Answer: B) Compile-time error
The super() call must ALWAYS be the very first statement in the constructor. If you put any statement before it, even a simple System.out.println(), the Java compiler will give an error. This is a rule enforced by Java to ensure that the parent class is fully initialized before the child class starts its own initialization.
Question 7: The _________ keyword is used to access the parent class members when both parent and child classes have members with the same name.
Answer: super
When parent and child classes have attributes or methods with the same name, the child class version hides the parent class version. To access the parent class version from inside the child class, we use the super keyword. For example, super.name accesses the parent’s name variable, and super.method() calls the parent’s method.
Constructor Chaining in Inheritance
Now let me explain something that students often get confused about. What happens to constructors when we use inheritance?
Remember this rule: Constructors are NOT inherited. But when you create an object of a child class, the parent class constructor is still called. Why? Because the child class needs the parent class part to be initialized first.
Let me show you what happens step by step:
Output:
Notice the order! Even though we only created object C, the constructors ran from top to bottom: A first, then B, then C. This is called constructor chaining. Each constructor implicitly calls super() which goes to its parent constructor.
Now what if the parent class does NOT have a no-argument constructor? Then the child class MUST explicitly call the parent constructor using super with the right parameters.
1. If the parent class has only a parameterized constructor (no default), the child class MUST call
super(parameters) explicitly.2. Constructor chaining always starts from the topmost parent and goes down to the child.
3. Even with multilevel inheritance, the order is always from grandparent to parent to child.
4. A common exam trick is to show code where the parent has only a parameterized constructor but the child does not call super() with parameters. That code will NOT compile.
Question 8: What will be the output of the following code?
A) Z Y X B) X Y Z C) Y Z X D) Compile error
Answer: B) X Y Z
When we create new Z(), Z’s constructor runs first. But before Z’s body executes, it calls super() which goes to Y’s constructor. Before Y’s body executes, it calls super() which goes to X’s constructor. X has no parent, so its body runs first and prints “X “. Then control returns to Y’s body, which prints “Y “. Then control returns to Z’s body, which prints “Z “. So the output is X Y Z.
What is Polymorphism?
The word “Polymorphism” comes from Greek. Poly means “many” and morph means “forms.” So polymorphism means “many forms.” In programming, it means the same thing can behave differently in different situations.
Let me give you a real-life example first. Think about the word “play.” A child says “I want to play” and means playing with toys. A musician says “I want to play” and means playing an instrument. A football player says “I want to play” and means playing football. The same word “play” has many forms depending on who is using it. That is polymorphism!
In programming, polymorphism allows us to:
- Use the same method name to perform different tasks
- Write flexible code that can work with different types of objects
- Make our programs easier to extend and maintain
There are two main types of polymorphism in Java:
1. Polymorphism means “one interface, multiple implementations.”
2. Compile-time polymorphism is achieved through method overloading.
3. Runtime polymorphism is achieved through method overriding (with inheritance).
4. A very common exam question is to distinguish between overloading and overriding. Learn the differences well!
Method Overloading (Compile-Time Polymorphism)
Method overloading means having multiple methods in the same class with the same name but different parameters. The parameters must differ in number, type, or order.
The compiler decides at compile time which method to call based on the arguments you pass. That is why it is called compile-time polymorphism.
Rules for Method Overloading
- Methods must have the same name
- Methods must have different parameters (number, type, or order)
- Return type alone is NOT enough to overload a method
- Access modifier can be different
- It happens in the same class
Look at how the compiler knows which method to call. When we pass two integers, it calls the first method. When we pass three integers, it calls the second one. When we pass two doubles, it calls the third one. The decision is made at compile time.
Important Point: Return Type Alone Cannot Overload
The above code will give a compile error because both methods have the same name AND the same parameters. Even though the return type is different, Java cannot distinguish between them. The compiler looks at the method signature (name + parameters), not the return type.
1. Overloading is determined at compile time (early binding).
2. Only parameters must be different, return type does not matter for overloading.
3. Changing only the return type is NOT valid overloading.
4. Overloading can also happen with constructors (constructor overloading).
5. Method signature = method name + parameter list (return type is NOT part of the signature).
Question 9: Two methods with the same name and same parameters but different return types are considered overloaded methods.
Answer: False
This is a very common trick question in exams. Two methods with the same name and same parameter list but different return types will cause a compile-time error. The Java compiler uses the method signature (method name + parameter list) to identify methods. Since both methods have the same signature, the compiler sees them as duplicate methods, regardless of the return type difference.
Question 10: Method overloading is an example of which type of polymorphism?
A) Runtime polymorphism B) Compile-time polymorphism C) Both D) Neither
Answer: B) Compile-time polymorphism
Method overloading is resolved at compile time. The compiler looks at the method call and matches it with the correct method definition based on the number and types of arguments. Since the decision is made before the program runs (at compile time), it is called compile-time polymorphism or static polymorphism or early binding.
Method Overriding (Runtime Polymorphism)
Method overriding is completely different from method overloading, even though their names sound similar. In method overriding, a child class provides a new implementation of a method that is already defined in its parent class.
The key idea is: the parent class has a method, and the child class says, “I do not like your version, I will write my own version.” The child class method must have the exact same signature as the parent class method.
Rules for Method Overriding
- The method in the child class must have the same name as in the parent class
- The method must have the same parameters (same number, same type, same order)
- The return type must be the same or a covariant type (subclass of the original return type)
- The access level cannot be more restrictive (can be same or less restrictive)
- Private, static, and final methods cannot be overridden
- Overriding happens between parent and child classes (needs inheritance)
Now look at this very carefully. I declared the variables as Animal type, but the objects are Dog, Cat, and Cow. When I call makeSound(), Java does NOT look at the variable type. It looks at the actual object type and calls the method of that object. This decision happens at runtime, not at compile time. That is why it is called runtime polymorphism!
The @Override Annotation
You might have noticed the @Override annotation above the method. This is not required, but it is a very good practice. It tells the compiler, “I am trying to override a method from the parent class.” If you make a mistake (like a spelling error in the method name), the compiler will warn you. Always use @Override when overriding methods.
Access Modifier Rules for Overriding
The child class method cannot have a more restrictive access modifier than the parent class method. Think of it as: the child cannot have fewer rights than the parent.
| Parent Method Access | Child Method Can Be | Child Method Cannot Be |
|---|---|---|
| public | public | protected, default, private |
| protected | protected, public | default, private |
| default | default, protected, public | private |
| private | Cannot be overridden (not visible) | — |
1. Overriding happens at runtime (late binding / dynamic dispatch).
2. The method signature must be exactly the same in parent and child.
3. static methods cannot be overridden. If a child class has the same static method, it is called method hiding, not overriding.
4. final methods cannot be overridden.
5. private methods cannot be overridden because they are not visible to the child class.
6. Constructors cannot be overridden.
7. For runtime polymorphism to work, you must use a parent type reference pointing to a child type object.
Question 11: What will be the output of the following code?
A) Animal sound B) Lion roars C) Compile error D) Runtime error
Answer: B) Lion roars
This is the classic runtime polymorphism question. The reference variable a is of type Animal, but the actual object created is of type Lion. At runtime, Java looks at the actual object type (Lion), not the reference type (Animal). Since Lion has overridden the sound() method, the Lion’s version is called. The output is “Lion roars”. This is called dynamic method dispatch.
Question 12: A static method in a parent class can be overridden by a static method in the child class with the same signature.
Answer: False
Static methods belong to the class, not to objects. They cannot be overridden. When a child class defines a static method with the same signature as a parent class static method, it is called method hiding, not method overriding. The difference is important: in method hiding, the method called depends on the reference type, not the actual object type. This is the opposite of overriding where the actual object type decides.
Question 13: A parent class method is declared as protected. Which of the following is a valid override in the child class?
A) private void method() B) void method() (default) C) public void method() D) Both B and C
Answer: D) Both B and C
The parent method is protected. The child class can use the same or a less restrictive access modifier. The order from most to least restrictive is: private > default > protected > public. So the child can use protected (same) or public (less restrictive). Default is actually MORE restrictive than protected, so technically option B would cause a compile error. Wait, let me correct this. The correct order is: private (most restrictive) > default > protected > public (least restrictive). So default is MORE restrictive than protected. Therefore, only C) public is correct. I apologize for the confusion. The answer is C.
Difference Between Method Overloading and Method Overriding
This comparison is asked in almost every OOP exam. Please memorize these differences carefully.
| Feature | Method Overloading | Method Overriding |
|---|---|---|
| Definition | Same method name, different parameters in the SAME class | Same method name and same parameters in parent and child class |
| Where it happens | Same class | Parent and child classes (needs inheritance) |
| Parameters | MUST be different | MUST be exactly the same |
| Return type | Can be different | Must be same or covariant |
| Access modifier | Can be different | Cannot be more restrictive |
| When resolved | Compile time (early binding) | Runtime (late binding) |
| Polymorphism type | Compile-time polymorphism | Runtime polymorphism |
| static methods | Can be overloaded | Cannot be overridden (method hiding) |
| final methods | Can be overloaded | Cannot be overridden |
| private methods | Can be overloaded | Cannot be overridden (not visible) |
Question 14: List any four differences between method overloading and method overriding.
Answer:
1. Class relationship: Overloading happens within the same class. Overriding happens between a parent class and a child class (requires inheritance).
2. Parameters: In overloading, the parameter list MUST be different (different number, type, or order). In overriding, the parameter list MUST be exactly the same.
3. Resolution time: Overloading is resolved at compile time (early binding). Overriding is resolved at runtime (late binding / dynamic dispatch).
4. Return type: In overloading, the return type can be anything (it does not matter). In overriding, the return type must be the same as the parent or a covariant type (a subclass of the original return type).
Dynamic Method Dispatch
Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at runtime rather than compile time. This is the core of runtime polymorphism.
When you have a parent class reference pointing to a child class object, and you call an overridden method, Java does not decide which method to call at compile time. Instead, it waits until the program is running, checks the actual type of the object, and then calls the appropriate method.
Notice how the same variable s calls different versions of draw() depending on which object it points to. The reference type is always Shape, but the behavior changes based on the actual object. This flexibility is the real power of polymorphism!
1. Dynamic method dispatch only works with overridden methods, not overloaded methods.
2. The reference variable type determines which methods are visible (you can only call methods that exist in the parent class).
3. The actual object type determines which version of the overridden method is executed.
4. If the child class has a method that does NOT exist in the parent class, you CANNOT call it through a parent reference.
Question 15: In dynamic method dispatch, the method to be executed is decided by:
A) The reference variable type B) The actual object type C) The return type D) The access modifier
Answer: B) The actual object type
In dynamic method dispatch, the JVM looks at the actual object in memory (not the reference variable type) to decide which overridden method to call. For example, if Animal a = new Dog(), the reference type is Animal but the actual object is Dog. So a.makeSound() will call Dog’s version of makeSound(), not Animal’s version.
Question 16: Given the code below, which line will cause a compile error?
A) Line 1 B) Line 2 C) Both lines D) Neither line
Answer: B) Line 2
Line 1 works fine because eat() exists in the Animal class and Dog overrides it. But Line 2 causes a compile error because the reference variable a is of type Animal, and the Animal class does NOT have a fetch() method. Even though the actual object is a Dog (which has fetch), the compiler only looks at the reference type to check if a method exists. This is a very common exam question, so remember it well!
Use of “instanceof” Operator
When we use parent class references with child class objects (runtime polymorphism), sometimes we need to know what the actual object type is. The instanceof operator helps with this.
The instanceof operator returns true if the object is an instance of the specified class or any of its parent classes. It returns false otherwise. This is very useful when you need to perform type-specific operations.
Abstract Classes and Polymorphism
Abstract classes and polymorphism work together beautifully. An abstract class is a class that cannot be instantiated (you cannot create objects from it). It is meant to be a blueprint for other classes.
An abstract method is a method that has no body. The child class MUST provide the implementation of abstract methods.
Notice how we used polymorphism here. The reference type is Shape (abstract), but the objects are Circle and Square. When we call draw(), the appropriate child class method runs. The abstract class forces every child class to implement draw(), which guarantees that every shape can be drawn.
1. An abstract class can have both abstract methods and concrete (normal) methods.
2. An abstract method has NO body; it ends with a semicolon.
3. If a class has even one abstract method, the class MUST be declared abstract.
4. You CANNOT create an object of an abstract class.
5. The child class MUST override all abstract methods, otherwise the child class must also be declared abstract.
6. Abstract classes ARE commonly used with polymorphism (parent reference = child object).
Question 17: Which of the following is TRUE about abstract classes in Java?
A) You can create an object of an abstract class B) An abstract class must have at least one abstract method C) An abstract method must be overridden by the child class D) Abstract methods can have a body
Answer: C) An abstract method must be overridden by the child class
Let me explain why the others are wrong. Option A is wrong because you cannot instantiate an abstract class. Option B is wrong because an abstract class can have zero abstract methods (though that would be unusual). Option D is wrong because abstract methods have no body. Option C is correct because the child class MUST provide an implementation for all abstract methods, or else the child class itself must be declared abstract.
Final Keyword and Inheritance
The final keyword has an important relationship with inheritance and polymorphism. Let me explain its three uses:
1. Final variable: Once assigned, its value cannot be changed (constant).
2. Final method: A final method CANNOT be overridden by any child class.
3. Final class: A final class CANNOT be inherited by any class. No child class can extend it.
A good example of a final class in Java is the String class. You cannot create a class that extends String. This is done for security and performance reasons.
Question 18: What happens when you try to override a final method of a parent class?
A) The method runs twice B) Compile-time error C) Runtime error D) The override works but with a warning
Answer: B) Compile-time error
The final keyword on a method explicitly prevents overriding. If a child class attempts to override a final method, the Java compiler will immediately give an error. The error message typically says something like “Cannot override the final method from ParentClass.” This is useful when a parent class designer wants to ensure that a particular method’s behavior is never changed by child classes.
Complete Example: Putting It All Together
Now let me give you one big example that combines inheritance, method overriding, and polymorphism. This type of question often appears in exams as a “find the output” question.
Output:
Let me walk you through what happened:
- e1 is a regular Employee.
calculateSalary()returns just the basic salary: 5000. - e2 is a Manager but referenced as Employee.
calculateSalary()is overridden in Manager, so it returns 8000 + 3000 = 11000. - e3 is a Developer but referenced as Employee.
calculateSalary()is overridden in Developer, so it returns 7000 + (20 * 150) = 7000 + 3000 = 10000.
The displayInfo() method is in the Employee class and it calls calculateSalary(). Because of runtime polymorphism, the correct overridden version of calculateSalary() is called for each object. This is a beautiful example of how polymorphism makes our code flexible!
Question 19: What will be the output of the following code?
Output:
Explanation: When b.display() is called, the display() method is found in the Base class (it is not overridden in Derived). So Base’s display() runs and prints “Base display”. Then inside display(), there is a call to show(). Now, show() IS overridden in Derived. So at this point, runtime polymorphism kicks in. The actual object is Derived, so Derived’s show() is called, printing “Derived show”. This is a tricky question that tests your deep understanding of how overridden methods work even when called from inside a parent class method!
Exercises with Answers
Vehicle with attributes brand and year, and a method start(). Create two child classes Car and Bike that override the start() method. Write a main method that demonstrates runtime polymorphism.
Errors:
Error 1: The @Override annotation will cause a compile error. The show() method in class A is private. Private methods are NOT visible to child classes, so they cannot be overridden. The @Override annotation tells the compiler to check if this method truly overrides a parent method, and since the parent method is private, the compiler will say there is nothing to override.
Fix: Change the access modifier of show() in class A from private to public or protected. If you remove the @Override annotation, the code will compile, but it will be method hiding (a new method in B), not overriding.
Output:
Explanation: This is NOT method overriding. This is method hiding. Static methods belong to the class, not to objects. When you call x.greet(), the compiler looks at the reference type (which is X), not the actual object type. Since X has a static greet() method, X’s version is called. Even though the actual object is Y, the static method of Y is not used. This is the key difference between overriding (where object type decides) and hiding (where reference type decides).
BankAccount with an abstract method calculateInterest() and a concrete method displayBalance(). Create two subclasses SavingsAccount and CurrentAccount that implement calculateInterest(). Demonstrate polymorphism in the main method.
Practice Questions for Exam Preparation
Question 20: Which of the following statements about inheritance is FALSE?
A) Inheritance promotes code reusability B) Java supports multiple inheritance through classes C) The protected members of a parent class are accessible in the child class D) Constructors are not inherited in Java
Answer: B) Java supports multiple inheritance through classes
This statement is FALSE because Java does NOT support multiple inheritance through classes. A Java class can extend only one class. Java supports multiple inheritance only through interfaces (a class can implement multiple interfaces). All other statements are true: inheritance does promote code reusability, protected members are accessible in child classes, and constructors are not inherited.
Question 21: What is the output of the following code?
A) P B) Q C) P Q D) Q P
Answer: C) P Q
When new Q() is called, Q’s constructor runs. The first statement is super() which calls P’s constructor. P’s constructor prints “P “. Then control returns to Q’s constructor which prints “Q “. So the output is “P Q”. Even if we remove the explicit super() call, the result would be the same because Java automatically inserts it.
Question 22: Can an abstract class have a constructor?
A) No, because you cannot create objects of abstract classes B) Yes, and it is called when a child class object is created C) Yes, but only a default constructor D) No, constructors are not allowed in abstract classes
Answer: B) Yes, and it is called when a child class object is created
Abstract classes CAN have constructors, including parameterized constructors. Even though you cannot directly create an object of an abstract class using new, the constructor is called when a child class object is created (because the child constructor calls super()). The abstract class constructor is used to initialize the fields that the abstract class defines. This is a commonly misunderstood concept in exams.
Question 23: What will be the output?
Output:
Explanation: This is a very important question! For variables, Java uses the reference type to decide which variable to access. obj.x uses the reference type A, so it prints A’s x which is 10. But for methods, Java uses the actual object type (runtime polymorphism). obj.show() calls B’s overridden show() method, which uses B’s x, so it prints 20. Remember: variables are resolved by reference type, methods are resolved by object type.
Question 24: Explain the difference between “is-a” relationship and “has-a” relationship in OOP. Give one example for each.
Answer:
“Is-a” relationship represents inheritance. It means one class is a specialized version of another class. For example, a Car “is a” Vehicle. In code, this is implemented using extends. Example: class Car extends Vehicle.
“Has-a” relationship represents composition or association. It means one class contains an object of another class as a member. For example, a Car “has a” Engine. In code, this is implemented by declaring a reference variable of another class inside the class. Example: inside Car class, we have Engine engine;. The “has-a” relationship is also called composition because the containing class is made up of other classes.
1. Always remember: variables follow reference type, methods follow object type in polymorphism.
2. If a question shows
Animal a = new Dog(), remember that a can only call methods that exist in Animal, but the Dog’s overridden version will run.3. The
super() call must always be the FIRST statement in a constructor. This rule has NO exceptions.4. A class with an abstract method MUST be declared abstract. But an abstract class does NOT need to have an abstract method.
5. Practice writing code by hand. Many exam questions ask you to find the output of code without running it.
6. When in doubt about overloading vs overriding, check: same class or different classes? Same parameters or different parameters?
7. The Diamond Problem is the reason Java does not support multiple inheritance with classes. Be ready to explain and draw the diagram.