Java Object-Oriented Programming Fundamentals: Classes, Inheritance, and Polymorphism
Creating Objects from Classes
Setting Up a Program Environment (Shapes Demo)
Main Application (ImageRenderer)
package geometrydemo;
public class ImageRenderer {
public static void main(String[] args) {
ImageCanvas canvas = new ImageCanvas(420, 300);
Circle circOne = new Circle(320, 40, 80);
Rectangle rectOne = new Rectangle(100, 100, 100, 100);
Triangle triOne = new Triangle(100, 100, 200, 100, 150, 50);
Line lineOne = new Line(0, 205, 400, 205);
Circle circTwo = new Circle(200, 200, 50);
canvas.addShape(circOne);
canvas.addShape(rectOne);
canvas.addShape(triOne);
canvas.addShape(lineOne);
canvas.addShape(circTwo);
canvas.render();
}
}
Canvas Window (ImageCanvas)
package geometrydemo;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageCanvas extends JFrame {
private int canvasWidth;
private int canvasHeight;
private ArrayList<GeometricShape> shapeCollection = new ArrayList<>();
private class ShapePanel extends JPanel {
@Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
for (GeometricShape shape : shapeCollection) {
shape.render(graphics);
}
}
}
public void addShape(GeometricShape shape) {
shapeCollection.add(shape);
}
public ImageCanvas(int width, int height) {
add(new ShapePanel());
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.canvasWidth = width;
this.canvasHeight = height;
}
public void render() {
setLocationRelativeTo(null);
setSize(canvasWidth, canvasHeight);
setVisible(true);
}
}
Circle Implementation
package geometrydemo;
import java.awt.Graphics;
public class Circle extends GeometricShape {
private int centerX;
private int centerY;
private int diameter;
public Circle(int x, int y, int radius) {
this.centerX = x;
this.centerY = y;
this.diameter = radius * 2;
}
@Override
public void render(Graphics g) {
g.drawOval(centerX - diameter/2, centerY - diameter/2, diameter, diameter);
}
}
Line Implementation
package geometrydemo;
import java.awt.Graphics;
public class Line extends GeometricShape {
private int startX, startY, endX, endY;
public Line(int x1, int y1, int x2, int y2) {
this.startX = x1;
this.startY = y1;
this.endX = x2;
this.endY = y2;
}
@Override
public void render(Graphics g) {
g.drawLine(startX, startY, endX, endY);
}
}
Rectangle Implementation
package geometrydemo;
import java.awt.Graphics;
public class Rectangle extends GeometricShape {
private int posX, posY, rectWidth, rectHeight;
public Rectangle(int x, int y, int width, int height) {
this.posX = x;
this.posY = y;
this.rectWidth = width;
this.rectHeight = height;
}
@Override
public void render(Graphics g) {
g.drawRect(posX, posY, rectWidth, rectHeight);
}
}
Triangle Implementation
package geometrydemo;
import java.awt.Graphics;
public class Triangle extends GeometricShape {
private int[] xPoints = new int[3];
private int[] yPoints = new int[3];
public Triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
xPoints[0] = x1; xPoints[1] = x2; xPoints[2] = x3;
yPoints[0] = y1; yPoints[1] = y2; yPoints[2] = y3;
}
@Override
public void render(Graphics g) {
g.drawPolygon(xPoints, yPoints, 3);
}
}
Abstract Base Class (GeometricShape)
package geometrydemo;
import java.awt.Graphics;
public abstract class GeometricShape {
public abstract void render(Graphics g);
}
Relationship Between Classes and Objects
- Objects are concrete entities that are instantiated
- Classes are blueprints defining object structure
Encapsulation Principles
Encapsulation combines data and operations into cohesive units. Objects consist of properties (attributes) and services (methods).
Defining Classes
Class Design and Object Creation
package vending;
public class VendingMachine {
private int itemCost = 80;
private int currentBalance = 0;
private int totalRevenue = 0;
public void setItemCost(int newCost) {
this.itemCost = newCost;
}
public void displayWelcome() {
System.out.println("Welcome to Vending Machine");
}
public void addFunds(int amount) {
currentBalance += amount;
}
public void showCurrentBalance() {
System.out.println("Balance: " + currentBalance);
}
public void dispenseItem() {
if (currentBalance >= itemCost) {
System.out.println("Item dispensed");
currentBalance -= itemCost;
totalRevenue += itemCost;
} else {
System.out.println("Insufficient funds");
}
}
public static void main(String[] args) {
VendingMachine machine = new VendingMachine();
machine.displayWelcome();
machine.showCurrentBalance();
machine.addFunds(100);
machine.dispenseItem();
machine.showCurrentBalance();
}
}
Member Variables and Methods
Member Variables
- Variables defined within a class are member variables
- Each object maintains its own copy of member variables
Accessing Member Variables in Methods
- Methods can directly access member variables
- The accessed variables belong to the object that invoked the method
- The dot operator establishes connection between method and object
Member Methods
Member methods are defined within classes to perform specific operations:
accessModifier returnType methodName(parameterList) {
// Method implementation
}
The 'this' Reference
'this' refers to the current object instance, used to differentiate between member variables and parameters with the same name.
Local Variables
- Defined within method scope
- Exist only during method execution
- Contrast with member variables that persist throughout object lifetime
Object Initialization
Constructors
Constructors are special methods that initialize objects when created:
accessModifier ClassName(parameterList) {
// Constructor body
}
Method Overloading
Method overloading allows multiple methods with the same name but different parameters:
public class Calculator {
public int add(int x, int y) {
return x + y;
}
public double add(double x, double y) {
return x + y;
}
public int add(int x, int y, int z) {
return x + y + z;
}
}
Type Conversion
Explicit Type Casting
Converting between incompatible types requires explicit casting:
double value = 3.14159;
int integerValue = (int) value; // Result: 3
Implicit Type Conversion
Java automatically converts compatible types in certain contexts:
- Compatible assignments (byte → short → int → long → float → double)
- String to numeric conversions using wrapper classes
- Character to integer conversions
Object Interaction Patterns
Designing a Digital Clock
package timekeeper;
public class DigitalClock {
private HourDisplay hour = new HourDisplay(24);
private MinuteDisplay minute = new MinuteDisplay(60);
public void begin() {
while (true) {
minute.increment();
if (minute.getCurrentValue() == 0) {
hour.increment();
}
System.out.printf("%02d:%02d\n", hour.getCurrentValue(), minute.getCurrentValue());
}
}
public static void main(String[] args) {
DigitalClock clock = new DigitalClock();
clock.begin();
}
}
Access Modifiers
Java provides four access levels:
- public: Accessible from any class
- private: Accessible only within defining class
- protected: Accessible within package and subclasses
- default (no modifier): Accessible within package only
Packages
Packages organize related classes. Use import statements to access classes from other packages.
Class-Level Members
Static Variables and Methods
The static modifier creates class-level members shared across all instances:
public class Counter {
private static int instanceCount = 0; // Class variable
private int id;
public Counter() {
instanceCount++;
this.id = instanceCount;
}
public static int getTotalCount() { // Class method
return instanceCount;
}
}
Inheritance and Polymorphism
Extending Classes
Inheritance allows classes to inherit properties and behaviors from parent classes:
public class MediaItem {
protected String title;
protected int duration;
protected boolean available;
public MediaItem(String title, int duration) {
this.title = title;
this.duration = duration;
this.available = true;
}
public void displayInfo() {
System.out.println("Title: " + title);
}
}
public class MusicCD extends MediaItem {
private String artist;
public MusicCD(String title, int duration, String artist) {
super(title, duration);
this.artist = artist;
}
@Override
public void displayInfo() {
System.out.print("CD: ");
super.displayInfo();
System.out.println("Artist: " + artist);
}
}
Polymorphic Variables and Upcasting
Java variables can reference objects of their declared type or any subclass:
MediaItem item = new MusicCD("Album", 45, "Artist"); // Upcasting
Downcasting requires explicit type checking:
if (item instanceof MusicCD) {
MusicCD cd = (MusicCD) item;
}
Method Overriding
Subclasses can override parent class methods to provide specialized implementations:
public class BaseClass {
public void display() {
System.out.println("Base implementation");
}
}
public class DerivedClass extends BaseClass {
@Override
public void display() {
System.out.println("Derived implementation");
}
}
The Object Class
All Java classes implicitly extend Object, providing methods like:
toString(): String representationequals(): Object equality comparisonhashCode(): Hash code generation
Custom equals() Implementation
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof MyClass)) return false;
MyClass obj = (MyClass) other;
return this.value == obj.value;
}
Abstraction and Interfaces
Abstract Classes and Methods
Abstract classes cannot be instantiated and may contain abstract methods:
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public abstract double calculateArea(); // Abstract method
public String getColor() {
return color;
}
}
Interfaces
Interfaces define contracts without implementation:
public interface Drawable {
void draw(Graphics g);
void resize(double factor);
}
public class Circle implements Drawable {
@Override
public void draw(Graphics g) {
// Implementation
}
@Override
public void resize(double factor) {
// Implementation
}
}
Exception Handling
Basic Exception Handling
try {
int[] numbers = new int[5];
int value = numbers[10]; // ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Invalid array index: " + e.getMessage());
e.printStackTrace();
}
Exception Propagation
Exceptions propagate up the call stack until caught:
public void methodA() throws IOException {
methodB();
}
public void methodB() throws IOException {
// Code that may throw IOException
}
Custom Exceptions
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
Design Patterns
Model-View-Controller (MVC)
MVC separates data (Model), presenattion (View), and control logic (Controller):
// Model
public class Student {
private String name;
private int grade;
// Getters and setters
}
// View
public class StudentView {
public void displayStudentInfo(String name, int grade) {
System.out.println("Student: " + name + ", Grade: " + grade);
}
}
// Controller
public class StudentController {
private Student model;
private StudentView view;
public void updateView() {
view.displayStudentInfo(model.getName(), model.getGrade());
}
}