-
इंटरफेस फक्त वर्तनाचे वर्णन करतो. त्याला राज्य नाही. परंतु अमूर्त वर्गामध्ये अवस्था समाविष्ट आहे: ते दोन्हीचे वर्णन करते.
उदाहरणार्थ,
Bird
अमूर्त वर्ग आणिCanFly
इंटरफेस घ्या:public abstract class Bird { private String species; private int age; public abstract void fly(); public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
चला
MockingJay
पक्षी वर्ग तयार करू आणि त्याला वारसा बनवूBird
:public class MockingJay extends Bird { @Override public void fly() { System.out.println("Fly, bird!"); } public static void main(String[] args) { MockingJay someBird = new MockingJay(); someBird.setAge(19); System.out.println(someBird.getAge()); } }
तुम्ही बघू शकता, आम्ही अमूर्त वर्गाच्या स्थितीत सहज प्रवेश करू शकतो — त्याची
species
आणिage
चल.परंतु जर आपण इंटरफेससह तेच करण्याचा प्रयत्न केला तर चित्र वेगळे आहे. आम्ही त्यात व्हेरिएबल्स जोडण्याचा प्रयत्न करू शकतो:
public interface CanFly { String species = new String(); int age = 10; public void fly(); } public interface CanFly { private String species = new String(); // Error private int age = 10; // Another error public void fly(); }
आम्ही इंटरफेसमध्ये खाजगी व्हेरिएबल्स देखील घोषित करू शकत नाही . का? कारण वापरकर्त्यापासून अंमलबजावणी लपवण्यासाठी खाजगी सुधारक तयार केला गेला होता. आणि इंटरफेसमध्ये कोणतीही अंमलबजावणी नाही: लपवण्यासाठी काहीही नाही.
इंटरफेस फक्त वर्तनाचे वर्णन करतो. त्यानुसार, आम्ही इंटरफेसमध्ये गेटर्स आणि सेटर लागू करू शकत नाही. हे इंटरफेसचे स्वरूप आहे: ते वर्तनासह कार्य करण्यासाठी आवश्यक आहेत, राज्य नाही.
Java 8 ने अंमलबजावणी असलेल्या इंटरफेससाठी डीफॉल्ट पद्धती सादर केल्या आहेत. तुम्हाला त्यांच्याबद्दल आधीच माहिती आहे, म्हणून आम्ही स्वतःची पुनरावृत्ती करणार नाही.
-
एक अमूर्त वर्ग अतिशय जवळून संबंधित असलेल्या वर्गांना जोडतो आणि एकत्र करतो. त्याच वेळी, एकच इंटरफेस अशा वर्गांद्वारे लागू केला जाऊ शकतो ज्यात काहीही साम्य नाही.
चला पक्ष्यांच्या उदाहरणाकडे परत जाऊया.
Bird
त्या वर्गावर आधारित पक्षी तयार करण्यासाठी आपला अमूर्त वर्ग आवश्यक आहे. फक्त पक्षी आणि दुसरे काही नाही! अर्थात, विविध प्रकारचे पक्षी असतील.इंटरफेससह
CanFly
, प्रत्येकजण आपापल्या मार्गाने पुढे जातो. हे फक्त त्याच्या नावाशी संबंधित वर्तन (उडणारे) वर्णन करते. अनेक असंबंधित गोष्टी 'उडता येतात'.या 4 संस्था एकमेकांशी संबंधित नाहीत. ते सर्व जिवंतही नाहीत. तथापि, ते सर्व
CanFly
.आम्ही अमूर्त वर्ग वापरून त्यांचे वर्णन करू शकत नाही. ते समान स्थिती किंवा समान फील्ड सामायिक करत नाहीत. विमानाची व्याख्या करण्यासाठी, आम्हाला मॉडेल, उत्पादन वर्ष आणि जास्तीत जास्त प्रवाशांसाठी फील्डची आवश्यकता असेल. कार्लसनसाठी, त्याने आज खाल्लेल्या सर्व मिठाईसाठी आणि त्याच्या लहान भावासोबत खेळलेल्या खेळांची यादी आम्हाला आवश्यक आहे. एका डासासाठी, ...उह... मला माहीतही नाही... कदाचित, 'चीडची पातळी'? :)
मुद्दा असा आहे की आम्ही त्यांचे वर्णन करण्यासाठी अमूर्त वर्ग वापरू शकत नाही. ते खूप वेगळे आहेत. परंतु त्यांच्यात सामायिक वागणूक आहे: ते उडू शकतात. एक इंटरफेस जगातील प्रत्येक गोष्टीचे वर्णन करण्यासाठी योग्य आहे जे उड्डाण करू शकतात, पोहू शकतात, उडी मारू शकतात किंवा इतर काही वर्तन प्रदर्शित करू शकतात.
-
वर्ग तुम्हाला पाहिजे तितके इंटरफेस लागू करू शकतात, परंतु ते फक्त एक वर्ग वारसा घेऊ शकतात.
आम्ही आधीच याचा एकापेक्षा जास्त वेळा उल्लेख केला आहे. Java मध्ये वर्गांचे एकाधिक वारसा नाही, परंतु ते इंटरफेसच्या एकाधिक वारसास समर्थन देते. हा मुद्दा मागील भागाच्या काही अंशी खालीलप्रमाणे आहे: इंटरफेस अनेक भिन्न वर्गांना जोडतो ज्यात सहसा इतर काहीही साम्य नसते, तर एक अमूर्त वर्ग अगदी जवळून संबंधित वर्गांच्या गटासाठी तयार केला जातो. म्हणून, याचा अर्थ असा होतो की आपण केवळ अशाच एका वर्गाचा वारसा घेऊ शकता. एक अमूर्त वर्ग 'आहे-अ' संबंधाचे वर्णन करतो.
मानक इंटरफेस: इनपुटस्ट्रीम आणि आउटपुटस्ट्रीम
आम्ही आधीच इनपुट आणि आउटपुट प्रवाहांसाठी जबाबदार असलेल्या विविध वर्गांवर गेलो आहोत. चला विचार करूयाInputStream
आणि OutputStream
. सर्वसाधारणपणे, हे अजिबात इंटरफेस नाहीत, तर संपूर्णपणे अस्सल अमूर्त वर्ग आहेत. आता तुम्हाला त्याचा अर्थ माहित आहे, त्यामुळे त्यांच्यासोबत काम करणे खूप सोपे होईल :) InputStream
बाइट इनपुटसाठी जबाबदार एक अमूर्त वर्ग आहे. Java मध्ये अनेक वर्ग आहेत जे वारसा घेतात InputStream
. त्यापैकी प्रत्येक वेगवेगळ्या स्त्रोतांकडून डेटा प्राप्त करण्यासाठी डिझाइन केलेले आहे. कारण InputStream
पालक आहे, ते अनेक पद्धती प्रदान करते ज्यामुळे डेटा प्रवाहांसह कार्य करणे सोपे होते. प्रत्येक वंशजात InputStream
या पद्धती आहेत:
int available()
वाचनासाठी उपलब्ध बाइट्सची संख्या परत करते;close()
इनपुट प्रवाह बंद करते;int read()
प्रवाहात पुढील उपलब्ध बाइटचे पूर्णांक प्रतिनिधित्व मिळवते. जर प्रवाहाचा शेवट झाला असेल, तर -1 परत केला जाईल;int read(byte[] buffer)
बफरमध्ये बाइट्स वाचण्याचा प्रयत्न करते आणि वाचलेल्या बाइट्सची संख्या परत करते. जेव्हा ते फाइलच्या शेवटी पोहोचते, तेव्हा ते -1 परत येते;int read(byte[] buffer, int byteOffset, int byteCount)
बाइट्सच्या ब्लॉकचा भाग लिहितो. जेव्हा बाइट अॅरे पूर्णपणे भरलेला नसतो तेव्हा ते वापरले जाते. जेव्हा ते फाइलच्या शेवटी पोहोचते, तेव्हा ते -1 परत येते;long skip(long byteCount)
इनपुट प्रवाहात byteCount बाइट्स वगळते आणि दुर्लक्षित केलेल्या बाइट्सची संख्या परत करते.
FileInputStream
: सर्वात सामान्य प्रकारInputStream
. याचा उपयोग फाईलमधील माहिती वाचण्यासाठी केला जातो;StringBufferInputStream
: आणखी एक उपयुक्त प्रकारInputStream
. ते स्ट्रिंगला मध्ये रूपांतरित करतेInputStream
;BufferedInputStream
: बफर केलेला इनपुट प्रवाह. हे कार्यप्रदर्शन वाढविण्यासाठी बहुतेकदा वापरले जाते.
BufferedReader
आणि सांगितले की तुम्हाला ते वापरण्याची गरज नाही? जेव्हा आम्ही लिहितो:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
…तुम्हाला वापरण्याची गरज नाही BufferedReader
: एक InputStreamReader
काम करू शकते. परंतु BufferedReader
कार्यप्रदर्शन सुधारते आणि वैयक्तिक वर्णांऐवजी डेटाच्या संपूर्ण ओळी देखील वाचू शकतात. समान गोष्ट लागू होते BufferedInputStream
! वर्ग इनपुट डिव्हाइसमध्ये सतत प्रवेश न करता एका विशेष बफरमध्ये इनपुट डेटा जमा करतो. चला एक उदाहरण विचारात घेऊया:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
public class BufferedInputExample {
public static void main(String[] args) throws Exception {
InputStream inputStream = null;
BufferedInputStream buffer = null;
try {
inputStream = new FileInputStream("D:/Users/UserName/someFile.txt");
buffer = new BufferedInputStream(inputStream);
while(buffer.available()>0) {
char c = (char)buffer.read();
System.out.println("Character read: " + c);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
inputStream.close();
buffer.close();
}
}
}
या उदाहरणात, आम्ही ' D:/Users/UserName/someFile.txt ' येथे संगणकावर असलेल्या फाइलमधील डेटा वाचतो . आम्ही 2 वस्तू तयार करतो - a FileInputStream
आणि a BufferedInputStream
जे ते 'रॅप' करतात. मग आपण फाईलमधील बाइट्स वाचतो आणि त्यांना अक्षरांमध्ये रूपांतरित करतो. आणि फाईल संपेपर्यंत आम्ही ते करतो. जसे आपण पाहू शकता, येथे काहीही क्लिष्ट नाही. तुम्ही हा कोड कॉपी करून तुमच्या कॉम्प्युटरवर रिअल फाइलवर रन करू शकता :) OutputStream
क्लास हा एक अमूर्त वर्ग आहे जो बाइट्सच्या आउटपुट प्रवाहाचे प्रतिनिधित्व करतो. आपल्याला आधीच माहित आहे की, हे एक च्या उलट आहे InputStream
. ते कुठूनतरी डेटा वाचण्यासाठी जबाबदार नाही, तर कुठेतरी डेटा पाठवण्यासाठी जबाबदार आहे . प्रमाणे InputStream
, हा अमूर्त वर्ग त्याच्या सर्व वंशजांना सोयीस्कर पद्धतींचा संच देतो:
void close()
आउटपुट प्रवाह बंद करते;void flush()
सर्व आउटपुट बफर साफ करते;abstract void write(int oneByte)
आउटपुट प्रवाहावर 1 बाइट लिहितो;void write(byte[] buffer)
आउटपुट प्रवाहावर बाइट अॅरे लिहितो;void write(byte[] buffer, int offset, int count)
ऑफसेट स्थितीपासून सुरू होणार्या अॅरेमधून काउंट बाइट्सची श्रेणी लिहितो.
OutputStream
:
-
DataOutputStream
. एक आउटपुट प्रवाह ज्यामध्ये मानक Java डेटा प्रकार लिहिण्याच्या पद्धती समाविष्ट आहेत.आदिम Java डेटा प्रकार आणि स्ट्रिंग्स लिहिण्यासाठी एक अतिशय सोपा वर्ग. स्पष्टीकरण न देता देखील तुम्हाला खालील कोड समजेल:
import java.io.*; public class DataOutputStreamExample { public static void main(String[] args) throws IOException { DataOutputStream dos = new DataOutputStream(new FileOutputStream("testFile.txt")); dos.writeUTF("SomeString"); dos.writeInt(22); dos.writeDouble(1.21323); dos.writeBoolean(true); } }
यात प्रत्येक प्रकारासाठी स्वतंत्र पद्धती आहेत —
writeDouble()
,writeLong()
,writeShort()
, आणि असेच. FileOutputStream
. हा वर्ग डिस्कवरील फाइलवर डेटा पाठवण्याची यंत्रणा कार्यान्वित करतो. तसे, आम्ही ते आधीच शेवटच्या उदाहरणात वापरले आहे. तुझ्या लक्षात आले का? आम्ही ते DataOutputStream ला पास केले, ज्याने 'रॅपर' म्हणून काम केले.BufferedOutputStream
. बफर केलेला आउटपुट प्रवाह. येथे देखील काहीही क्लिष्ट नाही. त्याचा उद्देशBufferedInputStream
(किंवाBufferedReader
) सारखा आहे. डेटाच्या नेहमीच्या अनुक्रमिक वाचनाऐवजी, ते विशेष 'संचयी' बफर वापरून डेटा लिहिते. बफर डेटा सिंकमध्ये प्रवेश करण्याच्या वेळा कमी करणे शक्य करते, ज्यामुळे कार्यक्षमता वाढते.import java.io.*; public class DataOutputStreamExample { public static void main(String[] args) throws IOException { FileOutputStream outputStream = new FileOutputStream("D:/Users/Username/someFile.txt"); BufferedOutputStream bufferedStream = new BufferedOutputStream(outputStream); String text = "I love Java!"; // We'll convert this string to a byte array and write it to a file byte[] buffer = text.getBytes(); bufferedStream.write(buffer, 0, buffer.length); } }
पुन्हा, तुम्ही हा कोड स्वतः खेळू शकता आणि ते तुमच्या काँप्युटरवरील रिअल फाइल्सवर काम करेल याची पडताळणी करू शकता.
FileInputStream
आमच्याकडे , FileOutputStream
आणि बद्दल एक वेगळा धडा असेल BuffreredInputStream
, म्हणून पहिल्या ओळखीसाठी ही पुरेशी माहिती आहे. बस एवढेच! आम्हाला आशा आहे की तुम्ही इंटरफेस आणि अमूर्त वर्गांमधील फरक समजून घ्याल आणि कोणत्याही प्रश्नाचे उत्तर देण्यास तयार आहात, अगदी युक्ती प्रश्न :)
GO TO FULL VERSION