Govt Exams
Java supports only single class inheritance to avoid the diamond problem. However, multiple interface implementation is allowed.
class Parent { void show() { System.out.println("Parent"); } }
class Child extends Parent { void show() { System.out.println("Child"); } }
public class Test { public static void main(String[] args) { Parent p = new Child(); p.show(); } }
This demonstrates runtime polymorphism. Although the reference is of type Parent, the actual object is Child. The overridden show() method in Child class is executed.
Java achieves runtime polymorphism through method overriding using inheritance. Unlike C++, Java doesn't use the 'virtual' keyword; it's implicit for all non-final methods.
Interfaces cannot be instantiated directly. You must create a concrete class that implements the interface or use an anonymous inner class.
The default (package-private) access modifier allows access to members from any class within the same package, but not from classes in other packages.
Encapsulation is the bundling of data (variables) and methods into a single unit (class) while hiding the internal implementation details from the outside world. It is achieved using access modifiers.
Method overloading is compile-time (static) polymorphism with same method name but different parameters in the same class. Method overriding is runtime (dynamic) polymorphism where a child class provides a specific implementation of a parent method.
abstract class Animal { abstract void sound(); void sleep() { System.out.println("Zzz"); } }
class Dog extends Animal { void sound() { System.out.println("Bark"); } }
What can Dog objects do?
Dog inherits the concrete method sleep() from Animal and provides implementation for the abstract method sound(). Therefore, Dog objects can call both methods.
Abstract classes cannot be directly instantiated, but you can create objects using anonymous inner classes that implement the abstract methods.
class A { int x = 10; }
class B extends A { int x = 20; }
public class Test { public static void main(String[] args) { A a = new B(); System.out.println(a.x); } }
Variable shadowing occurs here. The reference type is A, so a.x accesses A's x field which is 10. Method overriding works with methods, not instance variables.