1. इंटरफेस सादर करत आहे
आज तुमचा दिवस ज्ञानासाठी आहे. आणखी एक नवीन आणि मनोरंजक विषय इंटरफेस आहे.
इंटरफेसची संकल्पना ही अमूर्तता आणि बहुरूपता या तत्त्वांचे मूल आहे. इंटरफेस अमूर्त वर्गासारखाच असतो, ज्यामध्ये सर्व पद्धती अमूर्त असतात. हे वर्गाप्रमाणेच घोषित केले आहे, परंतु आम्ही कीवर्ड वापरतो interface
.
interface Feline
{
void purr();
void meow();
void growl();
}
इंटरफेसबद्दल काही उपयुक्त तथ्ये येथे आहेत:
1. इंटरफेस घोषित करणे
interface Drawable
{
void draw();
}
interface HasValue
{
int getValue();
}
- कीवर्ड ऐवजी
class
, आम्ही लिहितोinterface
. - यात फक्त अमूर्त पद्धती आहेत (कीवर्ड लिहू नका
abstract
) - खरं तर, इंटरफेसमध्ये सर्व
public
पद्धती आहेत
इंटरफेस केवळ इंटरफेसचा वारसा घेऊ शकतो. परंतु इंटरफेसमध्ये अनेक पालक असू शकतात. हे सांगण्याचा दुसरा मार्ग म्हणजे जावामध्ये इंटरफेसचा एकापेक्षा जास्त वारसा आहे. उदाहरणे:
interface Piece extends Drawable, HasValue
{
int getX();
int getY();
}
3. इंटरफेसमधून वर्ग इनहेरिट करणे
एक वर्ग एकाधिक इंटरफेस वारसा मिळवू शकतो (फक्त एका वर्गाकडून). हे implements
कीवर्ड वापरून केले जाते. उदाहरण:
abstract class ChessItem implements Drawable, HasValue
{
private int x, y, value;
public int getValue()
{
return value;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
ChessItem वर्गाला अमूर्त घोषित केले आहे: ते शिवाय वारशाने मिळालेल्या सर्व पद्धती लागू करते draw
. दुसऱ्या शब्दांत, ChessItem
वर्गात एक अमूर्त पद्धत आहे — draw()
.
extends
आणि कीवर्डचा तांत्रिक अर्थ implements
एकच आहे: दोन्ही वारसा आहेत. कोडची वाचनीयता सुधारण्यासाठी हा फरक करण्यात आला. आम्ही असेही म्हणतो की वर्ग वारशाने मिळाले आहेत (मार्गे extends
) आणि इंटरफेस लागू केले जातात (मार्गे implements
)
4. चल
येथे सर्वात महत्वाची गोष्ट आहे: सामान्य व्हेरिएबल्स इंटरफेसमध्ये घोषित केले जाऊ शकत नाहीत (जरी स्टॅटिक असू शकतात).
पण आम्हाला इंटरफेसची गरज का आहे? ते कधी वापरले जातात? वर्गांपेक्षा इंटरफेसचे दोन मजबूत फायदे आहेत:
2. त्यांच्या अंमलबजावणीपासून "पद्धतींचे वर्णन" वेगळे करणे.
पूर्वी, आम्ही असे म्हटले होते की जर तुम्हाला तुमच्या वर्गाच्या पद्धती इतर वर्गांमधून कॉल करण्याची परवानगी द्यायची असेल, तर तुमच्या पद्धतींना कीवर्डने चिन्हांकित करणे आवश्यक आहे public
. जर तुम्हाला त्यापैकी काही पद्धती फक्त तुमच्या वर्गातून कॉल करायच्या असतील तर तुम्हाला त्यांना कीवर्डने चिन्हांकित करणे आवश्यक आहे private
. दुसऱ्या शब्दांत, आम्ही वर्गाच्या पद्धतींना दोन श्रेणींमध्ये विभागतो: "प्रत्येकासाठी वापरण्यासाठी" आणि "केवळ आमच्या स्वत: च्या वापरासाठी".
इंटरफेस या विभागाला आणखी मजबूत करण्यात मदत करतात. आम्ही एक विशेष "प्रत्येकासाठी वापरण्यासाठी वर्ग" तसेच द्वितीय श्रेणी "केवळ आमच्या स्वतःच्या वापरासाठी" बनवू, जो प्रथम श्रेणीचा वारसा घेईल. हे अंदाजे कसे दिसेल ते येथे आहे:
आधी | नंतर |
---|---|
|
|
|
|
आम्ही आमचा वर्ग दोन भागात विभाजित करतो: एक इंटरफेस आणि एक वर्ग जो इंटरफेसचा वारसा घेतो . आणि येथे फायदा काय आहे?
अनेक भिन्न वर्ग समान इंटरफेस लागू (वारसा) करू शकतात. आणि प्रत्येकाची स्वतःची वागणूक असू शकते. उदाहरणार्थ, ArrayList
LinkedList
इंटरफेसची दोन भिन्न अंमलबजावणी आहेत List
.
अशा प्रकारे, आम्ही केवळ विविध अंमलबजावणीच नाही तर अंमलबजावणी करणारा वर्ग देखील लपवतो (कारण आम्हाला फक्त कोडमधील इंटरफेसची आवश्यकता आहे). हे आम्हाला खूप लवचिक बनू देते: प्रोग्राम चालू असताना, आम्ही एका ऑब्जेक्टला दुसर्या ऑब्जेक्टने बदलू शकतो, ऑब्जेक्टचा वापर करणाऱ्या सर्व वर्गांना प्रभावित न करता त्याचे वर्तन बदलू शकतो.
पॉलीमॉर्फिझमसह एकत्रित केल्यावर हे एक अतिशय शक्तिशाली तंत्र आहे. तूर्तास, आपण हे का करावे हे स्पष्ट नाही. इंटरफेस शिवाय तुमचे जीवन खूप सोपे बनवू शकतात हे समजून घेण्यासाठी तुम्हाला प्रथम डझनभर किंवा शेकडो वर्गांसह प्रोग्राम्सचा सामना करावा लागेल.
3. एकाधिक वारसा
Java मध्ये, सर्व वर्गांमध्ये फक्त एक पालक वर्ग असू शकतो. इतर प्रोग्रामिंग भाषांमध्ये, वर्गांमध्ये अनेकदा अनेक पालक वर्ग असू शकतात. हे खूप सोयीचे आहे, परंतु अनेक समस्या देखील आणते.
जावाचे निर्माते एक तडजोडीवर पोहोचले: त्यांनी वर्गांचे एकाधिक वारसा निषिद्ध केले, परंतु इंटरफेसच्या एकाधिक वारसास परवानगी दिली. इंटरफेसमध्ये एकाधिक पालक इंटरफेस असू शकतात. वर्गामध्ये अनेक पालक इंटरफेस असू शकतात परंतु फक्त एक पालक वर्ग.
त्यांनी वर्गांच्या एकाधिक वारशावर बंदी का घातली परंतु इंटरफेसच्या एकाधिक वारसास परवानगी का दिली? तथाकथित डायमंड वारसा समस्येमुळे:

जेव्हा ब वर्गाला अ वर्गाचा वारसा मिळतो तेव्हा त्याला क आणि ड वर्गाबद्दल काहीही माहिती नसते. त्यामुळे ते A वर्गाचे व्हेरिएबल्स योग्य वाटेल तसे वापरते. C वर्ग तेच करतो: ते A वर्गाचे व्हेरिएबल्स वापरते, परंतु वेगळ्या प्रकारे. आणि या सगळ्याचा परिणाम ड वर्गात संघर्षात होतो.
खालील साधे उदाहरण पाहू. समजा आमच्याकडे 3 वर्ग आहेत:
class Data
{
protected int value;
}
class XCoordinate extends Data
{
public void setX (int x) { value = x;}
public int getX () { return value;}
}
class YCoordinate extends Data
{
public void setY (int y) { value = y;}
public int getY () { return value; }
}
डेटा क्लास value
व्हेरिएबल साठवतो. त्याचा XCoordinate वंशज वर्ग मूल्य संचयित करण्यासाठी ते व्हेरिएबल वापरतो x
आणि YCoordinate
वंशज वर्ग मूल्य संचयित करण्यासाठी वापरतो y
.
आणि ते कार्य करते. स्वतंत्रपणे. परंतु जर आपल्याला XYCoordinates वर्गाने XCoordinate
आणि YCoordinate
वर्ग दोन्ही वारसा मिळावे असे वाटत असेल तर आपल्याला तुटलेला कोड मिळेल. या वर्गात त्याच्या पूर्वज वर्गाच्या पद्धती असतील, परंतु त्या योग्यरित्या कार्य करणार नाहीत, कारण त्यांच्याकडे समान आहे value variable
.
परंतु इंटरफेसमध्ये व्हेरिएबल्स नसल्यामुळे त्यांच्यात अशा प्रकारचा संघर्ष होऊ शकत नाही. त्यानुसार, इंटरफेसचे एकाधिक वारसा अनुमत आहे.
GO TO FULL VERSION