මචං, අපි කලින් කොටස් වලදී Class එකක් කියන්නේ මොකක්ද, Object එකක් කියන්නේ මොකක්ද කියලා ගොඩක් දුරට කතා කළානේ. හැබැයි Software Engineering ලෝකයේ ඔයා කොයිම භාෂාවක් (Java, C#, Python, C++) ඉගෙන ගත්තත් ඔයා අනිවාර්යයෙන්ම දැනගෙන ඉන්න ඕන, වෘත්තීය මට්ටමේ (Professional Level) කෝඩර් කෙනෙක් වෙන්න නම් අනිවාර්යයෙන්ම පාලනය කරන්න ඕන ලොකුම සංකල්පය තමයි OOP (Object-Oriented Programming). මේ OOP කියන කූඩාරම, එහෙමත් නැත්නම් මහා මන්දිරය රඳා පවතින්නේ ප්රධාන කණු (Pillars) 4ක් මතයි. මේවා හරියට මාර්වල් යුනිවර්ස් එකේ Infinity Stones වගේ. මේ හතර තේරුම් ගත්තා කියන්නේ ඔයාට ඕනෑම ලොකු සිස්ටම් එකක් හදන්න පුළුවන් කියන එකයි.
- Encapsulation (දත්ත සැඟවීම සහ ආරක්ෂා කිරීම)
- Inheritance (උරුමය සහ කේත නැවත භාවිතය)
- Polymorphism (බහුරූපීතාව)
- Abstraction (වියුක්ත කිරීම / අනවශ්ය දේ සැඟවීම)
අද අපි මේකෙන් මුල්ම රහස් බලවේග දෙක වන Encapsulation සහ Inheritance කියන්නේ මොකක්ද කියලා, අපේ ප්රායෝගික Project උදාහරණත් එක්කම, පතුලටම බහින ගමන් ඉගෙන ගමු. මේක ටිකක් දිග Article එකක් වේවි, මොකද මට ඕනේ ඔයාට මේකේ "ඇයි මෙහෙම කරන්නේ?" කියන හේතුවත් එක්කම (Theory + Practical) කියලා දෙන්න. කෝපි එකක් හදාගෙනම ලෑස්ති වෙන්න!
🛡️ 1. Encapsulation (දත්ත සැඟවීම සහ ආරක්ෂා කිරීම)
මේ වචනේ ඇතුලෙම තියෙනවා "Capsule" (කරල) කියන වචනේ. ඔයා ෆාමසියකින් ගන්න බෙහෙත් කරලක් දිහා බැලුවොත් ඇතුලේ තියෙන තිත්ත බෙහෙත් කුඩු ටික අපිට පේන්නේ නෑ. ඒක වටේට ලස්සන ප්ලාස්ටික් වගේ ආවරණයක් තියෙනවා. අපිට ඒක ලේසියෙන්ම බොන්න පුළුවන්. Encapsulation කියන්නෙත් අන්න ඒ වගේ දෙයක් Programming වලට ගෙනාපු එකටයි.
අපේ Class එක ඇතුලේ තියෙන වැදගත් Variables (දත්ත), පිටින් ඉන්න වෙනත් Classes වලට කෙලින්ම වෙනස් කරන්න බැරි වෙන්න
private කරලා හංගන එක. ඊට පස්සේ ඒ දත්ත වෙනස් කරන්න සහ කියවන්න ඕනේ නම්, අපි ඒ සඳහාම වෙන් වුණු ආරක්ෂිත දොරවල් (Methods / Getters සහ Setters) හදලා දෙනවා. මේකෙන් Data Hiding සහ Data Security කියන දේවල් දෙකම ලැබෙනවා.
ඇයි අපිට මේක ඕනේ වෙන්නේ? (The Real Problem)
හිතන්න ඔයා බැංකු පද්ධතියක් (Banking System) හදනවා කියලා. මේකේ තියෙනවා BankAccount කියලා Class එකක්. ඒක ඇතුලේ තියෙනවා balance කියලා Variable එකක්. ඔයා මේක public කරලා තිබ්බොත් මොකද වෙන්නේ?
පිටින් ඉන්න ඕනෑම කෙනෙකුට (හිතන්න වෙනස් Class එකකින් ලියන කෝඩ් එකකට) පුළුවන් කෙලින්ම myAccount.balance = 10000000; කියලා වෙනස් කරන්න. එහෙමත් නැත්නම් myAccount.balance = -500; කියලා ඍණ ගාණක් දාන්න. බැංකු ගිණුමක සල්ලි ඍණ වෙන්න බෑනේ! අන්න ඒ වගේ අනවශ්ය විදියට අපේ දත්ත වෙනස් කරන එක නවත්තන්න තමයි අපි Encapsulation පාවිච්චි කරන්නේ.
🎮 උදාහරණය 1: Stickman Combat Game එකක්!
අපි Banking System එකට යන්න කලින් ගේම් එකක උදාහරණයක් බලමු. හිතන්න ඔයා 2D Mobile Game එකක් හදනවා කියලා. මේකේ Player ගේ Health (ජීවය) එක තියෙනවා. අපි මේ Health එක public කරලා තිබ්බොත්, ඕනම Hack tool එකකට කෙලින්ම player.health = 9999; කියලා වෙනස් කරලා ගේම් එක හොර කරන්න පුළුවන්. ඒක Encapsulation වලින් අපි නතර කරන හැටි බලමු.
// 1. දත්තය private කරලා හැංගුවා (දැන් පිටින් කාටවත් කෙලින්ම අල්ලන්න බෑ)
private int health = 100;
// 2. Getter (Health එක බලාගන්න විතරක් දෙනවා - Read Only)
public int getHealth() {
return health;
}
// 3. Setter වෙනුවට අපි දෙනවා Business Logic එකක් තියෙන Method එකක්
public void takeDamage(int damage) {
// කවුරුහරි -500ක් damage කළොත් ඒක භාරගන්නේ නැති වෙන්න Validation එකක් දානවා
if (damage > 0 && damage <= 100) {
health = health - damage;
if(health < 0) health = 0; // Health එක 0ට වඩා අඩුවෙන්න බෑ
} else {
System.out.println("⚠️ Invalid Damage Amount!");
}
}
}
දැන් දැක්කා නේද? අපේ කෝඩ් එක මාරම ආරක්ෂිතයි. කවුරුහරි පිටින් ඉඳන් player.health = 5000; කියලා දුන්නොත් Java compiler එක එතනම Error එකක් ගහනවා "health has private access in StickmanPlayer" කියලා. Health එක අඩු කරන්න ඕනේ නම් අනිවාර්යයෙන්ම takeDamage() කියන method එක හරහාම එන්න ඕනේ. ඒ method එක ඇතුලේ අපි දාලා තියෙනවා නීති (Validations). මේකට තමයි Encapsulation කියලා කියන්නේ!
🏦 උදාහරණය 2: Advanced Bank Account System
තව දුරටත් පැහැදිලි වෙන්න අපි බැංකු ගිණුමක කෝඩ් එක ලියලා බලමු. මේකෙදි අපිට බැලන්ස් එක දකින්න (View) පුළුවන්, හැබැයි සල්ලි දාද්දි (Deposit) සහ ගනිද්දි (Withdraw) අපි නීති දානවා.
// Private Variables - පිටින් පේන්නේ නෑ
private String accountNumber;
private double balance;
// Constructor එකෙන් මූලික දත්ත දානවා
public BankAccount(String accNum, double initialBalance) {
this.accountNumber = accNum;
if(initialBalance > 0) {
this.balance = initialBalance;
} else {
this.balance = 0.0;
}
}
// Getter for Balance
public double getBalance() {
return balance;
}
// Setter වෙනුවට Deposit Method එක
public void deposit(double amount) {
if(amount > 0) {
balance += amount;
System.out.println("Successfully deposited: Rs." + amount);
} else {
System.out.println("Error: Deposit amount must be positive!");
}
}
// Setter වෙනුවට Withdraw Method එක
public void withdraw(double amount) {
if(amount > 0 && amount <= balance) {
balance -= amount;
System.out.println("Successfully withdrawn: Rs." + amount);
} else {
System.out.println("Error: Insufficient funds or invalid amount!");
}
}
}
Encapsulation වලදී අපි පාවිච්චි කරන ප්රධාන ආයුධ තමයි මේ Access Modifiers. Java වල මේවා 4ක් තියෙනවා:
- private: මේක දැම්මොත් ඒ Variable එකට හෝ Method එකට යන්න පුළුවන් ඒ Class එක ඇතුලේ ඉන්න අයට විතරයි. ගෙදර කාමරයක් වගේ.
- default (මොකුත් නොලියා හිටියොත්): එකම Package (ෆෝල්ඩරේ) එකේ ඉන්න අනිත් Classes වලට යන්න පුළුවන්. මේකට Package-Private කියලත් කියනවා.
- protected: එකම Package එකේ අයට සහ වෙන Package එකක හිටියත් Inheritance (උරුමය) හරහා හැදෙන Child Classes වලට යන්න පුළුවන්.
- public: ඕනෑම තැනක ඉඳන්, ඕනෑම Class එකකට යන්න පුළුවන්. පාරේ තියෙන බස් හෝල්ට් එකක් වගේ කාටත් විවෘතයි.
🧬 2. Inheritance (උරුමය සහ කෝඩ් නැවත භාවිතය)
මේක තමයි OOP වල තියෙන ලස්සනම සහ වැදගත්ම සංකල්පය. "උරුමය" කිව්වම ඔයාට මතක් වෙන්නේ මොකක්ද? තාත්තාගෙන් පුතාට දේවල් (ඉඩකඩම්, පෙනුම, වාහන) උරුම වෙනවා නේද? Programming වලදිත් ඒක එහෙම්මමයි!
එක Class එකක (අපි මේකට කියනවා Parent Class, Super Class, හෝ Base Class කියලා) තියෙන Variables සහ Methods, තවත් අලුත් Class එකකට (Child Class, Sub Class, හෝ Derived Class) මුල ඉඳන් ලියන්නේ නැතුව කෙලින්ම උරුම කරගන්න එකයි. මේකට Java වල අපි පාවිච්චි කරන්නේ
extends කියන keyword එකයි.
ඇයි අපිට Inheritance ඕනේ වෙන්නේ?
හිතන්න ඔයා Vehicle Management System එකක් හදනවා. ඔයාට Car, Bike, Truck කියලා Classes 3ක් ඕනේ. මේ තුනේම පොදු දේවල් තියෙනවා නේද? වාහන 3ටම රෝද තියෙනවා, එන්ජිමක් තියෙනවා, Start කරන්න පුළුවන්, Stop කරන්න පුළුවන්. ඔයා මේ Classes 3 ඇතුලේ වෙන වෙනම අර දේවල් ටයිප් කර කර හිටියොත් කෝඩ් එක කොච්චර දිග වෙනවද? ඒකට අපිට පුළුවන් Vehicle කියලා ප්රධාන Class එකක් හදලා, අරවා සේරම ඒක ඇතුලේ ලියන්න. ඊට පස්සේ Car, Bike වගේ දේවල් වලට ඒ Vehicle එක උරුම (Inherit) කරලා දෙනවා. එතකොට Car එකට ආයේ මුල ඉඳන් Start method එක ලියන්න ඕනේ නෑ, ඒක ඉබේම හම්බෙනවා!
🎓 උදාහරණය 3: University Management System එකක්!
අපි මේක සරලව තේරුම් ගන්න Campus එකක System එකක් හදමු. ඒකේ Student (සාමාන්ය සිසුවා - Parent) සහ CSStudent (Computer Science කරන සිසුවා - Child) කියලා ජාති දෙකක් ඉන්නවා.
class Student {
public String name;
public int age;
public void study() {
System.out.println(name + " is studying standard subjects...");
}
}
// 2. Child Class (පුතා - Sub Class) | "extends" keyword එක බලන්න!
class CSStudent extends Student {
// මේක ඇතුලේ නම, වයස ආයේ ලියන්න ඕනේ නෑ! ඒක උරුම වෙලා ඉවරයි.
// CS අයට විතරක් තියෙන විශේෂ දේවල් විතරක් මෙතන ලියනවා.
public String programmingLanguage;
public void writeCode() {
System.out.println(name + " is coding in " + programmingLanguage);
}
}
// 3. Main Class එකේ වැඩ කරන හැටි
public class Main {
public static void main(String[] args) {
CSStudent myStudent = new CSStudent();
// Parent ගෙන් ආපු දේවල් පාවිච්චි කරනවා (Inherited members)
myStudent.name = "Kaweesha";
myStudent.age = 22;
myStudent.study(); // Output: Kaweesha is studying standard subjects...
// තමන්ගේ (Child ගේ) විශේෂ දේවල් පාවිච්චි කරනවා
myStudent.programmingLanguage = "Java";
myStudent.writeCode(); // Output: Kaweesha is coding in Java
}
}
🚀 Super Keyword එකේ මායාව (The 'super' Keyword)
Inheritance ගැන කතා කරද්දි අනිවාර්යයෙන්ම දැනගන්න ඕන දෙයක් තමයි super කියන keyword එක. සමහර වෙලාවට Child Class එකක් හැදෙද්දි, Parent Class එකේ තියෙන දේවල් (විශේෂයෙන්ම Constructors) Call කරන්න ඕනේ වෙනවා. super කියන්නේ "මගේ තාත්තා" (Parent) කියන අදහස දෙන වචනයක්.
උදාහරණයක් විදියට, Parent class එකේ Constructor එකට Parameter එකක් පාස් කරන්න ඕනේ නම්, අපි Child class එකේ Constructor එක ඇතුලේ ඉඳන් super(parameter); කියලා call කරනවා. මේක ඉතාමත් වැදගත්! Child object එකක් හැදෙන්න කලින් අනිවාර්යයෙන්ම Parent object එකේ අඩිතාලම හැදෙන්න ඕනේ.
සාමාන්ය ලෝකේ එක පුතෙකුට තාත්තලා දෙන්නෙක් ඉන්න බෑනේ. අන්න ඒ වගේම Java වල එක Class එකකට
extends කරලා Classes දෙකකින් එකපාර දේවල් උරුම කරගන්න බෑ. (උදා: class Child extends Father, Mother { } කියලා ලියන්න බෑ).ඇයි ඒ? හිතන්න Father class එකෙත්
speak() කියලා method එකක් තියෙනවා, Mother class එකෙත් speak() කියලා method එකක් තියෙනවා. දැන් Child class එක මේ දෙකම Inherit කරගත්තොත්, අපි child.speak() කියලා call කළාම Java compiler එකට පිස්සු හැදෙනවා "මම කාගේ එකද රන් කරන්න ඕනේ?" කියලා. මේකට කියන්නේ Diamond Problem කියලා. C++ වල මේක පුළුවන් වුණාට, Java හදපු අය මේ අවුල මඟහරින්න Multiple Inheritance සම්පූර්ණයෙන්ම තහනම් කළා. හැබැයි මේකට විසඳුමක් විදියට Interfaces කියන වෙනම ක්රමයක් ගෙනාවා (ඒ ගැන අපි ඉස්සරහට කතා කරමු).
🌟 Inheritance සහ Encapsulation එකට පාවිච්චි කිරීම
ගොඩක් අය හිතන්නේ මේ Pillars දෙක වෙන වෙනම තියෙන දේවල් කියලා. නෑ! හොඳ Software එකක මේ සේරම වැඩ කරන්නේ එකට. අපි කලින් Encapsulation වල කතා කළානේ private දැම්මම පිටින් අල්ලන්න බෑ කියලා. එතකොට Parent Class එකේ තියෙන Variable එකක් private කළොත්, ඒක Child Class එකට උරුම වෙනවද?
උත්තරේ: නෑ! Private දේවල් උරුම වෙන්නේ නෑ. ඒවා ඒ Class එකට විතරක් සීමා වෙනවා. හැබැයි ඔයාට ඕනේ නම් Child ට විතරක් ඒක පාවිච්චි කරන්න දෙන්න, අනිත් අයට නොදී ඉන්න, අන්න එතකොට තමයි අපි protected කියන Access Modifier එක පාවිච්චි කරන්නේ.
Code Reusability (කෝඩ් එක නැවත නැවත භාවිතය)
Inheritance වල තියෙන ලොකුම වාසිය තමයි මේක. එකම කෝඩ් එක වටේ යව යව, කොපි පේස්ට් කර කර ලියන්නේ නැතුව එක තැනක ලිව්වම, ඒක ඕනම Child Class එකකට අරගන්න පුළුවන්. මේකෙන් අපේ කෝඩ් එක පිරිසිදු වෙනවා (Clean Code), Maintenance කරන්න (පස්සේ කාලෙක වෙනසක් කරන්න) ලේසි වෙනවා. හිතන්න Vehicle class එකේ තියෙන start method එක වෙනස් කරන්න ඕනේ වුණොත්, ඒක එක තැනකින් වෙනස් කළාම, ඒකෙන් හැදුණු Car, Bike, Truck කියන හැම එකටම ඒ වෙනස ඉබේම Apply වෙනවා.
ඉදිරි කොටසින්: OOP වල ඉතුරු රහස් බලවේග 2! (Polymorphism සහ Abstraction) 🎭👻
අද අපි Encapsulation සහ Inheritance කියන දැවැන්ත සංකල්ප දෙකේ පදනම හොඳටම තේරුම් ගත්තා. මේවා ප්රායෝගිකව ඔයාගේ පොඩි ප්රොජෙක්ට් වල ලියලා බලන්න. මොනවා හරි ප්රශ්නයක් තියෙනවා නම් පල්ලෙහායින් Comment එකක් දාන්න අමතක කරන්න එපා. ඊළඟ කොටසින් මුණගැහෙමු! 👇

Discussion