OOP(Object-oriented programming)
Summary
In this post, I will cover the basics of Object Oriented Programming(OOP).
Definition
OOP is a programming paradigm that is based on the concept of objects or data instead of functions and logic. An object is a โdata field that has unique attributes and behavior.โ1 This concept is used to design a software program with simple, reusable pieces of code-classes.
It is the most popular programming paradigm today. OOP programming languages include Java, C++, Python, and Javascript.
Building blocks
- Classes
- an โabstract blueprint used to create more specific concrete objectsโ2.
- ex) often broad categories like
Car
orDog
that share attributes(color
)
- Objects
- specific examples of classes
- can have unique values to the properties in the class
- ex)
myCar
,goldenRetriever
- Methods
- distinct logic sequence
- defined within the class, available only to objects of that type
- ex)
repaint
method ofCar
class
-
Attributes
- ex)
color, brand, model
inCar
class
- ex)
4 principles of OOP
- Encapsulation
- The manipulation and state of an object are privately defined inside a class. Other objects cannot directly access and change this class (data hiding)
- adds security and avoids unintended data corruption
- ex) private class variables
- Abstraction
- hide unnecessary implementation code
- easy to make changes over time
- ex) abstract classes, interfaces
- Inheritance
- assign relationships between objects
- developers can reuse a common logic with a unique hierarchy
- Polymorphism
- objects can take more than one form
- different classes use the same interface and have their own implementation
- ex) overloading a method with different parameter sets (static polymorphism), a subclassโ overriding its superclassโ method (dynamic polymorphism)3
Examples
All the examples are written in Java and taken from tutorialspoint4.
Encapsulation
- wrapping the data(variables) and code acting on the data(methods) together as a single unit.
-
class variables are hidden from other classes & accessed only through the class methods
- declare the variables of a class as private
- provide public setter and getter methods to change & view the variable values
/* EncapTest.java */
public class EncapTest {
private String name;
private String idNum;
private int age;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getIdNum() {
return idNum;
}
public void setAge( int newAge) {
age = newAge;
}
public void setName(String newName) {
name = newName;
}
public void setIdNum( String newId) {
idNum = newId;
}
}
- class fields can be made read-only or write-only
- class can have total control over its field values
Abstraction
- hiding the implementation details from the user. only the functionality is provided to the user.4
-
the user will have the information on what the object does instead of how it does it.
- using Abstract classes and interfaces
- abstract classes canโt be instantiated
- classes that inherit from an abstract class should provide implementations to all the abstract methods in it
- Abstract Class example : class containing the abstract keyword in its declaration
/* Employee.java */
public abstract class Employee {
private String name;
private String address;
private int number;
public Employee(String name, String address, int number) {
this.name = name;
this.address = address;
this.number = number;
}
public double computePay() {
return 0.0;
}
public void mailCheck() {
System.out.println("Mailing a check to " + this.name + " " + this.address);
}
public String toString() {
return name + " " + address + " " number;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public void setAddress(String newAddress) {
address = newAddress;
}
public int getNumber() {
return number;
}
}
Inheriting the Employee class:
/* Salary.java */
public class Salary extends Employee {
private double salary; // annual salary
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
setSalary(salary);
}
public void mailCheck() {
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to " + getName() + " with salary " + salary);
}
public double getSalary() {
return salary;
}
public void setSalary(double newSalary) {
if(newSalary >= 0.0) {
salary = newSalary;
}
}
public double computePay() {
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
Instantiating the Salary class:
/* AbstractionDemo.java */
public class AbstractionDemo {
public static void main(String [] args) {
Salary s = new Salary("Choi Minjeong", "Seoul, Korea", 1, 10000.00);
Employee e = new Salary("John Smith", "Madison, WI", 2, 2400.00);
System.out.println("Call mailCheck using Salary reference --");
s.mailCheck();
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
- Abstract Methods
- want a class to contain a particular method, but want the actual implementation of that method in child classes
- contains a method signature, but no method body
- end with a semi colon(;) instead of curly braces({}),
- the class containing it must be abstract
- child class must either override the abstract method or declare itself as abstract
public abstract class Employee {
private String name;
private String address;
private int number;
public abstract double computePay();
...
}
/* Salary.java */
public class Salary extends Employee {
private double salary; // Annual salary
public double computePay() {
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
...
}
Inheritance
- one class acquires the properties (methods, fields) of another
- manage information in a hierarchical order
- superclass (base class, parent class) and subclass(derived class, child class)
extends
class Super {
.....
.....
}
class Sub extends Super {
.....
.....
}
class Calculation {
int z;
public void addition(int x, int y) {
z = x + y;
System.out.println("The sum of the given numbers:"+z);
}
public void subtraction(int x, int y) {
z = x - y;
System.out.println("The difference between the given numbers:"+z);
}
}
public class My_Calculation extends Calculation {
// inherits the methods addition(), subtration() of Calculation class
// super.variable, super.method()
public void multiplication(int x, int y) {
z = x * y;
System.out.println("The product of the given numbers:"+z);
}
public static void main(String args[]) {
int a = 20, b = 10;
My_Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.subtraction(a, b);
demo.multiplication(a, b);
}
}
When an object to My_Calculation
class gets created, a copy of the contents of the superclass is made within it. Thus, you can access the members of a superclass by using the subclass object.
Calculation demo = new My_Calculation();
// Superclass ref var can hold the subclass obj,
// but can access only the members of the superclass
demo.addition(a, b);
demo.Subtraction(a, b);
//can't call multiplication() that belongs to the subclass
IS-A Relationship
This object is a type of that object.
extends
and implements
keywords are used
public class Animal {
}
public class Mammal extends Animal {
}
public class Reptile extends Animal {
}
public class Dog extends Mammal {
public static void main(String args[]) {
Animal a = new Animal();
Mammal m = new Mammal();
Dog d = new Dog();
System.out.println(m instanceof Animal); // true
System.out.println(d instanceof Mammal); // true
System.out.println(d instanceof Animal); // true
}
}
Mammal IS-A Animal
Reptile IS-A Animal
Dog IS-A Mammal
Thus, Dog IS-A Animal as well
Interfaces use the implements
keyword.
public interface Animal {}
public class Mammal implements Animal {}
public class Dog extends Mammal {}
HAS-A relationship A certain class HAS-A certain thing
public class Vehicle{}
public class Speed{}
public class Van extends Vehicle {
private Speed sp; // Van HAS-A speed
}
A separate class of Speed
can be reused.
Types of Inheritance
Java doesnโt support multiple inheritance. classes canโt extend more than one class.
Polymorphism
- an object can take on many forms
- a parent class reference is used to refer to a child class object.
- Any Java obj that can pass more than 1 IS-A test is polymorphic.
- all Java objects are polymorphic since any object will pass the IS-A test for their own type and for the class Object.
public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}
the class Deer
has multiple inheritance and is polymorphic
- A
Deer
IS-A Animal - A
Deer
IS-A Vegetarian - A
Deer
IS-A Deer - A
Deer
IS-A Object
Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;
a reference variable can refer to any obj of its declared type or any subtype of its declared type
Virtual Methods
- a method used to override the behavior of the function in an inherited class with the same signature to achieve the polymorphism.5
virtual methods can be achieved by using the following techniques:
- override the virtual function with the inheriting class function using the same function name
- define virtual function in the derived class & call it by referring to the derived classโs obj using the ref or pointer of the base class
- no virtual keyword is used in Java
-
A virtual function should have the same name and parameters in the base and derived class.
- an IS-A relationship is necessary
- virtual function cannot be private/final/static since the private/final/static functions cannot be overridden.
- every non-static, non-final, and public method in Java is a virtual function.
- a static, final, private method are not virtual functions and cannot achieve the polymorphism
- the virtual functions can be used to achieve runtime polymorphism.
- a call to an overridden method is resolved at runtime rather than compile time.
- all Java interfaces are considered virtual functions since they depend on the implementing classes to provide the method implementation.
Virtual Method invoation example:
public class Employee {
private String name;
private String address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
this.number = number;
}
public void mailCheck() {
System.out.println("Mailing a check to " + this.name + " " + this.address);
}
}
public class Salary extends Employee {
private double salary;
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
setSalary(salary);
}
public void mailCheck() {
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to " + getName()
+ " with salary " + salary);
}
...
}
public class VirtualDemo {
public static void main(String [] args) {
Salary s = new Salary("Choi Minjeong", "Seoul, KR", 3, 3600.00);
Employee e = new Salary("John Smith", "Madison, WI", 2, 2400.00);
System.out.println("Call mailCheck using Salary reference --");
s.mailCheck();
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Choi Minjeong with salary 3600.0
Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Smith with salary 2400.0
Two Salary objects are instantiated: one using a Salary reference(s) and one using an Employee reference e.
When invoking s.mailCheck()
, the compiler sees mailCheck()
in the Salary
class at compile time, and the JVM invokes mailCheck()
in the Salary
class at run time.
Invoking e.mailCheck()
, on the other hand, the compiler sees the mailCheck()
method in the Employee
class to validate the statement at compile time because e
is an Employee
reference. The JVM, however, invokes mailCheck()
in the Salary
class at runtime.
This behavior is called virtual method invocation, and these methods are virtual methods. An overridden method is invoked at run time, no matter what data type the reference is that was used in the source code at compile time.
SOLID principles of OOP Design
- Single Responsibility Principle (SRP)
- each component should have only one responsibility
- Open Closed Principle (OCP)
- open for extension, but closed for modification.
- Liskov Substitution Principle (LSP)
- an object of a child class is able to replace an object of its base class
- Interface Segregation Principle (ISP)
- a class should not be forced to implement members that it does not need/use
- Dependency Inversion Principle (DIP)
- high-level (fundamental logic) components should not depend on low-level (specific logic) components6
characteristics
+
- code reusability
- scalability
- easier to debug as classes often contain all applicable info
- secure, protects info through encapsulation
- allows for class-specific behavior through polymorphism
- or criticism
- concern that OOP overemphasizes the data component of software developement and does not focus on computation or algorithms
- may be more complicated to write and take longer to compile
alternatives to OOP include functional programming, structured programming, and imperative programming
Leave a comment