JavaRush /Java Blog /Random-TL /Coffee break #90. 4 Pillars ng Object Oriented Programmin...

Coffee break #90. 4 Pillars ng Object Oriented Programming

Nai-publish sa grupo
Pinagmulan: The Geek Asian Tingnan natin ang apat na batayan ng object-oriented programming at subukang maunawaan kung paano gumagana ang mga ito. Ang Object-oriented programming (OOP) ay isa sa mga pangunahing paradigm sa programming. Maaari itong maging madali at simple o, sa kabaligtaran, napaka kumplikado. Ang lahat ay nakasalalay sa kung paano ka magpasya na bumuo ng iyong aplikasyon. Coffee break #90.  4 na haligi ng object-oriented programming - 1Mayroong 4 na haligi ng OOP:
  1. Encapsulation.
  2. Mana.
  3. Abstraction.
  4. Polymorphism.
Tatalakayin natin ngayon ang bawat isa sa kanila na may maikling paliwanag at isang tunay na halimbawa ng code.

1. Encapsulation

Lahat tayo ay nag-aral ng encapsulation bilang pagtatago ng mga elemento ng data at nagpapahintulot sa mga user na ma-access ang data gamit ang mga pampublikong pamamaraan. Tinatawag namin itong mga getter at setter. Ngayon kalimutan natin ang tungkol dito at maghanap ng mas simpleng kahulugan. Ang Encapsulation ay isang paraan ng paghihigpit sa user mula sa direktang pagpapalit ng mga miyembro ng data o mga variable ng klase upang mapanatili ang integridad ng data. Paano natin ito gagawin? Pinaghihigpitan namin ang pag-access sa mga variable sa pamamagitan ng paglipat ng access modifier sa pribado at paglalantad ng mga pampublikong pamamaraan na maaaring magamit upang ma-access ang data. Tingnan natin ang mga partikular na halimbawa sa ibaba. Makakatulong ito sa amin na maunawaan kung paano namin magagamit ang encapsulation upang mapanatili ang integridad ng data. Nang walang encapsulation:
/**
 * @author thegeekyasian.com
 */
public class Account {

  public double balance;

  public static void main(String[] args) {

  	Account theGeekyAsianAccount = new Account();

  	theGeekyAsianAccount.balance = -54;
  }
}
Sa snippet ng code sa itaas, direktang ina-access ng main() na paraan ang variable ng balanse . Nagbibigay-daan ito sa user na magtakda ng anumang dobleng halaga sa variable ng balanse ng klase ng Account . Maaari naming mawala ang integridad ng data sa pamamagitan ng pagpayag sa sinuman na magtakda ng balanse sa anumang di-wastong numero, gaya ng -54 sa kasong ito. May encapsulation:
/**
 * @author thegeekyasian.com
 */
public class Account {

  private double balance;

  public void setBalance(double balance) {

    if(balance >= 0) { // Validating input data in order to maintain data integrity
	  this.balance = balance;
    }

    throw new IllegalArgumentException("Balance cannot be less than zero (0)");
  }

  public static void main(String[] args) {

  	Account theGeekyAsianAccount = new Account();

  	theGeekyAsianAccount.setBalance(1); // Valid input - Allowed
  	theGeekyAsianAccount.setBalance(-55); // Stops user and throws exception
  }
}
Sa code na ito, pinaghigpitan namin ang pag-access sa variable ng balanse at nagdagdag ng setBalance() na paraan na nagpapahintulot sa mga user na itakda ang halaga ng balanse para sa Account . Sinusuri ng setter ang ibinigay na halaga bago ito italaga sa variable. Kung ang halaga ay mas mababa sa zero, ang isang pagbubukod ay itinapon. Tinitiyak nito na ang integridad ng data ay hindi nakompromiso. Matapos ipaliwanag ang mga halimbawa sa itaas, inaasahan kong malinaw ang halaga ng encapsulation bilang isa sa apat na haligi ng OOP.

2. Pamana

Ang inheritance ay isang paraan ng pagkuha ng mga katangian ng isa pang klase na may mga karaniwang katangian. Nagbibigay-daan ito sa amin na pataasin ang muling paggamit at bawasan ang pagdoble ng code. Ang pamamaraan ay mayroon ding prinsipyo ng pakikipag-ugnayan ng anak-magulang, kapag ang isang elemento ng bata ay nagmamana ng mga katangian ng magulang nito. Sumisid tayo sa dalawang mabilis na halimbawa at tingnan kung paano ginagawang mas simple at mas magagamit muli ng inheritance ang code. Walang mana:
/**
 * @author thegeekyasian
 */
public class Rectangle {

  private int width;
  private int height;

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

  public int getArea() {
	return width * height;
  }
}

public class Square {

  private int width; // Duplicate property, also used in class Rectangle

  public Square(int width) {
	this.width = width;
  }

  public int getArea() { // Duplicate method, similar to the class Rectangle
	return this.width * this.width;
  }
}
Ang dalawang magkatulad na klase ay nagbabahagi ng mga katangian ng lapad at ang getArea() na pamamaraan . Maaari naming dagdagan ang muling paggamit ng code sa pamamagitan ng paggawa ng kaunting refactoring kung saan ang Square class ay nagtatapos sa pagmamana mula sa Rectangle class . May mana:
/**
 * @author thegeekyasian
 */
public class Rectangle {

  private int width;
  private int height;

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

  public int getArea() {
	return width * height;
  }
}

public class Square extends Rectangle {

  public Square(int width) {
	super(width, width); // A rectangle with the same height as width is a square
  }
}
Sa simpleng pagpapalawak ng Rectangle class , nakukuha namin ang Square class bilang Rectangle type . Nangangahulugan ito na minana nito ang lahat ng katangiang karaniwan sa Square at Rectangle . Sa mga halimbawa sa itaas, nakikita natin kung paano gumaganap ng mahalagang papel ang mana sa paggawang magagamit muli ng code. Pinapayagan din nito ang isang klase na magmana ng pag-uugali ng kanyang magulang na klase.

3. Abstraction

Ang abstraction ay isang pamamaraan ng pagpapakita lamang ng mga mahahalagang detalye sa gumagamit sa pamamagitan ng pagtatago ng mga hindi kailangan o hindi nauugnay na mga detalye ng isang bagay. Nakakatulong ito na bawasan ang pagiging kumplikado ng pagpapatakbo sa panig ng gumagamit. Binibigyang-daan kami ng abstraction na magbigay ng isang simpleng interface sa user nang hindi humihingi ng mga kumplikadong detalye upang magsagawa ng isang aksyon. Sa madaling salita, binibigyan nito ang user ng kakayahang magmaneho ng kotse nang hindi kinakailangang maunawaan nila nang eksakto kung paano gumagana ang makina. Tingnan muna natin ang isang halimbawa at pagkatapos ay talakayin kung paano nakakatulong sa atin ang abstraction.
/**
* @author thegeekyasian.com
*/
public class Car {

  public void lock() {}
  public void unlock() {}

  public void startCar() {

	checkFuel();
	checkBattery();
	whatHappensWhenTheCarStarts();
  }

  private void checkFuel() {
	// Check fuel level
  }

  private void checkBattery() {
	// Check car battery
  }

  private void whatHappensWhenTheCarStarts() {
	// Magic happens here
  }
}
Sa code sa itaas, pampubliko ang lock() , unlock() at startCar () at ang iba ay pribado sa klase. Ginawa naming mas madali para sa user na "magmaneho ng kotse." Siyempre, maaari niyang manual na suriin ang checkFuel() at checkBattery() bago simulan ang kotse gamit ang startCar() , ngunit iyon ay magpapalubha lamang sa proseso. Gamit ang code sa itaas, ang kailangan lang gawin ng user ay gumamit ng startCar() at ang klase na ang bahala sa iba. Ito ang tinatawag nating abstraction.

4. Polymorphism

Ang huli at pinakamahalaga sa apat na haligi ng OOP ay polymorphism. Ang ibig sabihin ng polymorphism ay "maraming anyo." Gaya ng ipinahihiwatig ng pangalan, ito ay isang function na nagbibigay-daan sa iyong magsagawa ng isang aksyon sa maramihan o iba't ibang paraan. Kapag pinag-uusapan natin ang tungkol sa polymorphism, walang gaanong pag-uusapan maliban kung pag-uusapan natin ang tungkol sa mga uri nito. Mayroong dalawang uri ng polymorphism:
  1. Paraan ng overloading - static polymorphism (Static Binding).
  2. Pamamaraan overriding - dynamic polymorphism (Dynamic Binding).
Talakayin natin ang bawat isa sa mga uri na ito at tingnan kung ano ang pagkakaiba sa pagitan nila.

Paraan ng overloading - static polymorphism:

Ang method overloading o static polymorphism, na kilala rin bilang Static Binding o compile-time binding, ay isang uri kung saan ang mga method call ay tinutukoy sa oras ng compile. Ang overloading ng pamamaraan ay nagbibigay-daan sa amin na magkaroon ng maraming pamamaraan na may parehong pangalan, pagkakaroon ng iba't ibang uri ng data ng parameter, o iba't ibang bilang ng mga parameter, o pareho. Ngunit ang tanong ay, bakit kapaki-pakinabang ang paraan ng overloading (o static polymorphism)? Tingnan natin ang mga halimbawa sa ibaba para mas maunawaan ang paraan ng overloading. Nang walang paraan ng overloading:
/**
* @author thegeekyasian.com
*/
public class Number {

  public void sumInt(int a, int b) {
	System.out.println("Sum: " + (a + b));
  }

  public void sumDouble(double a, double b) {
	System.out.println("Sum: " + (a + b));
  }

  public static void main(String[] args) {

	Number number = new Number();

	number.sumInt(1, 2);
	number.sumDouble(1.8, 2.5);
  }
}
Sa halimbawa sa itaas, gumawa kami ng dalawang pamamaraan na may magkaibang mga pangalan, para lang magdagdag ng dalawang magkaibang uri ng mga numero. Kung magpapatuloy kami sa isang katulad na pagpapatupad, magkakaroon kami ng maraming pamamaraan na may iba't ibang pangalan. Babawasan nito ang kalidad at kakayahang magamit ng code. Upang mapabuti ito, maaari naming gamitin ang paraan ng overloading sa pamamagitan ng paggamit ng parehong pangalan para sa iba't ibang mga pamamaraan. Papayagan nito ang user na magkaroon ng isang opsyon bilang entry point para sa pagbubuod ng iba't ibang uri ng mga numero. Gumagana ang paraan ng overloading kapag ang dalawa o higit pang mga pamamaraan ay may parehong pangalan ngunit magkaibang mga parameter. Ang uri ng pagbabalik ay maaaring pareho o iba. Ngunit kung ang dalawang pamamaraan ay may parehong pangalan, parehong mga parameter, ngunit magkaibang mga uri ng pagbabalik, ito ay magdudulot ng labis na karga at isang error sa compilation! Sa paraan ng overloading:
/**
* @author thegeekyasian.com
*/
public class Number {

  public void sum(int a, int b) {
	System.out.println("Sum: " + (a + b));
  }

  public void sum(double a, double b) {
	System.out.println("Sum: " + (a + b));
  }

  public static void main(String[] args) {

	Number number = new Number();

	number.sum(1, 2);
	number.sum(1.8, 2.5);
  }
}
Sa parehong code, na may ilang maliliit na pagbabago, na-overload namin ang parehong mga pamamaraan, na ginagawang pareho ang mga pangalan para sa pareho. Maaari na ngayong tukuyin ng user ang kanilang mga partikular na uri ng data bilang mga parameter ng pamamaraan. Magsasagawa ito ng pagkilos batay sa uri ng data na ibinigay nito. Ang pamamaraang ito na nagbubuklod ay ginagawa sa oras ng pag-compile dahil alam ng compiler kung aling paraan ang tatawagin gamit ang tinukoy na uri ng parameter. Kaya naman tinatawag namin itong compile-time binding.

Overriding ng pamamaraan - dynamic na polymorphism:

Hindi tulad ng overloading ng pamamaraan, ang pag-override ng pamamaraan ay nagbibigay-daan sa iyo na magkaroon ng eksaktong kaparehong lagda sa maraming pamamaraan, ngunit dapat ay nasa maraming magkakaibang klase ang mga ito. Ang tanong, ano ang espesyal dito? Ang mga klase na ito ay may IS-A na relasyon, ibig sabihin, dapat silang magmana sa isa't isa. Sa madaling salita, sa paraan na overriding o dynamic na polymorphism, ang mga pamamaraan ay dynamic na pinoproseso sa runtime kapag tinawag ang pamamaraan. Ginagawa ito batay sa sanggunian sa bagay kung saan ito nasimulan. Narito ang isang maliit na halimbawa ng paraan ng pag-override:
/**
* @author thegeekyasian.com
*/
public class Animal {

  public void walk() {
	System.out.println("Animal walks");
  }
}

public class Cat extends Animal {

  @Override
  public void walk() {
	System.out.println("Cat walks");
  }
}

public class Dog extends Animal {

  @Override
  public void walk() {
	System.out.println("Dog walks");
  }
}

public class Main {

  public static void main(String[] args) {

	Animal animal = new Animal();
	animal.walk(); // Animal walks

	Cat cat = new Cat();
	cat.walk(); // Cat walks

	Dog dog = new Dog();
	dog.walk(); // Dog walks

	Animal animalCat = new Cat(); // Dynamic Polymorphism
	animalCat.walk(); // Cat walks

	Animal animalDog = new Dog(); // Dynamic Polymorphism
	animalDog.walk(); //Dog walks
  }
}
Sa overriding na halimbawang ito, pabago-bago naming itinalaga ang mga bagay na may uri ng "Aso" at "Pusa" upang i-type ang "Animal". Nagbibigay-daan ito sa amin na tawagan ang walk() na pamamaraan sa mga na-refer na pagkakataon nang pabago-bago sa runtime. Magagawa natin ito gamit ang overriding na pamamaraan (o dynamic polymorphism). Ito ay nagtatapos sa aming maikling talakayan sa apat na haligi ng OOP at umaasa ako na kapaki-pakinabang ito.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION