Object-Oriented Basics
Constructors
Object Initialization
Creating a Person object shouldn't require separate calls to set name and age.
Constructors let you initialize an object in one step: new Person("Alice", 30)
creates a fully-formed object immediately.
Default constructor
The constructor Java provides when you don't write one.
public class DefaultConstructor {
public static void main(String[] args) {
System.out.println("=== Default Constructor ===\n");
// Java provides default constructor when you write none
SimpleClass obj = new SimpleClass();
System.out.println("Object created with default constructor");
System.out.println("number: " + obj.number); // Default: 0
System.out.println("text: " + obj.text); // Default: null
System.out.println("flag: " + obj.flag); // Default: false
// We can still set fields after construction
obj.number = 42;
obj.text = "Hello";
obj.flag = true;
System.out.println("\nAfter setting values:");
System.out.println("number: " + obj.number);
System.out.println("text: " + obj.text);
System.out.println("flag: " + obj.flag);
System.out.println("\n=== No Default If You Write One ===");
// WithConstructor obj2 = new WithConstructor(); // Error!
WithConstructor obj2 = new WithConstructor("Required");
System.out.println("value: " + obj2.value);
}
}
// Class without explicit constructor
class SimpleClass {
int number;
String text;
boolean flag;
// Java adds this automatically:
// SimpleClass() { }
}
// Class with explicit constructor
class WithConstructor {
String value;
WithConstructor(String v) { // No default constructor now!
value = v;
}
}
No-arg constructor sets fields to defaults: 0, null, false.
Parameterized constructor
Accept values to initialize fields.
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
public class ParameterizedConstructor {
public static void main(String[] args) {
System.out.println("=== Parameterized Constructor ===\n");
// Create Person with required data
int firstAge = ;
String secondName = ;
Person alice = new Person("Alice", firstAge);
Person bob = new Person(secondName, 25);
System.out.println("Created: " + alice.describe());
System.out.println("Created: " + bob.describe());
// No way to create incomplete Person!
// Person invalid = new Person(); // Won't compile
System.out.println("\n=== Benefits ===");
System.out.println("✓ Object is fully initialized immediately");
System.out.println("✓ Can't forget to set required fields");
System.out.println("✓ Clear what data is needed");
}
}
class Person {
String name;
int age;
// Parameterized constructor
Person(String name, int age) {
this.name = name;
this.age = age;
}
String describe() {
return name + " (age " + age + ")";
}
}
Constructor name matches class name. No return type, not even void.
Constructor overloading
Multiple constructors for different creation scenarios.
public class ConstructorOverloading {
public static void main(String[] args) {
System.out.println("=== Constructor Overloading ===\n");
// Multiple ways to create a Book
Book book1 = new Book();
System.out.println("1. " + book1.describe());
Book book2 = new Book("1984");
System.out.println("2. " + book2.describe());
Book book3 = new Book("1984", "George Orwell");
System.out.println("3. " + book3.describe());
Book book4 = new Book("1984", "George Orwell", 328);
System.out.println("4. " + book4.describe());
System.out.println("\n=== Flexibility ===");
System.out.println("Same class, 4 ways to construct!");
System.out.println("Choose based on what data you have.");
}
}
class Book {
String title;
String author;
int pages;
// Constructor 1: No arguments (defaults)
Book() {
title = "Untitled";
author = "Unknown";
pages = 0;
}
// Constructor 2: Title only
Book(String title) {
this.title = title;
author = "Unknown";
pages = 0;
}
// Constructor 3: Title and author
Book(String title, String author) {
this.title = title;
this.author = author;
pages = 0;
}
// Constructor 4: All fields
Book(String title, String author, int pages) {
this.title = title;
this.author = author;
this.pages = pages;
}
String describe() {
String result = "\"" + title + "\" by " + author;
if (pages > 0) {
result += " (" + pages + " pages)";
}
return result;
}
}
Provide several constructors for flexible object creation.
Constructor chaining
Call one constructor from another.
public class ConstructorChaining {
public static void main(String[] args) {
System.out.println("=== Constructor Chaining with this() ===\n");
// Create products with different constructors
Product p1 = new Product();
Product p2 = new Product("Laptop");
Product p3 = new Product("Phone", 999.99);
Product p4 = new Product("Tablet", 599.99, 50);
System.out.println("1. " + p1.describe());
System.out.println("2. " + p2.describe());
System.out.println("3. " + p3.describe());
System.out.println("4. " + p4.describe());
System.out.println("\n=== Why Chain? ===");
System.out.println("✓ Avoids code duplication");
System.out.println("✓ Single place for initialization logic");
System.out.println("✓ Easy to maintain");
}
}
class Product {
String name;
double price;
int stock;
// Primary constructor - all parameters
Product(String name, double price, int stock) {
System.out.println(" [Primary constructor called]");
this.name = name;
this.price = price;
this.stock = stock;
}
// Chain to primary with default stock
Product(String name, double price) {
this(name, price, 0); // Calls primary constructor
System.out.println(" [Two-arg constructor finished]");
}
// Chain to two-arg with default price
Product(String name) {
this(name, 0.0); // Calls two-arg constructor
System.out.println(" [One-arg constructor finished]");
}
// Chain to one-arg with default name
Product() {
this("Unknown"); // Calls one-arg constructor
System.out.println(" [No-arg constructor finished]");
}
String describe() {
return name + " ($" + price + ", " + stock + " in stock)";
}
}
this(args) calls another constructor. Must be first statement.
Validate in constructor
Reject invalid data at creation time.
public class Validation {
public static void main(String[] args) {
System.out.println("=== Validation in Constructors ===\n");
// Valid accounts
Account acc1 = new Account("ACC001", 100.0);
System.out.println("Created: " + acc1.describe());
Account acc2 = new Account("ACC002", 0.0);
System.out.println("Created: " + acc2.describe());
System.out.println("\n=== Invalid Attempts ===");
// Invalid: null ID
try {
new Account(null, 100.0);
} catch (IllegalArgumentException e) {
System.out.println("Rejected null ID: " + e.getMessage());
}
// Invalid: empty ID
try {
new Account("", 100.0);
} catch (IllegalArgumentException e) {
System.out.println("Rejected empty ID: " + e.getMessage());
}
// Invalid: negative balance
try {
new Account("ACC003", -50.0);
} catch (IllegalArgumentException e) {
System.out.println("Rejected negative: " + e.getMessage());
}
System.out.println("\n=== Benefit ===");
System.out.println("Invalid objects can NEVER be created!");
}
}
class Account {
final String id;
double balance;
Account(String id, double balance) {
// Validate ID
if (id == null || id.isEmpty()) {
throw new IllegalArgumentException("ID cannot be null or empty");
}
// Validate balance
if (balance < 0) {
throw new IllegalArgumentException("Balance cannot be negative");
}
// All validations passed - initialize
this.id = id;
this.balance = balance;
}
String describe() {
return "Account " + id + ": $" + balance;
}
}
Throw exceptions for invalid arguments. Prevent invalid objects from existing.
Exercise: CompleteExample.java
Create a complete class with multiple constructors and validation