Encapsulation

In procedural programming language like C, data and behavior are mixed together in one file. The data can be accessed in any behavior. It means that some data can be changed by some behaviors that are not associated with that data. It leads to data corruption.

Reason for Data Insecurity in Procedural Programming

  • It is the global variables that leads to data insecurity
  • Global variables can be accessed in any functions in the program. So it means that the value of the global variables can be changed by the unrelated functions.
  • Whenever unrelated functions accessed that data, data corruption arises.

For example:


#include <stdio.h>

int result = 0;

int main() {
	result = sum(5, 5);
	printResult();
	return 0;
}

int sum(int firstNumber, int secondNumber) {
	return firstNumber + secondNumber;
}

int multiply(int firstNumber, int secondNumber) {
	return firstNumber * secondNumber;
}

void printResult() {
	printf("Result is %d", result);
}

void unrelatedFunction() { //assuming some unrelated behavior accesses the "result" variable
	result++;
}

Encapsulation?

Encapsulation is one of the core concepts in object oriented programming. Encapsulation is the binding of data with their corresponding behavior.

What is binding?

  • The concept of restricting the availability of the data only to its related areas and related functions it is known as binding.
  • Because of binding we can restrict the availability of data to the unrelated functions
  • So that unrelated functions cannot access the data
  • Class is the base for encapsulation
public class Room {

	private long id;
	private String roomName;
	private String building;

	public String getRoomName() {
		return roomName;
	}

	public void setRoomName(String roomName) {
		this.roomName = roomName;
	}

	public String getBuilding() {
		return building;
	}

	public void setBuilding(String building) {
		this.building = building;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (id ^ (id >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Room other = (Room) obj;
		if (id != other.id)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return roomName + " " + building;
	}
}

Abstraction

Abstraction is a way of dealing with things in a general way as much as possible, separate from specific details, implementations and instances.

According to wikipedia:

Abstraction is a mechanism and practice to reduce and factor out details so that one can focus on a few concepts at a time.

In this blog post, I will show to you simple ways how to achieve abstraction. Some of you implemented this concept but you’re unaware of it.

Abstraction via Functions

  • Processes can be grouped into functions
  • One function can call other function
  • You don’t have to understand each line, just what the function does
  • You can hide data to be accessible only within the function – local variables

double areaOfCircle(int radius) {

	return PI * radius * radius;

}

boolean isFirstBiggerThanSecond(int radius1, int radius2) {
	double area1, area2;
	area1 = areaOfCircle(radius1);
	area2 = areaOfCircle(radius2);
	return area1 > area2;
}

The areaOfCircle() method computes the area of the circle. The isFirstBiggerThanSecond() method compares the size of the circle if the first circle is bigger than the second one given the radius of the two. The isFirstBiggerThanSecond() called the areaOfCircle(). The one who writes the code of the isFirstBiggerThanSecond() method does not need to know how the implementation of the areaOfCircle() method. What he need to do is just to know what the areaOfCircle() does. The implementation on how to compute the area of the circle is separated and factored out so that who will ever use that method does not need to know how the computation is done, only what the function does.

Abstraction via Objects

Combining complex data types and the functions that operates on them give you objects.

public class Rectangle {
    private int length;
    private int width;

    public Rectangle (int length, int width) {
        this.length = length;
        this.width width;
    }

    public int area() {
        return length * width;
    }

    public boolean isBiggerThan(Rectangle other) {
        return this.area() > other.area();
    }   
}

Rectangle rect1 = new Rectangle(3, 4);
Rectangle rect2 = new Rectangle(5, 6);

if (rect1.isBiggerThan(rect2)) {
    buyPaint(rect2.area());
} else {
    buyPaint(rect1.area());
}

Objects are mini-programs, each with its own data and operations.

In Unix, we have a lot of little programs (grep, ls, cat…) that do just one thing. We can combine the little programs into bigger programs by having the output of one become the input of another.

OOP is the same. We make small, simple, specialized programs, and then make bigger programs by combining little programs (“Composition”).

“Think of an OO system as a bunch of intelligent animals (the objects) inside your machine, talking to each other by sending messages to one another.” – Allen Holub

OOP is a way to make programs easier to understand, by allowing bigger programs to be composed of smaller programs, and those smaller programs to be composed of even smaller programs, ad infinitum.

Those are only simple concepts that relates to abstraction. I found an interesting article which discusses abstraction using interface and abstract class in java.

StringBuilder Class

I wrote a blog post about String and StringBuilder last week but I haven’t discussed more in detail about StringBuilder. So in this blog post, I will talk about more in detail on StringBuilder class in Java.

StringBuilder is a mutable sequence of characters. It means that when you modify the contents of the StringBuilder object, java does not instantiate intermediate String objects (except for any String literal you pass into the StringBuilder) unlike String.


new StringBuilder("Live").append("What").append("You").append("Love");

//LiveWhatYouLove

Since StringBuilder is mutable, it can perform these operations:

  1.  Append – appends the string representation of the parameter(boolean, int, char, double, object, etc) to the char sequence.

Append method is overloaded so it can receive different data types like int, long, double, boolean.


new StringBuilder("You are").append(true).append(2).append("me");

//You are true2me

2.  Insert – appends the string representation of  the parameter(boolean, int, char, double, object, etc) to the char sequence. It differs to append because in insert, you can specify the place where you insert whereas append you just adding or concatenating the string after the last character.


StringBuilder couple = new StringBuilder("JunaldBeverly");

couple.insert(6, " Love ");

//Junald Love Beverly

3. Delete – deletes the substring in the char sequence based on the starting index and ending index.


StringBuilder greeting = new StringBuilder("Happy New Year");

greeting.delete(5, 8);

//Happy Year

4. Reverse –  reverses the char sequence.


StringBuilder food = new StringBuilder("stressed");

food = food.reverse();

//desserts

There are lot of methods in StringBuilder like substring, replace, trimToSize. If you want to learn more about those methods you must check out the Java documentation.

If you liked this post, don’t forget to share! Thanks

 

String and StringBuilder

In this blog post, I’ll talk about String and StringBuilder.

String is immutable. Immutable means its contents cannot be altered.


String message = "I Love You";

message = "I Love You Beverly";

Consider the code above, the value of the message variable has not altered but actually java creates two different objects.

“I Love You” value does not garbage collected right away after being deferenced. The value is actually stored in “String Pool”, a special memory for Strings.

This is what happens in the String Pool after the code above is executed,
string-pool1
After the “I Love You” value is being deferenced, the value still exists in the String Pool. So that if the value is needed elsewhere in the application, java does not need to instantiate new String object.

For example,
string-pool1
Assuming the “I Love You” value is needed somewhere in the application, java does not instantiate new String object, it rather finds the existing value in the String Pool.

This helps with performance if certain strings are used over and over in the application because there are no cost of repeated String instantiation. However things get complicated if we try to “modify” a string.

String greeting = "Happy"
greeting = greeting + " ";
greeting = greeting + "Birthday";
greeting = greeting + " ";
greeting = greeting + "Beverly";

As what I’ve discussed earlier, Strings are immutable, you can never modify a String, instead you create new one.

For the code above 9 String objects are instantiated:

  1. “Happy”
  2. ” “
  3. “Happy “
  4. “Birthday”
  5. “Birthday “
  6. “Beverly”
  7. “Happy Birthday”
  8. “Happy Birthday “
  9. “Happy Birthday Beverly”

This is what happen in the String Pool

string-pool1

This could lead to large memory consumption because of multiple String instantiation. In the other words, performance will suffer if you will use String that will handle multiple string manipulations.

If your application needs to handle a lot of String manipulation, consider using StringBuilder.

StringBuilder is mutable sequence of characters unlike String.

Since StringBuilder is mutable, the contents of the strings can be altered without making multiple instantiation, hence, performance will not suffer.

For StringBuilder click here.

Conclusion

Use String if have only few String manipulation like concatenating short messages.

If a string-manipulation might leave a lot of objects in the StringPool, or performance is a high priority, consider StringBuilder.