-
Интерфейс тек мінез-құлықты сипаттайды. Оның байлығы жоқ. Бірақ абстрактілі класстың күйі бар: ол екеуін де сипаттайды.
Bird
Мысал ретінде дерексіз класс пен интерфейсті алайықFlyable
: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, birdie!"); } public static void main(String[] args) { Mockingjay someBird = new Mockingjay(); someBird.setAge(19); System.out.println(someBird.getAge()); } }
Көріп отырғаныңыздай, біз абстрактілі класстың күйіне – оның айнымалыларына
species
(түріне) жәнеage
(жасына) оңай қол жеткізе аламыз.Бірақ интерфейспен де солай істеуге тырыссақ, сурет басқаша болады. Оған айнымалы мәндерді қосуға болады:
public interface Flyable { String species = new String(); int age = 10; public void fly(); } public interface Flyable { private String species = new String(); // error private int age = 10; // also an error public void fly(); }
Біз тіпті интерфейс ішінде жеке айнымалы мәндерді жасай алмаймыз . Неліктен? Жеке модификатор пайдаланушыдан іске асыруды жасыру үшін жасалғандықтан . Бірақ интерфейс ішінде ешқандай іске асыру жоқ: онда жасыратын ештеңе жоқ.
Интерфейс тек әрекетті сипаттайды. Тиісінше, интерфейс ішінде гетерлер мен орнатушыларды іске асыра алмаймыз. Бұл интерфейстің табиғаты: ол күйге емес, мінез-құлыққа қатысты.
Java8 іске асырылуы бар әдепкі интерфейс әдістерін ұсынды. Сіз олар туралы бұрыннан білесіз, сондықтан біз оларды қайталамаймыз.
-
Абстрактілі класс өте тығыз байланысы бар сыныптарды байланыстырады және біріктіреді. Сонымен қатар, бірдей интерфейсті мүлдем ортақ ештеңе жоқ сыныптар жүзеге асыра алады.
Құстар туралы мысалға оралайық.
Bird
Оның негізінде құстарды жасау үшін біздің реферат сыныбымыз қажет. Тек құстар және басқа ешкім емес! Әрине, олар әртүрлі болады.Интерфейспен
Flyable
бәрі басқаша. Ол тек өз атына сәйкес мінез-құлықты сипаттайды - «ұшу». «Ұшатын», «ұшуға қабілетті» анықтамасы бір-бірімен байланысы жоқ көптеген an objectілерді қамтиды.Бұл 4 нысан бір-бірімен ешқандай байланысы жоқ. Не айтамын, олардың бәрі де жанды емес. Дегенмен, олардың барлығы
Flyable
ұшуға қабілетті.Біз оларды дерексіз класс арқылы сипаттай алмас едік. Олардың жалпы күйі немесе бірдей өрістері жоқ. Әуе кемесін сипаттау үшін бізге «модель», «шығару жылы» және «жолаушылар санының максималды саны» өрістері қажет болуы мүмкін. Карлсон үшін бүгін ол жеген барлық тәттілерге арналған өрістер және оның Баламен ойнайтын ойындарының тізімі бар. Москит үшін... у-у... біз тіпті білмейміз... Мүмкін «тітіркену деңгейі»? :)
Ең бастысы, біз оларды дерексіз класс арқылы сипаттай алмаймыз. Олар тым әртүрлі. Бірақ жалпы мінез-құлық бар: олар ұша алады. Интерфейс әлемдегі ұшуға, жүзуге, секіруге немесе басқа мінез-құлыққа ие болатын барлық нәрсені сипаттауға өте ыңғайлы.
-
Кластар қалағанша көптеген интерфейстерді жүзеге асыра алады, бірақ олар тек бір сыныптан мұраға алады.
Біз бұл туралы бірнеше рет айтқанбыз. Java-да бірнеше мұра жоқ, бірақ бірнеше іске асыру бар. Бұл тармақ алдыңғысынан ішінара туындайды: интерфейс көбінесе ортақ ештеңесі жоқ көптеген әртүрлі класстарды байланыстырады және бір-біріне өте жақын класстар тобы үшін абстрактілі класс жасалады. Сондықтан, сіз тек бір сыныптан мұраға алатыныңыз қисынды. Абстрактілі класс «бұл» қатынасты сипаттайды.
Стандартты InputStream & OutputStream интерфейстері
Біз қазірдің өзінде ағынды енгізу мен шығаруға жауапты әртүрлі сыныптардан өттік.InputStream
және қарайық OutputStream
. Жалпы, бұл интерфейстер емес, нақты дерексіз класстар. Енді сіз олардың не екенін білесіз, сондықтан олармен жұмыс істеу әлдеқайда жеңіл болады :) InputStream
- бұл byte енгізуге жауапты дерексіз класс. Java-да мұраға қалдырылатын сыныптар қатары бар InputStream
. Олардың әрқайсысы әртүрлі көздерден деректерді алу үшін конфигурацияланған. Ол ата-ана болғандықтан InputStream
, ол деректер ағындарымен ыңғайлы жұмыс істеудің бірнеше әдістерін ұсынады. Әр баланың мынадай әдістері бар InputStream
:
int available()
оқуға қолжетімді byte санын қайтарады;close()
кіріс көзін жабады;int read()
ағындағы келесі қол жетімді byteтың бүтін көрінісін қайтарады. Егер ағынның соңына жетсе, -1 саны қайтарылады;int read(byte[] buffer)
byteтарды буферге оқу әрекеті, оқылған byteтардың санын қайтарады. Файлдың соңына жеткенде -1 қайтарады;int read(byte[] buffer, int byteOffset, int byteCount)
byte блогының бір бөлігін оқиды. Деректер блогының толық толтырылмау мүмкіндігі болған кезде қолданылады. Файлдың соңына жеткенде -1 қайтарады;long skip(long byteCount)
өткізіп жіберуbyteCount
, енгізу byteы, еленбеген byteтардың санын қайтарады.
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 was read" + c);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
inputStream.close();
buffer.close();
}
}
}
Бұл мысалда біз компьютерде "D:/Users/UserName/someFile.txt" мекенжайында орналасқан файлдан деректерді оқимыз . Біз 2 нысанды жасаймыз - FileInputStream
және BufferedInputStream
оның «орауы» ретінде. Осыдан кейін біз файлдан byteтарды оқып, оларды таңбаларға түрлендіреміз. Файл аяқталмайынша. Көріп отырғаныңыздай, мұнда күрделі ештеңе жоқ. Сіз бұл codeты көшіріп, оны компьютеріңізде сақталған кейбір нақты файлда іске қоса аласыз :) Класс OutputStream
- byte ағынының шығысын анықтайтын дерексіз класс. Сіз түсінгеніңіздей, бұл «а» антиподы InputStream
. Ол деректерді қайдан оқуға емес, оны қайда жіберуге жауапты . Мысалы InputStream
, бұл абстрактілі класс барлық ұрпақтарды ыңғайлы жұмыс үшін әдістер тобымен қамтамасыз етеді:
int close()
шығыс ағынын жабады;void flush()
барлық шығыс буферлерін тазартады;abstract void write (int oneByte)
шығыс ағынына 1 byte жазады;void write (byte[] buffer)
шығыс ағынына byte массивін жазады;void write (byte[] buffer, int offset, int count)
позицияның ығысуынан бастап массивтен санау byteтарының ауқымын жазады.
OutputStream
:
-
DataOutputStream
. Стандартты Java деректер түрлерін жазу әдістерін қамтитын шығыс ағыны.Қарапайым Java түрлері мен жолдарын жазуға арналған өте қарапайым класс. Сіз жазбаша codeты түсіндірместен де түсінесіз:
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
Ештеңе де күрделі емес, мәні (немесе 'a) дегенмен бірдей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 will convert this string into an array of bytes and write it to a file byte[] buffer = text.getBytes(); bufferedStream.write(buffer, 0, buffer.length); bufferedStream.close(); } }
Тағы да, сіз бұл codeпен өзіңіз «ойнауға» және оның компьютердегі нақты файлдарда қалай жұмыс істейтінін тексеруге болады.
InputStream
Input /Output SystemOutputStream
» материалынан оқуға болады . О , бізде де бөлек дәріс болады, сондықтан олар туралы алғашқы танысу үшін жеткілікті ақпарат бар. Осымен болды! Сіз интерфейстер мен дерексіз сыныптар арасындағы айырмашылықтарды жақсы түсіндіңіз және кез келген сұраққа, тіпті қиын сұраққа жауап беруге дайынсыз деп үміттенеміз :) FileInputStream
FileOutputStream
BufferedInputStream
GO TO FULL VERSION