Object-Oriented Programming Homework Compilation – Java
(Expanded Guide)
...[previous content]...
11. Downcasting in Polymorphism
• Downcasting is converting a parent class reference back to a child class.
• Required when you want to access child-specific methods from a superclass reference.
Animal a = new Dog(); // Upcasting
Dog d = (Dog) a; // Downcasting
• Must ensure the object is actually of the target type, otherwise ClassCastException is
thrown.
if (a instanceof Dog) {
Dog d = (Dog) a;
d.bark();
}
12. Why Not Use Object for Polymorphism?
• Object is too generic – doesn't allow method calls without casting.
• Loses all type-specific behavior.
• Defeats purpose of polymorphism.
Object obj = new Circle();
// Cannot call obj.draw() without casting
Better:
Use superclass or interface references instead:
Shape s = new Circle();
s.draw();
13. finally in Exception Handling
• finally block always executes, whether exception occurs or not.
• Ensures resources (files, DB connections) are closed.
1
try {
int x = 5 / 0;
} catch (ArithmeticException e) {
System.out.println("Error");
} finally {
System.out.println("Cleanup actions");
}
14. Custom Exceptions
• User-defined exceptions extend Exception or RuntimeException .
• Used for application-specific errors.
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
void checkAge(int age) throws InvalidAgeException {
if (age < 18) throw new InvalidAgeException("Too young");
}
15. Type-Bound Generics
• Restrict types used in generics using extends keyword.
• Ensures that only certain types can be used.
class Box<T extends Number> {
T value;
}
Box<Integer> b = new Box<>(); // ✅
Box<String> b = new Box<>(); // ❌ compile error
16. Generics vs ArrayList
• Generics allow type-safe reusable code.
• Raw ArrayList (non-generic) leads to runtime ClassCastException .
2
ArrayList list = new ArrayList();
list.add("String");
Integer x = (Integer) list.get(0); // Runtime error!
Use generics:
ArrayList<String> list = new ArrayList<>();
String s = list.get(0); // Safe
17. Why Abstract Class Has a Protected Constructor
• Prevents direct instantiation.
• Allows inheritance and controlled object creation.
abstract class Animal {
protected Animal() {
System.out.println("Animal created");
}
}
18. Abstract Class Without Abstract Methods
Yes, it's allowed.
• Use when you want to prevent instantiation but still provide full method implementations.
abstract class Utility {
public void log(String msg) {
System.out.println(msg);
}
}
19. Wrapper Classes
• Provide object form of primitives.
• Useful for collections, generics, null handling.
Primitive Wrapper
int Integer
double Double
3
Primitive Wrapper
boolean Boolean
char Character
int x = 10;
Integer obj = Integer.valueOf(x);
20. className<T> vs className<Object>
• className<T> : T is a placeholder, generic and reusable.
• className<Object> : fixed to Object , loses type-safety.
class Box<T> {
T item;
}
Box<String> box1 = new Box<>(); // Type-safe
Box<Object> box2 = new Box<>(); // Accepts anything
21. Wildcards
• Used when working with unknown types in generics.
List<?> list; // Unbounded wildcard
List<? extends Number> nums; // Upper bound
List<? super Integer> ints; // Lower bound
• Wildcards allow flexibility with read-only or write-only generics.
22. Thread Coordination (Thread Control)
a. join()
• Ensures one thread finishes before another starts.
Thread t1 = new Thread(() -> { /* task */ });
Thread t2 = new Thread(() -> { /* depends on t1 */ });
t1.start();
t1.join();
t2.start();
4
b. wait() and notify()
• Low-level communication between threads.
• Threads wait and notify on shared objects.
synchronized(obj) {
obj.wait();
obj.notify();
}
23. What is Type-Safe?
• Type-safe code ensures that type errors are caught at compile time.
• Generics enforce type safety.
List<String> list = new ArrayList<>();
list.add("Text");
Without generics:
List list = new ArrayList();
list.add("Text");
Integer num = (Integer) list.get(0); // Runtime error
24. Generic Methods
• You can define generics at method level.
public <T> void display(T item) {
System.out.println(item);
}
Can be used in non-generic classes:
MyClass obj = new MyClass();
obj.<String>display("Hello");
25. Why Not Use Object Instead of Generics?
• Using Object sacrifices type safety.
• Requires casting.
• Prone to runtime errors.
5
public void add(Object item) { ... }
// No compile-time check, must cast later
With generics:
public <T> void add(T item) { ... }
• Compiler enforces correct usage.
• Cleaner, reusable, safer code.
✅ End of Compilation – You now have a complete and beginner-friendly guide to all key Java OOP
homework topics.