Java Lab 4
Java Lab 4
1. Objectives
By the end of this lab, students will be able to:
• Understand and apply the final keyword to variables, methods, and classes.
• Differentiate between reference type and object type in Java.
• Implement dynamic dispatch and runtime polymorphism.
• Use abstract classes and interfaces for abstraction.
• Resolve ambiguities like the diamond problem using interfaces.
• Practice coding with examples and exercises on these topics.
Output:
MAX: 100
class BlankFinalExample {
final int speed; // blank final
BlankFinalExample(int s) {
speed = s; // must assign value here
}
void showSpeed() {
[Link]("Speed: " + speed);
}
public static void main(String[] args) {
BlankFinalExample obj = new BlankFinalExample(90);
[Link](); // Output: Speed: 90
}
}
Output:
Speed: 90
class StaticBlankFinalExample {
static final int MAX;
static {
MAX = 500; // must initialize here
}
public static void main(String[] args) {
[Link]("MAX: " + MAX); // Output: MAX: 500
}
}
Output:
MAX: 500
class Parent {
final void show() {
[Link]("Final method in Parent");
}
}
Output:
Output:
Vehicle is running
a. Create a class Constants with final variables for PI (3.14159) and GRAVITY
(9.8). Write a main method to print them. Attempt to reassign one and note the
error.
Sample Code:
public class Constants {
public static void main(String[] args) {
final double PI = 3.14159;
final double GRAVITY = 9.8;
[Link]("PI: " + PI);
[Link]("GRAVITY: " + GRAVITY);
// PI = 3.14; // Error
}
}
a. Create a class Person with a blank final String name. Initialize it in the construc-
tor. Add a method to display the name.
Sample Code:
class Person {
final String name;
Person(String n) {
name = n;
}
void display() {
[Link]("Name: " + name);
}
public static void main(String[] args) {
Person p = new Person("Alice");
[Link](); // Output: Name: Alice
}
}
a. Create a class Config with a static blank final int PORT. Initialize it in a static
block to 8080. Print it in main.
Sample Code:
class Config {
static final int PORT;
static {
PORT = 8080;
}
public static void main(String[] args) {
[Link]("PORT: " + PORT); // Output: PORT: 8080
}
}
a. Create a final class MathUtils with a final method add(int a, int b) that
returns the sum. Try to extend the class and override the method (note errors).
Sample Code:
final class MathUtils {
final int add(int a, int b) {
return a + b;
}
}
class Parent {
int x = 10;
void speak() {
[Link]("Parent speaks");
}
}
class Child extends Parent {
int x = 20;
@Override
void speak() {
[Link]("Child speaks");
}
void onlyChildDoes() {
[Link]("Child-only method");
}
}
public class Test {
public static void main(String[] args) {
Parent p = new Child(); // ref: Parent, obj: Child
[Link](p.x); // 10 (reference type wins)
[Link](); // Child speaks (object type wins)
// [Link](); // Compile error (Parent doesn’t have
,→ this method)
((Child) p).onlyChildDoes(); // OK after casting
}
}
Output:
10
Child speaks
Child-only method
class Animal {
String name = "Animal";
void sound() {
[Link]("Animal makes a sound");
}
}
class Dog extends Animal {
String name = "Dog";
@Override
void sound() {
[Link]("Dog barks");
}
}
class Cat extends Animal {
String name = "Cat";
@Override
void sound() {
[Link]("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal a1 = new Dog(); // parent reference, child object
Animal a2 = new Cat(); // parent reference, child object
Animal a3 = new Animal(); // parent reference, parent object
// --- Dynamic Dispatch in action ---
[Link](); // Dog barks
[Link](); // Cat meows
[Link](); // Animal makes a sound
// --- Variable behavior ---
[Link]([Link]); // Animal
[Link]([Link]); // Animal
[Link]([Link]); // Animal
}
}
Output:
Dog barks
Cat meows
Animal makes a sound
Animal
Animal
Animal
a. Create classes Vehicle (with int speed = 50, void move()) and Car extends
Vehicle (speed = 100, override move()). Use Vehicle ref = new Car() and print
speed/move.
Sample Code:
class Vehicle {
int speed = 50;
void move() {
[Link]("Vehicle moves");
}
}
class Car extends Vehicle {
int speed = 100;
@Override
void move() {
[Link]("Car drives");
}
}
public class VehicleTest {
public static void main(String[] args) {
Vehicle v = new Car();
[Link]([Link]); // 50 (reference type)
[Link](); // Car drives (object type)
}
}
a. Add a method honk() to Car only. Use casting to call it from Vehicle reference.
Sample Code:
// Extend from above
class Car extends Vehicle {
// ... (previous)
void honk() {
[Link]("Car honks");
}
}
public class VehicleTest {
public static void main(String[] args) {
Vehicle v = new Car();
// [Link](); // Compile error
((Car) v).honk(); // Car honks
}
}
a. Create Bird extends Animal (name = ”Bird”, override sound() to ”Bird chirps”).
Use Animal refs for Dog, Cat, Bird and call sound()/print name.
Sample Code:
// Extend from Animal example
class Bird extends Animal {
String name = "Bird";
@Override
void sound() {
[Link]("Bird chirps");
}
}
public class Main {
public static void main(String[] args) {
Animal a4 = new Bird();
[Link](); // Bird chirps
[Link]([Link]); // Animal
}
}
• Abstract Class: Can have abstract (no body) and concrete methods, fields, con-
structors. Cannot instantiate. Subclasses must implement abstract methods.
• Differences: Interfaces are 100% abstract, abstract classes can have defaults.
Output:
Dog barks
Animal is sleeping...
Output:
Beagle barks
Dog barking behavior
Animal is sleeping...
Output:
Output:
interface Flyable {
// Variable must be static and final
int MAX_ALTITUDE = 10000; // implicitly public static final
void fly(); // implicitly public and abstract
}
interface Bank {
double INTEREST_RATE = 5.5;
void calculateInterest();
}
interface Shape {
double pi = 3.1416;
double area();
}
class Circle implements Shape {
double r = 2;
public double area() {
return pi * r * r;
}
}
public class Main {
public static void main(String[] args) {
Circle c = new Circle();
[Link]([Link]());
[Link]([Link]);
[Link]([Link]);
}
}
interface Printable {
void print();
}
interface Scannable {
void scan();
}
class Printer implements Printable, Scannable {
public void print() {
[Link]("Printing document");
}
public void scan() {
[Link]("Scanning document");
}
}
interface Payment {
void pay();
}
class CreditCardPayment implements Payment {
public void pay() {
[Link]("Paid using credit card");
}
}
class MobileBankingPayment implements Payment {
public void pay() {
[Link]("Paid using mobile banking");
}
}
public class Main {
public static void main(String[] args) {
Payment p1 = new CreditCardPayment();
[Link](); // Paid using credit card
Payment p2 = new MobileBankingPayment();
[Link](); // Paid using mobile banking
}
}
Output:
Output:
Bark
Plays fetch
Sleeping...
class A {
void show() {
[Link]("A’s show");
}
}
class C extends A {
void show() {
[Link]("C’s show");
}
}
class B extends A {
void show() {
[Link]("B’s show");
}
}
// Compile error: Java does not allow multiple inheritance with classes
interface A {
default void show() {
[Link]("Interface A");
}
}
interface B {
default void show() {
[Link]("Interface B");
}
}
class Demo implements A, B {
public void show() {
[Link]();
}
}
public class Main {
public static void main(String[] args) {
Demo d = new Demo();
[Link](); // Interface A
}
}
Output:
Interface A
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
class Duck implements Flyable, Swimmable {
public void fly() {
[Link]("Duck is flying");
}
public void swim() {
[Link]("Duck is swimming");
}
public static void main(String[] args) {
Duck d = new Duck();
[Link](); // Output: Duck is flying
[Link](); // Output: Duck is swimming
}
}
Output:
Duck is flying
Duck is swimming
a. Create abstract class Device with abstract void powerOn() and concrete void
checkBattery(). Subclass Phone implements powerOn().
Sample Code:
abstract class Device {
abstract void powerOn();
void checkBattery() {
[Link]("Battery level: 100%");
}
}
class Phone extends Device {
@Override
void powerOn() {
[Link]("Phone powering on");
}
}
public class DeviceTest {
public static void main(String[] args) {
Device d = new Phone();
[Link](); // Phone powering on
[Link](); // Battery level: 100%
}
}
a. Create abstract Fruit with String color (via constructor) and abstract void taste().
Subclass Apple.
Sample Code:
abstract class Fruit {
String color;
Fruit(String color) {
[Link] = color;
}
abstract void taste();
void displayColor() {
[Link]("Color: " + color);
}
}
class Apple extends Fruit {
Apple(String color) {
super(color);
}
@Override
void taste() {
[Link]("Sweet");
}
}
public class FruitTest {
public static void main(String[] args) {
Apple a = new Apple("Red");
[Link](); // Sweet
[Link](); // Color: Red
}
}
a. Create interface Drawable with void draw() and constant int SIZE = 10. Imple-
ment in class Square.
Sample Code:
interface Drawable {
int SIZE = 10;
void draw();
}
class Square implements Drawable {
public void draw() {
[Link]("Drawing square of size " + SIZE);
}
}
public class DrawTest {
public static void main(String[] args) {
Square s = new Square();
[Link](); // Drawing square of size 10
}
}
a. Create interfaces Readable (void read()) and Writable (void write()). Class
Book implements both.
Sample Code:
interface Readable {
void read();
}
interface Writable {
void write();
}
class Book implements Readable, Writable {
public void read() {
[Link]("Reading book");
}
public void write() {
[Link]("Writing book");
}
}
public class BookTest {
public static void main(String[] args) {
Book b = new Book();
[Link](); // Reading book
[Link](); // Writing book
}
}
Sample Code:
abstract class Gadget {
abstract void operate();
}
interface Chargeable {
void charge();
}
class Laptop extends Gadget implements Chargeable {
@Override
void operate() {
[Link]("Laptop operating");
}
@Override
void charge() {
[Link]("Laptop charging");
}
}
public class GadgetTest {
public static void main(String[] args) {
Laptop l = new Laptop();
[Link](); // Laptop operating
[Link](); // Laptop charging
}
}
a. Interfaces SoundA and SoundB both with default void makeSound(). Class Speaker
implements both and overrides.
Sample Code:
interface SoundA {
default void makeSound() {
[Link]("Sound A");
}
}
interface SoundB {
default void makeSound() {
[Link]("Sound B");
}
}
class Speaker implements SoundA, SoundB {
@Override
public void makeSound() {
[Link](); // Choose A
}
}
public class SoundTest {
public static void main(String[] args) {
Speaker s = new Speaker();
[Link](); // Sound A
}
}
5. Write a program using an interface with default methods and resolve a diamond
problem.
Keep Coding!