OOP - Principles

Download as pdf or txt
Download as pdf or txt
You are on page 1of 11

OOP

OOP stands for Object-Oriented Programming. Procedural programming is about


writing procedures or methods that perform operations on the data, while object-
oriented programming is about creating objects that contain both data and methods.

Main Class / Super Class


Definitions: A class that is derived from another class is called a subclass (also a
derived class, extended class, or child class). The class from which the subclass is
derived is called a superclass (also a base class or a parent class).
Sub Class
a primary division of a class. a subordinate class, especially one of persons who lack
the rights and privileges of the primary class: a subclass of migrant workers. Biology.
a category of related orders within a class.
Constructor

A constructor in Java is a special type of method that is used to initialize objects.


When an object is created, the constructor is called automatically. Here are some
key points about constructors in Java:

1. Name: The constructor must have the same name as the class it is in.
2. No Return Type: Constructors do not have a return type, not even void.
3. Purpose: The primary purpose of a constructor is to initialize the newly created
object.
4. Types of Constructors:
• Default Constructor: A constructor that takes no arguments. If no constructor is
explicitly defined, Java provides a default constructor.
• Parameterized Constructor: A constructor that takes one or more arguments,
allowing for more flexible initialization of objects.

Example of a Constructor in Java

Here's a simple example demonstrating both a default constructor and a


parameterized constructor:

public class Dog {


String name;
int age;

// Default constructor
public Dog() {
this.name = "Unknown";
this.age = 0;
}

// Parameterized constructor
public Dog(String name, int age) {
this.name = name;
this.age = age;
}

public void display() {


System.out.println("Name: " + name + ", Age: " + age);
}

public static void main(String[] args) {


// Creating objects using different constructors
Dog dog1 = new Dog();
Dog dog2 = new Dog("Buddy", 3);

dog1.display(); // Output: Name: Unknown, Age: 0


dog2.display(); // Output: Name: Buddy, Age: 3
}
}

Constructor Overloading

Just like other methods, constructors can be overloaded. This means you can have
more than one constructor in a class with different parameter lists.

Constructor Chaining

In Java, you can call one constructor from another constructor in the same class
using this(). This is called constructor chaining.

Variables
Variables in Java are used to store data that can be used and manipulated within a
program. They act as containers for storing data values. Each variable in Java has a
specific type, which determines the kind of data it can hold.

Types of Variables in Java

1. Local Variables:

• Declared within a method, constructor, or block.


• Accessible only within the scope of the method, constructor, or block in which they
are declared.
• Must be initialized before use.

2. Instance Variables (Non-static fields):


• Declared within a class but outside any method, constructor, or block.
• Each instance (object) of the class has its own copy of instance variables.
• Default initialized if not explicitly initialized (e.g., null for objects, 0 for integers).

3. Class Variables (Static fields):

• Declared with the static keyword within a class, outside any method, constructor, or
block.
• Shared among all instances of the class.
• Default initialized if not explicitly initialized.

Declaration and Initialization

Variables must be declared with a type and can be initialized at the time of
declaration or later in the code.

public class VariablesExample {

// Instance variable
int instanceVariable;

// Class variable (static field)


static int classVariable;

public void method() {


// Local variable
int localVariable = 10;

System.out.println("Local Variable: " + localVariable);


}

public static void main(String[] args) {


// Local variable in main method
VariablesExample example = new VariablesExample();

// Accessing instance variable


example.instanceVariable = 20;
System.out.println("Instance Variable: " + example.instanceVariable);

// Accessing class variable


VariablesExample.classVariable = 30;
System.out.println("Class Variable: " + VariablesExample.classVariable);
}
}

Variable Types
1. Primitive Types: These include int, char, boolean, byte, short, long, float, and
double.

2. int number = 5;
3. char letter = 'A';
4. boolean flag = true;

Reference Types: These include objects, arrays, and strings.


String text = "Hello, World!";
int[] numbers = {1, 2, 3, 4, 5};
VariablesExample example = new VariablesExample();

Set Method
In Java, set methods, also known as "setter" methods, are part of the class design
used to modify the value of private fields in a class. They provide a controlled way to
set the value of an instance variable, allowing for encapsulation and data hiding. This
practice adheres to the principles of object-oriented programming.

Characteristics of Setter Methods

1. Naming Convention: Typically, setter methods are named using the prefix set
followed by the name of the field with the first letter capitalized.
2. Access Modifier: They are usually public, allowing external code to modify the value
of private fields.
3. Parameter: They take a parameter that represents the new value to be assigned to
the field.
4. No Return Value: Set methods typically have a void return type, as their primary
purpose is to set a value.

public class Person {


// Private fields
private String name;
private int age;

// Public setter method for name


public void setName(String name) {
this.name = name;
}

// Public setter method for age


public void setAge(int age) {
if (age > 0) { // Adding a simple validation
this.age = age;
}
}

// Getter methods
public String getName() {
return name;
}

public int getAge() {


return age;
}

public static void main(String[] args) {


Person person = new Person();

// Using setter methods to set values


person.setName("Alice");
person.setAge(30);

// Using getter methods to get values


System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
}
}

Benefits of Setter Methods

1. Encapsulation: By using private fields and public setter methods, you encapsulate
the internal representation of the object, which allows you to control how the data is
modified.
2. Validation: You can add validation logic within the setter method to ensure that only
valid data is assigned to the fields.
3. Flexibility: If the internal implementation changes, the setter methods can provide a
consistent interface for modifying the object's state without affecting the external
code that uses the class.

Additional Example with Validation

Here's another example where the setter method includes validation logic:

public class Account {


private double balance;

// Setter method with validation


public void setBalance(double balance) {
if (balance >= 0) {
this.balance = balance;
} else {
System.out.println("Invalid balance. Balance cannot be negative.");
}
}

public double getBalance() {


return balance;
}

public static void main(String[] args) {


Account account = new Account();

// Attempt to set a valid balance


account.setBalance(100.50);
System.out.println("Balance: $" + account.getBalance());

// Attempt to set an invalid balance


account.setBalance(-50.00);
}
}

Get Method
In Java, get methods, also known as "getter" methods, are used to retrieve the value
of private fields in a class. They provide a controlled way to access the value of an
instance variable, supporting encapsulation and data hiding.

Characteristics of Getter Methods

1. Naming Convention: Typically, getter methods are named using the prefix get
followed by the name of the field with the first letter capitalized.
2. Access Modifier: They are usually public, allowing external code to read the value of
private fields.
3. Return Value: They return the value of the field they are associated with.
4. No Parameters: Getter methods typically do not take any parameters.

Example of Getter Methods

Here’s an example illustrating how getter methods are used:

public class Person {


// Private fields
private String name;
private int age;

// Constructor
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Public getter method for name
public String getName() {
return name;
}

// Public getter method for age


public int getAge() {
return age;
}

public static void main(String[] args) {


Person person = new Person("Alice", 30);

// Using getter methods to get values


System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
}
}

Benefits of Getter Methods

1. Encapsulation: By using private fields and public getter methods, you encapsulate
the internal representation of the object, which allows you to control how the data is
accessed.
2. Read-Only Access: Getter methods provide read-only access to the fields,
preventing unauthorized modification.
3. Flexibility: If the internal implementation changes, the getter methods can provide a
consistent interface for accessing the object's state without affecting the external
code that uses the class.

Example with Both Setter and Getter Methods

Here’s an example demonstrating both setter and getter methods:

public class Account {


private double balance;

// Setter method
public void setBalance(double balance) {
if (balance >= 0) {
this.balance = balance;
} else {
System.out.println("Invalid balance. Balance cannot be negative.");
}
}

// Getter method
public double getBalance() {
return balance;
}

public static void main(String[] args) {


Account account = new Account();

// Using setter method to set balance


account.setBalance(100.50);

// Using getter method to get balance


System.out.println("Balance: $" + account.getBalance());
}
}

toString
In Java, the toString method is used to provide a string representation of an object. It
is defined in the Object class, which is the superclass of all classes in Java. By
default, the toString method returns a string that consists of the class name followed
by the @ symbol and the object's hashcode in hexadecimal form. However, it is
common practice to override this method to provide a more meaningful string
representation of an object.

Default toString Method

The default implementation in the Object class looks something like this:

public String toString() {


return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

Overriding the toString Method

To provide a more informative string representation of an object, you can override


the toString method in your class. Here’s an example:

public class Person {


private String name;
private int age;

public Person(String name, int age) {


this.name = name;
this.age = age;
}

// Overriding the toString method


@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}

public static void main(String[] args) {


Person person = new Person("Alice", 30);
System.out.println(person); // Output: Person{name='Alice', age=30}
}
}

Benefits of Overriding toString

1. Readability: Provides a human-readable description of the object, which is useful for


debugging and logging.
2. Information: Can include important information about the object’s state, making it
easier to understand its current condition.
3. Convenience: Automatically called when an object is concatenated with a string, or
when the object is printed using System.out.println.

Example with Different Fields

Here’s another example with a different class to show how you can override the
toString method:

public class Book {


private String title;
private String author;
private int year;

public Book(String title, String author, int year) {


this.title = title;
this.author = author;
this.year = year;
}

// Overriding the toString method


@Override
public String toString() {
return "Book{title='" + title + "', author='" + author + "', year=" + year + "}";
}

public static void main(String[] args) {


Book book = new Book("1984", "George Orwell", 1949);
System.out.println(book); // Output: Book{title='1984', author='George Orwell',
year=1949}
}
}

Method Overloading
Method overloading in Java is a feature that allows a class to have more than one
method with the same name, but with different parameter lists. It is a form of
polymorphism (specifically, compile-time polymorphism) that enables methods to
perform similar but slightly varied operations based on different inputs.

Key Points of Method Overloading

1. Method Signature: Overloaded methods must have different parameter lists (different
types, number, or order of parameters). The return type can be different, but it alone
is not sufficient to overload a method.
2. Compile-Time Polymorphism: The decision about which method to invoke is made at
compile-time based on the method signature.
3. Ease of Use: Method overloading increases the readability and reusability of code by
allowing methods with the same name to handle different data types or numbers of
arguments.

Example of Method Overloading

Here’s an example demonstrating method overloading:

public class MathOperations {

// Method to add two integers


public int add(int a, int b) {
return a + b;
}

// Overloaded method to add three integers


public int add(int a, int b, int c) {
return a + b + c;
}

// Overloaded method to add two double values


public double add(double a, double b) {
return a + b;
}

public static void main(String[] args) {


MathOperations math = new MathOperations();

// Calling the different overloaded methods


System.out.println(math.add(5, 10)); // Output: 15
System.out.println(math.add(5, 10, 15)); // Output: 30
System.out.println(math.add(5.5, 10.5)); // Output: 16.0
}
}

Benefits of Method Overloading


1. Readability: Method overloading allows methods to be named according to their
functionality rather than the parameter types, making the code easier to read.
2. Code Reusability: It allows for code reuse without needing to write multiple methods
with different names for similar operations.
3. Consistent Interface: Provides a consistent method interface that can handle
different data types and numbers of arguments, making the API easier to use and
understand.

Rules for Method Overloading

• Different Parameter List: Methods must have different parameter lists (different
types, number, or order of parameters).
• Return Type: The return type can be different, but it alone does not differentiate
overloaded methods.
• Access Modifiers: Methods can have different access modifiers, though this is not a
requirement for overloading.
• Static Methods: Static methods can also be overloaded in the same way as instance
methods.

Example with Different Parameter Types

public class Display {

// Method to display an integer


public void show(int a) {
System.out.println("Integer: " + a);
}

// Overloaded method to display a string


public void show(String a) {
System.out.println("String: " + a);
}

// Overloaded method to display a double


public void show(double a) {
System.out.println("Double: " + a);
}

public static void main(String[] args) {


Display display = new Display();

// Calling the different overloaded methods


display.show(10); // Output: Integer: 10
display.show("Hello"); // Output: String: Hello
display.show(10.5); // Output: Double: 10.5
}
}

You might also like