Saturday, September 24, 2011

ஜாவா இடைமுகம், மறுபயனீடு , பல்முக வாரிசுப்படுத்தல். (Java interface, re-usability, Multiple Inheritance)

ஜாவா என்னும் பொருள் நோக்கு நிரலாக்க மொழி (Object Orientation Language) சற்று இலகுபடுத்தபட்ட வாரிசுப்படுத்தளுடன் (Inheritance) அறிமுகமானது. நிரலாக்கத்தில், வாரிசுப்படுத்துவது மறுபயனீடு பெறுவதற்கே. இந்த பதிவில், வாரிசுப்படுத்துவதன் மூலம் கிடைக்க கூடிய  மறுபயனீடு  வடிவங்களையும், ஜாவாவில் கிடைக்கும் அல்லது இழந்துவிட்ட மறுபயனீடு  வடிவங்களையும் உதாரணங்களுடன் ஆராயப்போகிறேன்.

முதலில் வாரிசுப்படுத்தலை பார்ப்போம். ஒரு பொருளை எடுத்துக்கொண்டால், அவை பண்புக்கூறுகளையும்,  சுயசெயற்பாடுகளையும் கொண்டிருக்கும். கணனியில் நிரலாக்கங்கள் இயங்கும் போது, இப்பொருட்களின் பண்புநிலைகள் மாறிக்கொண்டிருக்கும். சுயசெயட்பாடுகளை தூண்டுவதன் மூலம் அவற்றின் பண்புகளை மாற்றிக்கொள்ளவும் அல்லது அறிந்துகொள்ளவும் முடியும். இதற்காக, பொருள் நோக்கு நிரலாக்கத்தில் வகுப்புகளை உருவாக்கிகொள்வோம், அவை பண்பு மாறிகளையும், சுயசெயலிகளையும் கொண்டிருக்கும். வகுப்புகளை உருவாக்கும் போது, புதிய வகுப்பு ஒன்று ஏற்கனவே அமைத்த ஒரு வகுப்பின் இயல்புகளையும் தன் சொந்த இயல்புகளையும் கொண்டிருந்தால் அதை மரபியல்பு என்போம். இவ்வேளைகளில், புதிய வகுப்பு உருவாக்கும் போது, ஏற்கனவே அமைத்துகொண்ட இயல்புகளையும் அதுசார்ந்த செயலிகளையும் மீள அமைத்து கொள்ளாது, புதிய வகுப்பை முன்னதன் வாரிசாக அமைத்துகொள்வோம், இதனையே வாரிசுப்படுத்தல் என்கிறோம்.

உதாரணத்துக்கு, கோளம் மற்றும் பந்து ஆகிய வகுப்புகளை எடுத்துக்கொள்வோம். கோளங்கள் குறிப்பிட்ட ஆரையை கொண்டிருக்கும். பந்துகள் குறிப்பிட்ட ஆரையையும், மொத்தல் சுட்டியையும் கொண்டிருக்கும். எனவே, கோளங்களை மேல்நிலை வகுப்பாக அமைத்து, பந்தை அதன் வாரிசு வகுப்பாகவும் அமைத்துக்கொள்வோம். கீழ்வரும் படத்தையும் நிரலாக்கத்தையும் பார்ப்போம்.

class Sphere{ // கோளம் வகுப்பு 
private float radius; // ஆரை பண்பு 
public float getRadius(){ // ஆரை அறியும் செயலி 
return radius;
}
public void setRadius(float radius){// ஆரை மாற்றும் செயலி 
this.radius = radius;
}
}

class Ball extends Sphere{// பந்து வகுப்பு 
private float collisionIndex; // மொத்தல் சுட்டி பண்பு 
public getCollisionIndex(){ // மொத்தல் சுட்டி அறியும் செயலி 
return collisionIndex;
}
public void setCollisionIndex(float collisionIndex){ // மொத்தல் சுட்டி மாற்றும் செயலி 
this.collisionIndex = collisionIndex;
}
}

இங்கே பந்து வகுப்பு அமைக்கும் போது ஆரை பண்பையோ அல்லது அது சார்ந்த செயலிகளையோ மீள அமைத்துக்கொள்ளவில்லை. ஆனால் பந்து வகுப்பு கோளம் வகுப்பின் வாரிசு என்பதால், தானாகவே அவை அமைந்துவிடும். அதுதான் வாரிசுப்படுதல் என்கிறோம். கீழுள்ள நிரலாக்கம் இதை உணர்த்தும்.

Ball ball = new Ball(); // பந்து ஒன்று உருவாக்கப்படும் 
ball.setRadius(10.0f); // ஆரை மாற்றுப்படும் 
ball.setCollisionIndex(0.80f); // மொத்தல் சுட்டி மாற்றுபடும்

இதை மரபியல்பு மறுபயனீடு என்கிறோம்.

இன்னொரு வகை மறுபயனீடு உள்ளது, அதற்கு கீழ்வரும் பெட்டி வகுப்பை பார்ப்போம். இந்த வகுப்பில் ஒரு செயலி அமைக்கப்பட்டுள்ளது, அதைக்கொண்டு இந்த பெட்டிக்குள் குறிப்பிட்ட எத்தனை கோளங்களை வைக்கலாம் என்று கணிக்கலாம்.

class Box{ // பெட்டி வகுப்பு 
private float width; // பெட்டியின் அகலம் பண்பு 
private float length; // பெட்டியின் நீளம் பண்பு 
private float height; // பெட்டியின் உயரம் பண்பு
/**
இந்த பெட்டிக்குள் வைக்ககூடிய கோளங்களின் எண்ணிக்கையை தரும்.
**/
public int numberOfSphere(Sphere sphere){// செயலி 
int diameter = sphere.getRadius();
return (int)width/diameter*(int)length/diameter*(int)height/diameter;
}
}

இப்போது கீழ்காணும் நிரலாக்கத்தைப்பார்ப்போம். இதன்மூலம் இந்த செயலியின் பயன்பாடு புரியும்.

Box box = new Box(); // ஒரு பெட்டி உருவாக்கப்படும் 
... // பெட்டியின் நீளம், அகலம், உயரம் மாற்றி கொள்ளவும்  
Sphere sphere = new Sphere(); // ஒரு கோளம் உருவாக்கப்படும் 
...// கோளத்தின் ஆரையை மாற்றி கொள்ளவும் 
int numberOfSphere = box.numberOfSphere(sphere); // கோளங்களின் எண்ணிக்கை கிடைக்கும்.

இது மட்டும் இல்லை, இந்த செயலியை பாவித்து அதே பெட்டியினுள் வைக்க கூடிய பந்துகளின் எண்ணிக்கையையும் அறிந்து கொள்ளலாம். ஏனென்றால், பந்து கோளத்தின் வாரிசு.

Ball ball = new Ball(); // ஒரு பந்து உருவாக்க படும் 
...// பந்தின் ஆரையை மாற்றி கொள்ளவும் 
int numberOfBalls = box.numberOfSphere(ball); // பந்துகளின் எண்ணிக்கை கிடைக்கும்.

இதுதான் அடுத்த மறுபயனீடு வடிவம், மேல் நிலை வகுப்பிற்காக அமைக்கப்பட்ட செயலியை  அவற்றின் வாரிசு வகுப்புகளுக்கும் பயன்படுத்தலாம். இதனை பல்லுறுத்தோற்ற (Polymorphism) மறுபயனீடு என்கிறோம். அதாவது, இயக்கநிலையில் இந்த செயலிக்கு அதன் கோளம் சுட்டளவு பலவகை பொருட்களாக அமையும் அல்லது தோன்றும். இதுவே அதிகப்படியான பயன்பாடு உடைய மறுபயனீடு. கோளங்களை பயன்படுத்துவதன் மூலம் தூண்டகூடிய அதிக செயலிகளை அமைத்திருப்போம். அவை அனைத்தையும் இப்போது பந்துகளுக்கும் பாவிக்கமுடியும் அல்லது கோளத்தின் அனைத்து வாரிசுகளுக்கும் பாவிக்கமுடியும்.

இனி பல்முக வாரிசுப்படுத்தலை பார்ப்போம். இதற்கு, கூடுதலாக, பழங்களை உதாரணமாக எடுப்போம். பழம் வகுப்பு ஒன்றையும், குளிரூட்டி வகுப்பு ஒன்றையும் ஏற்கனவே அமைத்துவிட்டோம் என எடுத்துகொள்வோம். குளிரூட்டி வகுப்பில் ஒரு செயலி ஒன்றையும் அமைத்திருக்கிறோம், அதனை பயன்படுத்தி, குறிப்பிட்ட பழம் எத்தனை நாட்கள் அக் குளிரூட்டியில் வைக்ககாம் என்று அறியலாம். 

class Fruit{...} // பழம் வகுப்பு 

class Refrigerator{ // குளிரூட்டி வகுப்பு 
public int numberOfDays(Fruit fruit){...} // செயலி 
}

Fruit fruit = new Fruit(); // பழம் ஒன்று உருவாக்கப்படும் 
...// பழத்தின் பண்புகளை மாற்றி கொள்ளவும் 
Refrigerator refrigerator = new Refrigerator(); // குளிரூட்டி ஒன்று உருவாக்கப்படும் 
..//குரிரூட்டியின் பண்புகளை மாற்றி கொள்ளவும் 
int numberOfDays = refrigerator.numberOfDays(fruit); // நாட்களின் எண்ணிக்கை கிடைக்கும்.

இப்போது தோடம்பழம் வகுப்பு ஒன்றை உருவாக்க வேண்டும் என எடுத்துகொள்வோம். இயற்கையில் தோடை ஒரு பழம், அத்துடன் அது கொளவடிவானது. ஆகவே இதனை பழம் வகுப்பின் வாரிசாகவும், கோளம் வகுப்பின் வாரிசாகவும் அமைத்துக்கொள்ளலாம். இதனால் பழங்களின் பண்புக்கூறும் அவைசார் செயலிகளும், கோளத்தின் பண்புக்கூறும் அவைசார் செயலிகளும் தோடைக்கு கிடைத்துவிடும். அதுமட்டுமில்லை, பெட்டியில் உள்ளது போன்ற மற்றும் குளிரூட்டியில் உள்ளது போன்ற பழம் அல்லது கோளத்தை உள்வாங்கும் செயலிகளையும் பாவிக்கமுடியும். அதாவது, எத்தனை நாட்கள் வைக்கலாம்? என்றும் எத்தனை பழம் வைக்கலாம்? என்றும் அறிந்து கொண்டுவிடலாம். 


இங்கே ஒன்றுக்கு மேற்பட்ட மேல்நிலை வகுப்புகளில் இருந்து ஒரு வாரிசு வகுப்பு உருவாக்க படுகிறது, இது பல்முக வாரிசுப்படுத்தல் ஆகும். ஆனால் இம்முறை ஜாவாவின் வகுப்புகளுக்கு செய்துவிட முடியாது. அதற்கு முற்பட்ட காலத்தில் இருந்த சீ++ போன்ற மொழிகளில் இருந்தது. இதற்காக, ஜாவாவில் இடைமுகங்களை அறிமுகப்படுத்தினர்.

இடைமுகங்கள் என்பது, செயலிகளின் அடையாள குறியீடுகளை மட்டுமே கொண்டிருக்கும். அதாவது, செயலிகளின் உடலை அமைத்துக்கொள்ள வேண்டியதில்லை. ஆனால், வகுப்பு ஒன்றிக்கு இடைமுகம் ஒன்றை அமைத்துகொள்ளும் போது, அவ் இடைமுகத்தில் உறுதிபடுத்தப்பட்ட செயலிகளை அமைத்துக்கொள்ளவேண்டும். அத்துடன்,
1 . வகுப்பு ஒன்றுக்கு, ஒன்றுக்குமேற்பட்ட இடைமுகங்களை அமைத்துக்கொள்ளலாம்.
2 .இடைமுகங்களை, வேறு ஒரு இடைமுகத்திலிருந்தோ அல்லது ஒன்றுக்கு மேற்பட்ட இடைமுகங்களிலிருந்தோ வாரிசுப்படுத்திக்கொள்ளலாம்.
3 .இடைமுகத்தின் சுட்டுக்குறி ஒன்றால், அவ் இடைமுகத்தை அமைத்துக்கொண்ட வகுப்பின் பொருள் அனைத்தையும் சுட்டிக்கொள்ளலாம்.

இப்போது, இந்த இடைமுகங்களின் அறிமுகத்துடன் கோளம், பெட்டி ஆகிய வகுப்புகளை மேம்படுத்திக்கொள்வோம்.

கோளம் இடைமுகம் ஒன்றை அமைப்போம்.

interface ISphere{ // கோளம் இடைமுகம் 
float getRadius(); // ஆரை அறிவிக்கும் செயலியின் வரையறை 
}

பெட்டி வகுப்பின் செயலியை இப்போது கீழ்க்கண்டவாறு மாற்றி அமைத்து கொள்ளலாம். முன்பு  செயலியின் சுட்டளவாக கோளம் வகுப்பு இருந்தது, இப்போது அதை கோளம் இடைமுகமாக மாற்றி அமைப்போம்.

public int numberOfSphere(ISphere sphere){ // செயலின் சுட்டளவு கோளம் இடைமுகம் 
        // கோளம் இடைமுகம் சுட்டளவைகொண்டு ஆரை அறிந்து கொள்ளலாம் 
int diameter = sphere.getRadius();
return (int)width/diameter*(int)length/diameter*(int) height/diameter;
}

சரி, இப்போது இந்த செயலியை கொளங்களுக்கோ அல்லது அவற்றின் வாரிசுகளுக்கோ பாவித்துகொள்வதற்கு கோளம் வகுப்பை கீழுள்ளவாறு மாற்றியமைக்க வேண்டும்.

class Sphere implements ISphere{ // கோளம் வகுப்பு , கோளம் இடைமுகத்தை அமைத்து கொள்கிறது.
.......

/**
இடைமுகத்தில் உறுதிப்படுத்தபட்ட செயலி அமைக்கப்பட்டுள்ளது.
**/


public float getRadius(){
return radius;
}
........

}

இப்பொழுது, ஒரு பெட்டியினுள் வைக்ககூடிய கோளங்களின், பந்துகளின் எண்ணிக்கையை முன்பு செய்ததுபோலவே அறிந்துகொள்ளலாம். அவ் நிரலாக்கத்தில் எந்த மாற்றமும் இல்லை.

int numberOfSphere = box.numberOfSphere(sphere); // கோளங்களின் எண்ணிக்கை கிடைக்கும்.
int numberOfBalls = box.numberOfSphere(ball); // பந்துகளின் எண்ணிக்கை கிடைக்கும்.

இயக்கநிலையில், பெட்டியின் செயலி கோளம் இடைமுகத்தில் வரையறை செய்யப்பட்ட செயலிகளின் ஊடாக கோளத்தின் ஆரையை அறிந்துகொள்கிறது, அதாவது, இடைமுகங்கள் இயக்கநிலையில் பொருளுக்கும் செயலிக்கும் ஒரு இடைமுகமாக தொழில்படுகிறது.

இப்போது, தோடை வகுப்பை பார்ப்போம், பெட்டி ஒன்றினுள் வைக்ககூடிய தோடை பழங்களின் எண்ணிக்கையை அறிவதுக்கு தோடை வகுப்புக்கு கோளம் இடைமுகத்தை அமைத்து கொள்ளவேண்டும், அத்துடன் ஆரை பண்புகூறை அறியும் செயலியை அமைக்கவேண்டும். அதாவது, ஆரை பண்புகூறு, அது சார்ந்த செயலிகளை அமைத்துக்கொள்ளவேண்டும்.


class Orange extends Fruit implements ISphere{
private float radius;
public float getRadius(){
return radius;
}
public void setRadius(float radius){
this.radius = radius;
}
}


தோடை ஒரு கோள வடிவான பழம், இது பல்முக வாரிசுப்படுத்தல், ஜாவாவில் இது வகுப்புகளில் செய்துவிட முடியாது. ஆனால் இடைமுங்களின் உதவியுடன் அடைந்துவிட முனைகிறோம். எனவே, தோடையை பழத்தின் வாரிசாக அமைத்து கோளம் இடைமுகத்தை அமைத்திருக்கிறோம். அதனால் ஆரை பண்புகூறு சார்ந்தவற்றை மீள அமைக்கவேண்டி இருந்தது. அதாவது, மரபியல்பு மறுபயனீடு கிடைக்கவில்லை. ஆனால் இப்போதும் கீழ் காண்பதுபோல் பெட்டி வகுப்பின் செயலியை தோடைப்பழங்களுக்கும் பாவிக்கலாம்.


Orange orange = new Orange(); // தோடை ஒன்று உருவாக்கப்படும் 
...//தோடையின் பண்புகளை மாற்றி கொள்ளவும் 
int numberOfOranges = box.numberOfSphere(orange); // தோடைகளின் எண்ணிக்கை கிடைக்கும் 


அதாவது, பல்லுறுத்தோற்ற மறுபயனீடு இப்போதும் சாத்தியமாகும். முன்பு சொன்னதுபோல் இந்த மறுபயனீடுதான் அதிக பயனுள்ளது. எம்மால் அமைத்துகொள்ளப்படும் வகுப்புகளின் செயலிகளுக்கு மட்டும் அல்லாது, மூன்றாம் நபர்கள் அமைத்துக்கொள்ளும் வகுப்புகளின் செயலிகளையும் எமது வகுப்புகளுக்கு பயன்படுத்தி கொள்ளலாம். மரபியல்பு மறுபயனீடு கிடைக்கவில்லை எனின் அதனை அமைத்துகொள்வது கடினம் இல்லை, ஏனெனில் அது எமது புதிய வகுப்பு சார்ந்தது. அவ் வகுப்பை பற்றி முழுமையாக ஆராய்ந்தால் அமைத்துக்கொள்வது சுலபம். அதாவது தோடை வகுப்பில் ஆரை சார்ந்த அமைப்புகள் சுலபமானது. ஆனால், பெட்டி வகுப்பு அல்லது அதுபோன்ற எத்தனையோ வகுப்புகளை மீள அமைப்பது என்பது கடினம்.


தோடையை கோளத்தின் வாரிசாக மட்டும் அமைத்துவிட்டிருக்கலாமே என்று தோன்றுகிறதா? அடுத்த நிரலாக்கவரியை பாருங்கள். அவ்வாறு செய்தால் இது சாத்தியமாகாது.


int numberOfDays = refrigerator.numberOfDays(orange);
// தோடை வைக்க கூடிய நாட்களின் எண்ணிக்கை கிடைக்கும்.


அதாவது பழங்களை பாவித்து அமைக்கபட்ட செயலிகளையும் நாம் மறுபயனீடு செய்யவேண்டும்  அல்லவா? அப்படியானால் தோடையை பழத்தின் வாரிசாக அமைத்தே ஆகவேண்டும்.


அதுமட்டும் இல்லை, கோளம் இடைமுகத்தை அறிமுகம் செய்ததன் மூலம் எப்படி பெட்டி வகுப்பின் மறுபயனீடு அதிகரிக்கசெய்யபட்டதோ அதே போன்று பழம் இடைமுகங்களை அறிமுகம் செய்து குளிரூட்டியின் மறுபயனீடும் அதிகரிக்க செய்வது நல்லது.


முடிவாக, ஜாவாவில் அறிமுகமான இலகுபடுத்தபட்ட வாரிசுப்படுத்தளினால் வகுப்புகளுக்கு பல்முக வாரிசுப்படுத்தல் செய்யமுடியாது, இதனால் மரபியல்பு மறுபயனீடை இழந்துவிட்டோம், எனினும் இடைமுகங்களின் உதவியுடன் மிகவும் முக்கியமான பல்லுறுத்தோற்ற மறுபயனீடை பெற்றுவிட முடியும். எனவே முடிந்த அளவு இடைமுங்களை பாவித்து அதிக மறுபயனீடு கொண்ட நிரலாக்கங்களை அமைத்துகொள்வோம்.

Wednesday, September 14, 2011

தமிழ் அழகு !

தமிழ் ஒரு அழகான மொழி என்று பலர் கூறிக் கேட்டிருக்கிறேன். என்னை கவர்ந்த சிலவற்றை இங்கே தொகுப்போம் என்று நினைக்கிறன்.

வளைக்குள் இருந்த நண்டு வலைக்குள் போனது.

மழைக்கு நல்ல குடையென மலை பிடித்த கண்ணனாம்.

கண்ணில் ஒரு வலி இருந்தால் கனவுகள் வருவதில்லை - அதேபோல் 
கண்ணில் ஒரு வழி தெரிந்தால் கனவுகள் தேவையில்லை.

அழகு! கிளி அலகு.

குழல் ஊதும் கண்ணன்
குளளில் பூ சூடினான்.

வணக்கம்

கடந்த சில வருடங்களாக ஆங்கிலத்தில் வலை பதிவுகளை எழுதிவருகிறேன். அடிப்படையில் நான் ஒரு பொறியியலாளர் என்பதால், கூடுதலாக தொழில்நுட்பம் சார்ந்த விடையங்களையும், அவ்வப்போது கவிதா என்ற பெயரில் ஓரிரண்டு தமிழ் பதிவுலும் எழுதி வந்தேன். 

எப்படியும் ஒருநாள் எம் முற்றம் மிதிப்போம்தானே!




இன்றில் இருந்து தமிழ் பதிவுகளை இங்கே எழுத தொடங்குகிறேன். கவிதைகள், கதைகள் என்று 
மட்டுமல்லாமல் தொழில்நுட்ப விடையங்களையும் எழுதபோகிறேன். 

முடிந்தால், நான் ஏற்கனவே எழுதிய ஆங்கில பதிவுகளையும் தமிழிலும் எழுத முனைகிறேன்.

உங்கள் பாடு கஷ்டம்தான்!.