කලින් Part 08 එකෙන් අපි OOP ලෝකයට අඩිය තිබ්බා විතරයි. Class එකක් කියන්නේ ප්ලෑන් එකක් (Blueprint) කියලත්, Object එකක් කියන්නේ ඒ ප්ලෑන් එකෙන් හදන ඇත්තම දේ කියලත් අපි ඉගෙන ගත්තා. හැබැයි Software Engineering පන්තියකදී නම් ඔය ටික දැනගෙන මදි.
පිටින් බලද්දි පේන කෝඩ් එකට වඩා, කෝඩ් එක Run වෙද්දි Computer එකේ RAM එක ඇතුලේ මොකද වෙන්නේ? public, private වගේ වචන වල තේරුම මොකක්ද? Interview එකකදී අහන අමාරුම ප්රශ්න වලට උත්තර දෙන්නේ කොහොමද? අන්න ඒ යටිකූට්ටු වැඩ ටික (Under the hood mechanics) තමයි අද අපි ගැඹුරටම හාරලා බලන්නේ. මේක හරියටම Campus එකක දෙන සම්පූර්ණ Lecture මොඩියුල් එකක් වගේ තමයි මම ලෑස්ති කරලා තියෙන්නේ. ලෑස්තිද? එහෙනම් පටන් ගමු! 🚀
1. Memory Management: RAM එක ඇතුලේ Objects හැදෙන හැටි 🧠
අපි Object එකක් හදද්දි ලියන කෝඩ් එක මතකද? SmartPhone p1 = new SmartPhone();. මේ පේළිය ලිව්වම Computer එකේ Memory එක (RAM එක) ඇතුලේ මොකද වෙන්නේ කියලා දන්නවද? Java වල ප්රධාන Memory කොටස් දෙකක් තියෙනවා: Stack Memory සහ Heap Memory.
📦 Stack vs Heap (මතක තබාගන්නම ඕන දෙයක්)
- Stack Memory: මේක හරියට ඔයාගේ සාක්කුව වගේ. පොඩි දේවල් තමයි දාන්නේ. අපි හදන Variables (උදා:
int a = 10;) සහ Object එකේ නම (Reference/Pointer එක) හැදෙන්නේ මෙතනයි. ඒ කියන්නේ අරp1කියන නම තියෙන්නේ Stack එකේ. Stack එක හරිම වේගවත්. - Heap Memory: මේක හරියට ලොකු ගබඩාවක් (Warehouse) වගේ. අපි
newකියන වචනේ පාවිච්චි කළාම, ඒ ලොකු Object එක (අර රැම් එක, පාට, බ්රෑන්ඩ් එක ඔක්කොම තියෙන ලොකු ෆෝන් එක) හැදෙන්නේ මේ Heap එක ඇතුලෙයි.
සම්බන්ධය: Stack එකේ තියෙන p1 කියන Variable එකෙන් කරන්නේ, Heap එකේ හැදිලා තියෙන ලොකු Object එක ඉන්නේ කොතනද කියලා ඇඟිල්ල දික් කරලා පෙන්නන එක (Pointing) විතරයි. හරියට TV රිමෝට් එකයි, TV එකයි වගේ! p1 කියන්නේ රිමෝට් එක.
🔍 Deep Dive: String Pool කියන්නේ මොකක්ද?
Interview වලදී අහන ලොකුම ප්රශ්නයක් තමයි මේක. Heap Memory එක ඇතුලේ තියෙනවා වෙනම පොඩි කාමරයක්. ඒකට කියන්නේ String Constant Pool (SCP) කියලා. Java වල Strings හදන විදිය අනුව Memory එක හැදෙන විදිය වෙනස් වෙනවා.
String s2 = "Apple"; // අලුතින් හැදෙන්නේ නෑ! s1 ගේ එකටමයි s2 ත් Point කරන්නේ.
String s3 = new String("Apple"); // 'new' දැම්මොත් අනිවාර්යයෙන්ම Heap එකේ අලුත් Object එකක් හැදෙනවා.
System.out.println(s1 == s2); // True (දෙන්නම එකම Object එක පෙන්නන නිසා)
System.out.println(s1 == s3); // False (s3 කියන්නේ සම්පූර්ණයෙන්ම අලුත් කෙනෙක්)
🤔 Pass-by-Value ද? Pass-by-Reference ද?
ගොඩක් අය හිතන්නේ Java වල Objects යවද්දී Pass-by-Reference වෙනවා කියලා. නැහැ! Java කියන්නේ 100% ක්ම Pass-by-Value භාෂාවක්. අපි Method එකකට Object එකක් යවද්දී, ඇත්තටම යවන්නේ අර Object එක නෙවෙයි, Object එක පෙන්නන රිමෝට් එකේ (Reference එකේ) කොපියක් විතරයි. ඒ කොපියෙන් අර TV එකේ චැනල් මාරු කරන්න (Object එක වෙනස් කරන්න) පුළුවන් වුණාට, අලුත් TV එකක් ගෙනත් තියන්න (Reassign කරන්න) බෑ.
2. Constructors: ගැඹුරු හැදෑරීමක් 🏗️
කලින් කොටසේදී අපි Constructor එකක් ගැන කතා කළා. Constructor එකක් කියන්නේ Object එකක් "උපදින මොහොතේම" Run වෙන විශේෂ Method එකක්. හැබැයි මේකේ අපි කතා නොකරපු තව ලොකු රහස් ටිකක් තියෙනවා.
2.1 Default Constructor (නොපෙනෙන Constructor එක)
හිතන්න ඔයා Class එක ඇතුලේ කිසිම Constructor එකක් ලිව්වේ නෑ කියලා. එතකොට Object එකක් හැදෙන්නේ කොහොමද? Java මාර Smart. ඔයා Constructor එකක් ලිව්වේ නැත්නම්, Java Compiler එක විසින් ඉබේම හිස් Constructor එකක් (Default Constructor) එතනට දානවා.
2.2 Constructor Overloading (එකම නම, විවිධ වැඩ)
අපිට එකම Class එක ඇතුලේ Constructors කිහිපයක් හදන්න පුළුවන්. මේකට කියන්නේ Constructor Overloading කියලා. මේක ගොඩක් වැදගත් වෙන්නේ අපිට විවිධ විදියට Objects හදන්න ඕන වුනාමයි.
new Laptop() කියලා Object එකක් හදන්න ගියොත් Error එකක් එනවා (ඔයා ආයේ අතින්ම හිස් Constructor එකක් ලියනකම්).
2.3 Constructor Chaining (`this()` පාවිච්චි කිරීම)
හිතන්න අපිට Constructors 3ක් තියෙනවා කියලා. මේ තුනේම එකම කෝඩ් එක ආයේ ආයේ ලියන එක මහ වදයක් නේද? අන්න ඒකට අපිට පුළුවන් එක Constructor එකක් ඇතුලේ ඉඳන් තව Constructor එකකට කතා කරන්න (Call කරන්න). මේකට කියන්නේ Constructor Chaining කියලා. මේකට පාවිච්චි කරන්නේ this() කියන ක්රමයයි.
String brand;
int ram;
// 1. ප්රධාන Constructor එක
public Laptop(String brand, int ram) {
this.brand = brand;
this.ram = ram;
}
// 2. Brand එක විතරක් දුන්නොත්, RAM එක 8GB විදියට ඉබේම දාන්න ඕනේ
public Laptop(String brand) {
// මෙතන this() කියන්නේ අර උඩ තියෙන ප්රධාන Constructor එකට කතා කරනවා!
this(brand, 8);
}
}
3. Access Modifiers: දත්ත වල ආරක්ෂකයින් 🛡️
මෙච්චර කල් අපි හැමදේටම ඉස්සරහින් public කියලා දැම්මා නේද? හැබැයි ඇත්තම Software එකක් හදද්දි එහෙම කරන්න බෑ. බැංකු ගිණුමක (Bank Account) කෝඩ් එකක් ලියද්දි, Account Balance එක ඕනම කෙනෙකුට වෙනස් කරන්න පුළුවන් විදියට public කරලා තිබ්බොත් මොකද වෙන්නේ? පිස්සු හැදෙනවනේ!
අන්න ඒ නිසා Java වල අපේ දත්ත ආරක්ෂා කරන්න Access Modifiers ජාති 4ක් තියෙනවා. මේ ටේබල් එකෙන් ඒක පැහැදිලිව බලාගන්න පුළුවන්:
| Modifier | Same Class (එකම ක්ලාස් එක) | Same Package (එකම ෆෝල්ඩරය) | Subclass (ළමා ක්ලාස් වල) | Global (ලෝකේ ඕන තැනක) |
|---|---|---|---|---|
| public 🟢 | ✔️ Yes | ✔️ Yes | ✔️ Yes | ✔️ Yes |
| protected 🟡 | ✔️ Yes | ✔️ Yes | ✔️ Yes | ❌ No |
| default ⚪ | ✔️ Yes | ✔️ Yes | ❌ No | ❌ No |
| private 🔴 | ✔️ Yes | ❌ No | ❌ No | ❌ No |
4. Getters, Setters සහ Immutability 🚪
හරි, දැන් අපි අපේ බැංකු ගිණුමේ සල්ලි private කළා කියමුකෝ. එතකොට වෙන Class එකක ඉන්න කෙනෙකුට තමන්ගේ සල්ලි කොච්චර තියෙනවද කියලා බලාගන්නවත් විදියක් නෑනේ. අන්න ඒකට අපි විශේෂ Methods ජාතියක් පාවිච්චි කරනවා. මේකට කියන්නේ Encapsulation කියලා.
- Getters: Private දත්තයක් එළියට "කියවන්න" (Read) දෙන Method එක.
- Setters: Private දත්තයක් ආරක්ෂිතව "වෙනස් කරන්න" (Update) දෙන Method එක. මෙතනදී අපිට පුළුවන් Condition (if-else) දාලා වැරදි ඩේටා එන එක නවත්තන්න.
💎 Pro Level: Immutability (වෙනස් කළ නොහැකි Objects)
සමහර වෙලාවට අපිට ඕනේ Object එකක් හැදුවට පස්සේ, කවුරුත් ඒකේ තියෙන දේවල් වෙනස් කරන්නේ නැති වෙන්න හදන්න. (උදා: උපන්දිනය, NIC නම්බර් එක). මේකට කියන්නේ Immutable Class එකක් හදනවා කියලා. මේක කරන්නේ Setter Methods නොලියා, Getter Methods විතරක් දීලා.
private final String nicNumber; // final දැම්මම ආයේ වෙනස් කරන්නම බෑ!
public Citizen(String nic) {
this.nicNumber = nic; // Constructor එකෙන් මුලින්ම දානවා විතරයි
}
// Setter එකක් නෑ! Getter එක විතරයි. ඒ කියන්නේ මේක Read-Only Object එකක්.
public String getNicNumber() {
return this.nicNumber;
}
}
5. The `static` Keyword: හැමෝටම පොදු දේවල් 🌍
මෙන්න ගොඩක් අය පටලගන්න තැනක්. අපි හිතමු අපි Campus එකේ ළමයි ලියාපදිංචි කරන Software එකක් හදනවා. එක ළමයෙක්ට Object එක ගානේ හදනවා. හැබැයි මේ හැමෝගෙම "University Name" එක සමානයි නේද? ළමයි 1000ක් හිටියොත් අර නම 1000 පාරක් Memory (RAM) එකේ සේව් වෙනවා. ඒක මාර අපරාධයක්! අන්න ඒකට තමයි static කියන මැජික් වචනේ තියෙන්නේ.
යම් Variable එකක් හෝ Method එකක් ඉස්සරහින්
static කියලා දැම්මොත්, ඒක අයිති වෙන්නේ Object එකට නෙමෙයි, මුළු Class එකටමයි! ඒ කියන්නේ RAM එකේ ඒක සේව් වෙන්නේ එක පාරයි. ළමයි 1000ක් හිටියත්, ඒ 1000 දෙනාම ශෙයාර් (Share) කරගන්නේ අර එකම Static Variable එකයි.
🚀 5.1 Static Blocks (Main Method එකටත් කලින් දුවන කෙනා)
ඔයා දන්නවද ප්රෝග්රෑම් එකක් Run කරද්දි main method එකටත් කලින් Run වෙන දේවල් තියෙනවා කියලා? ඒවට කියන්නේ Static Blocks කියලා. Class එක මුලින්ම Memory එකට ලෝඩ් වෙද්දිම මේක Run වෙනවා.
static {
System.out.println("1. මම තමයි මුලින්ම රන් වෙන්නේ! (Static Block)");
}
public static void main(String[] args) {
System.out.println("2. ඊටපස්සේ තමයි Main Method එක වැඩ කරන්නේ.");
}
}
⚙️ 5.2 Static Methods සහ `main` Method එකේ රහස
Static Methods වලට කතා කරන්න Objects හදන්න ඕනේ නෑ. Class එකේ නමෙන්ම කතා කරන්න පුළුවන් (උදා: Math.max(10, 20)). අන්න ඒ නිසයි අපේ main method එක හැමදාම public static void main වෙන්නේ. එතකොට Java අර ප්රෝග්රෑම් එක Run කරද්දි මුලින්ම Object හද හද ඉන්න ඕනේ නෑ, කෙලින්ම Class එකෙන් main එකට කතා කරනවා!
6. `final` Keyword එකේ බලය 🛑
final කියන්නේ Java වල තියෙන තහනම් ලකුණක් වගේ එකක්. මේක පාවිච්චි කරන තැන අනුව වැඩ කරන විදිය වෙනස් වෙනවා:
- final Variables: අගය ආයේ කවදාවත් වෙනස් කරන්න බෑ. (උදා:
final double PI = 3.14159;). Constant එකක් බවට පත්වෙනවා. - final Methods: Child Classes වලට මේ Method එක වෙනස් කරන්න (Override කරන්න) බෑ.
- final Classes: මේ Class එකෙන් තවත් Child Classes හදන්න (Inherit කරන්න) බෑ. (උදා:
Stringclass එක Java වල final කරලා තියෙන්නේ).
7. Garbage Collector: Java වල කුණු අදින රථය 🚛🧹
C++ වගේ පරණ භාෂා වල කෝඩ් ලියද්දි, අපි Object එකක් හැදුවොත් අන්තිමට ඒක මකලා Memory එක (RAM එක) නිදහස් කරන්න කෝඩ් එකකුත් ලියන්න ඕනේ (Destructors). නැත්නම් Memory පිරිලා Computer එක හිරවෙනවා (Memory Leak).
හැබැයි Java වල තියෙන ලොකුම වාසිය තමයි Garbage Collector (GC). මේක ඉබේම Background එකේ දුවන පොඩි ප්රෝග්රෑම් එකක්.
🕵️♂️ GC වැඩ කරන විදිය (Mark and Sweep Algorithm)
Garbage Collector එක ඇවිත් RAM එක සුද්ද කරන්නේ කොහොමද දන්නවද? මේක පියවර දෙකකින් වෙනවා:
- Mark (ලකුණු කිරීම): මුලින්ම GC එක ඇවිත් බලනවා Heap Memory එකේ තියෙන මොන Objects වලටද Stack එකේ ඉඳන් රිමෝට් (References) තියෙන්නේ කියලා. ඒ පාවිච්චි වෙන Objects ටික ලකුණු කරගන්නවා (Mark).
- Sweep (අතුගා දැමීම): ඊට පස්සේ අර ලකුණු කරපු නැති, ඒ කියන්නේ කිසිම කෙනෙක් දැන් පාවිච්චි කරන්නේ නැති "අනාථ" Objects සේරම RAM එකෙන් මකලා (Sweep කරලා) දානවා.
SmartPhone p2 = p1; // දැන් රිමෝට් 2ක් තියෙනවා
p1 = null; // p1 කනෙක්ෂන් එක කැඩුවා. හැබැයි තවම GC එකට Object එක මකන්න බෑ, මොකද p2 අල්ලගෙන ඉන්නවා!
p2 = null; // අන්න දැන් කවුරුත් නෑ! GC එක ඇවිත් "Mark and Sweep" කරලා Object එක මකලා දානවා 🧹
Mega Project: Advanced University System 🎓💻
අද ඉගෙන ගත්ත Constructors, Constructor Chaining, Private variables, Getters/Setters, Static සහ Final keywords ඔක්කොම එකතු කරලා අපි සම්පූර්ණ ප්රොෆෙෂනල් Class එකක් ලියමු.
// 1. Static Variable (හැමෝටම පොදුයි)
public static String university = "IIT Sri Lanka";
// 2. Private & Final Variables (ආරක්ෂිතයි වගේම, ID එක ආයේ වෙනස් කරන්න බෑ)
private final String studentID;
private String studentName;
private double gpa;
// 3. ප්රධාන Constructor එක
public CampusStudent(String id, String name, double gpa) {
this.studentID = id; // final නිසා මෙතනින් විතරයි දාන්න පුළුවන්
this.studentName = name;
this.setGPA(gpa); // Setter හරහා දත්ත දානවා
}
// 4. Constructor Chaining (අලුත් ළමයෙක් ආවොත්, GPA එක 0.0 කරලා ඉබේම හදන්න)
public CampusStudent(String id, String name) {
this(id, name, 0.0); // ප්රධාන Constructor එකට කතා කරනවා
}
// 5. Getter Methods
public String getStudentID() { return this.studentID; }
public String getName() { return this.studentName; }
public double getGPA() { return this.gpa; }
// 6. Setter Method එක (GPA එක 0-4 අතර විතරයි තියෙන්න පුළුවන්)
public void setGPA(double newGPA) {
if (newGPA >= 0.0 && newGPA <= 4.0) {
this.gpa = newGPA;
} else {
System.out.println("❌ Error: GPA එක 0 ත් 4 ත් අතර වෙන්න ඕනේ!");
}
}
public void showDetails() {
System.out.println("🎓 ID: " + studentID + " | Name: " + studentName + " | GPA: " + gpa + " | Uni: " + university);
}
}
public class Main {
public static void main(String[] args) {
CampusStudent s1 = new CampusStudent("IT001", "Kaweesha", 3.8);
CampusStudent s2 = new CampusStudent("IT002", "Amal"); // Constructor Chaining වැඩ කරනවා! (GPA = 0.0)
s1.showDetails();
s2.showDetails();
// s1.studentID = "IT999"; // ❌ මේක කරන්න බෑ! final නිසා.
s1.setGPA(5.0); // ❌ Setter එකෙන් Error එකක් දෙනවා හොර කරන්න ගියාම.
}
}
private වලින් දත්ත හංගනවා. getters/setters වලින් ඒවට පාලනයක් දෙනවා. static වලින් මුළු Class එකටම පොදු දේවල් හදනවා. final වලින් වෙනස් වෙන එක නවත්තනවා. අවසානයේ Garbage Collector එක Mark & Sweep කරලා RAM එක සුද්ද කරනවා. මේක තමයි නියම Software Engineering!
ඊළඟ කොටසින්: OOP වල රහස් බලවේග 4 න් පළමුවැන්න! (Encapsulation සහ Inheritance) 🛡️🧬
දිගටම KP Tech Gear සමඟ රැඳී සිටින්න! 👇

Discussion