පහුගිය ලිපියෙන් අපි Encapsulation (දත්ත සැඟවීම) සහ Inheritance (උරුමය) ගැන ගැඹුරටම කතා කළා. අද අපි යන්නේ Java විතරක් නෙවෙයි, ඕනෑම Object-Oriented භාෂාවක තියෙන දියුණුම සහ වැදගත්ම සංකල්ප දෙකක් වන Polymorphism සහ Abstraction ගැන ඉගෙන ගන්නයි.
Software Engineering Degree එකක් කරන කෙනෙක්ට වුණත්, තමන්ගේම 2D/3D Games හදන කෙනෙක්ට වුණත් මේ සංකල්ප දෙක හරියටම තේරුම් ගන්න එක අනිවාර්යයි. මොකද ලොකු Projects වල කෝඩ් එක Manage කරන්නේ මේවා පාවිච්චි කරලයි. අපි කිසිම දෙයක් අතාරින්නේ නැතුව පතුලටම බහිමු!
🎭 3. Polymorphism (බහුරූපීතාව)
Poly කියන්නේ "ගොඩක්" (Many) කියන එක. Morphism කියන්නේ "ස්වරූපයන්/හැඩයන්" (Forms) කියන එක. ඒ කියන්නේ එකම දේ අවස්ථානුකූලව විවිධ විදිහට හැසිරීමට අපි Polymorphism කියලා කියනවා.
සැබෑ ලෝකයේ උදාහරණයක් ගත්තොත්, "ඔයා" කියන පුද්ගලයා, ගෙදරදි අම්මට "පුතෙක්" වෙනවා, Campus ගියාම "Student" කෙනෙක් වෙනවා, යාළුවොත් එක්ක ඉද්දි "Friend" කෙනෙක් වෙනවා. කෙනා එකයි, හැසිරෙන විදිහ (Forms) ගොඩයි!
- Compile-time Polymorphism (Method Overloading)
- Run-time Polymorphism (Method Overriding)
1️⃣ Compile-time Polymorphism (Method Overloading)
මේකෙදි වෙන්නේ එකම Class එකක් ඇතුලේ එකම නම තියෙන Methods කිහිපයක් හදන එකයි. හැබැයි ඒ Methods වලට පාස් කරන Parameters (Values) වෙනස් වෙන්න ඕනේ. අපි මේක Stickman Game එකක උදාහරණයකින්ම බලමු.
// 1. සාමාන්ය පහර දීම (කිසිම ආයුධයක් නෑ)
public void attack() {
System.out.println("Punching with bare hands! Damage: 10");
}
// 2. ආයුධයක් එක්ක පහර දීම (Parameter එකක් තියෙනවා)
public void attack(String weapon) {
System.out.println("Attacking with " + weapon + "! Damage: 30");
}
// 3. ආයුධයක් සහ මැජික් පවර් එකක් එක්ක පහර දීම (Parameters දෙකක් තියෙනවා)
public void attack(String weapon, int magicPower) {
System.out.println("Magic " + weapon + " attack! Damage: " + (30 + magicPower));
}
}
public class Main {
public static void main(String[] args) {
StickmanPlayer hero = new StickmanPlayer();
hero.attack(); // 1 වෙනි Method එක Call වෙනවා
hero.attack("Sword"); // 2 වෙනි Method එක Call වෙනවා
hero.attack("Axe", 50); // 3 වෙනි Method එක Call වෙනවා
}
}
Overloading රීතිය: Method එකේ නම සමාන වුණාට, Parameters වල ගාණ හරි, Type එක (int, String etc.) හරි වෙනස් වෙන්නම ඕනේ. නැත්නම් Java වලට හොයාගන්න බෑ කෝකද Call කරන්නේ කියලා.
2️⃣ Run-time Polymorphism (Method Overriding)
මේක Inheritance එක්ක බැඳිලා තියෙන දෙයක්. Parent Class එකේ තියෙන Method එකක්ම, Child Class එකේදි තමන්ට ඕන විදිහට "වෙනස් කරලා" (Override කරලා) ලියන එකට තමයි මේක කියන්නේ.
public void doAssignment() {
System.out.println("Writing assignment on a paper...");
}
}
class CSStudent extends Student {
@Override // මේ Annotation එක දැම්මම Compile කරනකොට වැරදි තියෙනවද කියල අල්ලගන්න ලේසියි.
public void doAssignment() {
System.out.println("Typing code in IDE and pushing to GitHub...");
}
}
public class Campus {
public static void main(String[] args) {
// Dynamic Method Dispatch (වැදගත්ම කොටසක්!)
Student myStudent = new CSStudent(); // Reference එක Parent ගේ, Object එක Child ගේ!
myStudent.doAssignment(); // Run වෙන්නේ CSStudent ගේ Method එකයි!
}
}
Overriding කරද්දි ඔයාට Parent ගේ පරණ Method එකත් Run කරන්න ඕනේ වුණොත්? අන්න එතනදි අපි
super කියන Keyword එක පාවිච්චි කරනවා. උඩ උදාහරණයේ Child ගේ Method එක ඇතුලේ super.doAssignment(); කියලා ලිව්වොත්, Parent ගේ පේලියත් Print වෙලා ඊට පස්සේ Child ගේ පේලියත් Print වෙනවා!
👻 4. Abstraction (වියුක්ත කිරීම / සැඟවීම)
Abstraction කියන්නේ පිටුපස සිදුවෙන සංකීර්ණ ක්රියාවලිය හංගලා, පාවිච්චි කරන කෙනාට අවශ්ය දේ විතරක් පෙන්නන එකටයි. උදාහරණයක් විදියට ඔයා ලැප්ටොප් එකේ Power Button එක එබුවම ලැප් එක On වෙනවා. ඒත් ඒක ඇතුලේ Motherboard එකේ Current එක ගමන් කරන විදිය, RAM එකට OS එක Load වෙන විදිය ඔයාට පේන්නේ නෑනේ? අන්න ඒකටයි Abstraction කියන්නේ.
- Abstract Classes (0% සිට 100% දක්වා Abstraction)
- Interfaces (100% සම්පූර්ණ Abstraction)
1️⃣ Abstract Classes භාවිතය
සමහර Classes තියෙනවා අපිට ඒවායින් කෙලින්ම Objects හදන්න බැරි. උදාහරණයක් විදියට "Shape" (හැඩය) කියලා Class එකක් තිබ්බොත්, "හැඩයක්" කියන දේට අඳින්න පුළුවන් රූපයක් නෑනේ. රූපයක් අඳින්න නම් ඒක "Circle" එකක් හරි "Square" එකක් හරි වෙන්න ඕනේ. ඒ වගේ අසම්පූර්ණ Classes වලට අපි abstract Keyword එක පාවිච්චි කරනවා.
abstract class Vehicle {
// Abstract Method (Body එකක් නෑ, Child අනිවාර්යයෙන්ම සම්පූර්ණ කරන්න ඕනේ)
abstract void startEngine();
// සාමාන්ය Method (Abstract Classes ඇතුලේ සාමාන්ය Methods තියෙන්නත් පුළුවන්)
public void honk() {
System.out.println("Beep Beep!");
}
}
class Car extends Vehicle {
@Override
void startEngine() { // අනිවාර්යයෙන්ම Abstract method එක මෙතන ලියන්නම වෙනවා
System.out.println("Car engine starts with a button.");
}
}
2️⃣ Interfaces (දැඩි නීතිරීති මාලාවක්)
අපි Part 10 වලදි කතා කළා Java වල Multiple Inheritance (තාත්තලා දෙන්නෙක්ගෙන් උරුම කරගන්න එක) බෑ කියලා. අන්න ඒකට විසඳුම තමයි Interfaces. Interface එකක් කියන්නේ නිකන්ම නිකන් "පොරොන්දු පත්රිකාවක්" වගේ දෙයක්. ඒක ඇතුලේ තියෙන හැම Method එකක්ම Abstract (Body එකක් නෑ).
interface Camera {
void takePhoto(); // මේවා නිකන්ම public abstract වෙනවා
}
interface GPS {
void getLocation();
}
// Phone එකක් හදද්දි Camera එකයි GPS එකයි දෙකම එකවර ගන්න පුළුවන් 'implements' හරහා!
class SmartPhone implements Camera, GPS {
@Override
public void takePhoto() {
System.out.println("Taking a high-res photo...");
}
@Override
public void getLocation() {
System.out.println("Finding location via Satellites...");
}
}
Interface වල වාසිය: ඔයාගේ කෝඩ් එක මාරම පිළිවෙල වෙනවා. මොකද Interface එකක් implement කරන ඕනෑම Class එකක්, ඒ Interface එකේ තියෙන Methods අනිවාර්යයෙන්ම ලියන්නම ඕනේ. මේක ලොකු Software/Games හදද්දි කණ්ඩායමේ අනිත් අයට Guidelines දෙන්න පාවිච්චි කරන ප්රධානම ක්රමයක්.
ගොඩක් අයට පැටලෙන තැනක්.
this කියන්නේ දැනට වැඩ කරන Object එකටයි. Class එකේ තියෙන Variable එකයි, Method එකකට එන Parameter එකයි එකම නම වුණොත්, Java වලට ඒක වෙන් කරලා අඳුරගන්න this.name = name; කියලා අපි පාවිච්චි කරනවා.
ඔන්න දැන් ඔයා OOP වල Pillars 4ම සුපිරියටම දන්නවා! 🎉
ඊළඟ පාඩමෙන් අපි Java Collections Framework (ArrayLists, HashMaps) වගේ Data ගබඩා කරන Advanced ක්රම ගැන පතුලටම බහිමු. KP Tech Gear එක්කම රැඳෙන්න! 👇

Discussion