CodeGym /Java Blog /Random /Ang pagkakaiba sa pagitan ng mga abstract na klase at mga...
John Squirrels
Antas
San Francisco

Ang pagkakaiba sa pagitan ng mga abstract na klase at mga interface

Nai-publish sa grupo
Hi! Sa araling ito, pag-uusapan natin kung paano naiiba ang mga abstract na klase sa mga interface at isaalang-alang ang ilang halimbawa na may mga karaniwang abstract na klase. Ang pagkakaiba sa pagitan ng mga abstract na klase at mga interface - 1Naglaan kami ng hiwalay na aralin sa mga pagkakaiba sa pagitan ng abstract na klase at interface, dahil napakahalaga ng paksang ito. Tatanungin ka tungkol sa pagkakaiba ng mga konseptong ito sa 90% ng mga panayam sa hinaharap. Nangangahulugan iyon na dapat mong tiyakin na malaman kung ano ang iyong binabasa. At kung hindi mo lubos na nauunawaan ang isang bagay, basahin ang mga karagdagang mapagkukunan. Kaya, alam natin kung ano ang abstract na klase at kung ano ang interface. Ngayon tatalakayin natin ang kanilang mga pagkakaiba.
  1. Ang isang interface ay naglalarawan lamang ng pag-uugali. Wala itong estado. Ngunit ang isang abstract na klase ay may kasamang estado: inilalarawan nito ang pareho.

    Halimbawa, kunin ang Birdabstract na klase at ang CanFlyinterface:

    
    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;
       }
    }
    

    Gumawa tayo ng MockingJayklase ng ibon at gawin itong magmana 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());
       }
    }
    

    Gaya ng nakikita mo, madali nating maa-access ang estado ng abstract class — nito speciesat agemga variable.

    Ngunit kung susubukan naming gawin ang parehong sa isang interface, ang larawan ay naiiba. Maaari naming subukang magdagdag ng mga variable dito:

    
    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();
    }
    

    Hindi man lang kami makapagdeklara ng mga pribadong variable sa loob ng isang interface. Bakit? Dahil nilikha ang pribadong modifier upang itago ang pagpapatupad mula sa user. At ang isang interface ay walang pagpapatupad sa loob nito: walang anumang bagay na itatago.

    Ang isang interface ay naglalarawan lamang ng pag-uugali. Alinsunod dito, hindi namin maipapatupad ang mga getter at setter sa loob ng isang interface. Ito ang likas na katangian ng mga interface: kailangan ang mga ito upang gumana sa pag-uugali, hindi estado.

    Ipinakilala ng Java 8 ang mga default na pamamaraan para sa mga interface na may pagpapatupad. Alam mo na ang tungkol sa kanila, kaya hindi na namin mauulit.

  2. Ang isang abstract na klase ay nag-uugnay at nagsasama ng mga klase na napakalapit na magkakaugnay. Kasabay nito, ang isang solong interface ay maaaring ipatupad ng mga klase na talagang walang pagkakatulad.

    Bumalik tayo sa ating halimbawa sa mga ibon.

    Ang aming Birdabstract na klase ay kailangan para sa paglikha ng mga ibon na batay sa klase na iyon. Mga ibon lamang at wala nang iba pa! Siyempre, magkakaroon ng iba't ibang uri ng mga ibon.

    Ang pagkakaiba sa pagitan ng mga abstract na klase at mga interface - 2

    Gamit ang CanFlyinterface, lahat ay nagpapatuloy sa kanilang sariling paraan. Inilalarawan lamang nito ang pag-uugali (paglipad) na nauugnay sa pangalan nito. Maraming hindi nauugnay na bagay ang 'maaaring lumipad'.

    Ang pagkakaiba sa pagitan ng mga abstract na klase at mga interface - 3

    Ang 4 na entity na ito ay hindi nauugnay sa isa't isa. Hindi man sila lahat ay nabubuhay. Gayunpaman, silang lahat CanFly.

    Hindi namin mailarawan ang mga ito gamit ang abstract na klase. Hindi sila nagbabahagi ng parehong estado o magkaparehong mga field. Upang tukuyin ang isang sasakyang panghimpapawid, malamang na kailangan namin ng mga field para sa modelo, taon ng produksyon, at maximum na bilang ng mga pasahero. Para kay Carlson, kakailanganin namin ng mga field para sa lahat ng matamis na kinakain niya ngayon, at isang listahan ng mga larong lalaruin niya kasama ang kanyang nakababatang kapatid. Para sa isang lamok, ...uh... Hindi ko nga alam... Siguro, 'annoyance level'? :)

    Ang punto ay hindi tayo maaaring gumamit ng abstract na klase upang ilarawan ang mga ito. Masyado silang magkaiba. Ngunit mayroon silang magkatulad na pag-uugali: maaari silang lumipad. Ang isang interface ay perpekto para sa paglalarawan ng lahat ng bagay sa mundo na maaaring lumipad, lumangoy, tumalon, o magpakita ng ilang iba pang pag-uugali.

  3. Ang mga klase ay maaaring magpatupad ng maraming interface hangga't gusto mo, ngunit maaari lamang silang magmana ng isang klase.

    Nabanggit na namin ito ng higit sa isang beses. Ang Java ay walang maraming inheritance ng mga klase, ngunit sinusuportahan nito ang maramihang inheritance ng mga interface. Ang puntong ito ay sumusunod sa bahagi mula sa naunang isa: ang isang interface ay nag-uugnay sa maraming iba't ibang mga klase na kadalasang walang ibang pagkakatulad, habang ang isang abstract na klase ay nilikha para sa isang pangkat ng mga napakalapit na nauugnay na mga klase. Samakatuwid, makatuwiran na maaari ka lamang magmana ng isang ganoong klase. Ang isang abstract na klase ay naglalarawan ng isang 'is-a' na relasyon.

Mga karaniwang interface: InputStream at OutputStream

Napuntahan na namin ang iba't ibang klase na responsable para sa input at output stream. Isaalang-alang natin InputStreamat OutputStream. Sa pangkalahatan, hindi ito mga interface, ngunit ganap na tunay na abstract na mga klase. Ngayon alam mo na kung ano ang ibig sabihin nito, kaya mas madaling magtrabaho sa kanila :) InputStreamay isang abstract na klase na responsable para sa byte input. Ang Java ay may ilang mga klase na nagmana InputStream. Ang bawat isa sa kanila ay idinisenyo upang makatanggap ng data mula sa iba't ibang mga mapagkukunan. Dahil InputStreamsiya ang magulang, nagbibigay ito ng ilang paraan na nagpapadali sa paggamit ng mga stream ng data. Ang bawat inapo ni InputStreamay may mga pamamaraang ito:
  • int available()ibinabalik ang bilang ng mga byte na magagamit para sa pagbabasa;
  • close()isinasara ang input stream;
  • int read()nagbabalik ng integer na representasyon ng susunod na available na byte sa stream. Kung ang dulo ng batis ay naabot na, -1 ay ibabalik;
  • int read(byte[] buffer)sinusubukang basahin ang mga byte sa buffer, at ibinabalik ang bilang ng mga byte na nabasa. Kapag ito ay umabot sa dulo ng file, ito ay nagbabalik -1;
  • int read(byte[] buffer, int byteOffset, int byteCount)nagsusulat ng bahagi ng isang bloke ng mga byte. Ito ay ginagamit kapag ang byte array ay maaaring hindi ganap na napunan. Kapag ito ay umabot sa dulo ng file, ito ay nagbabalik -1;
  • long skip(long byteCount)nilalaktawan ang byteCount byte sa input stream, at ibinabalik ang bilang ng mga byte na hindi pinansin.
Inirerekomenda ko na pag-aralan mo ang kumpletong listahan ng mga pamamaraan . Mayroong talagang higit sa sampung klase ng bata. Halimbawa, narito ang ilan:
  1. FileInputStream: ang pinakakaraniwang uri ng InputStream. Ito ay ginagamit upang basahin ang impormasyon mula sa isang file;
  2. StringBufferInputStream: Isa pang nakakatulong na uri ng InputStream. Kino-convert nito ang isang string sa isang InputStream;
  3. BufferedInputStream: Isang buffered input stream. Ito ay madalas na ginagamit upang mapataas ang pagganap.
Tandaan noong pumunta tayo BufferedReaderat sinabing hindi mo kailangang gamitin ito? Kapag sumulat tayo:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
…hindi mo kailangang gamitin ang BufferedReader: InputStreamReaderMagagawa ni An ang trabaho. Ngunit BufferedReaderpinapabuti ang pagganap at maaari ring basahin ang buong linya ng data sa halip na mga indibidwal na character. Ang parehong bagay ay naaangkop sa BufferedInputStream! Ang klase ay nag-iipon ng data ng input sa isang espesyal na buffer nang hindi patuloy na ina-access ang input device. Isaalang-alang natin ang isang halimbawa:

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();
       }
   }
}
Sa halimbawang ito, nagbabasa kami ng data mula sa isang file na matatagpuan sa isang computer sa ' D:/Users/UserName/someFile.txt '. Gumagawa kami ng 2 bagay — a FileInputStreamat a BufferedInputStreamna 'nagbabalot' dito. Pagkatapos ay binabasa namin ang mga byte mula sa file at i-convert ang mga ito sa mga character. At ginagawa namin iyon hanggang sa matapos ang file. Tulad ng nakikita mo, walang kumplikado dito. Maaari mong kopyahin ang code na ito at patakbuhin ito sa isang tunay na file sa iyong computer :) Ang OutputStreamklase ay isang abstract na klase na kumakatawan sa isang output stream ng mga byte. Tulad ng alam mo na, ito ay kabaligtaran ng isang InputStream. Hindi ito responsable para sa pagbabasa ng data mula sa isang lugar, ngunit sa halip para sa pagpapadala ng data sa isang lugar . Tulad ng InputStream, ang abstract class na ito ay nagbibigay sa lahat ng mga inapo nito ng isang hanay ng mga maginhawang pamamaraan:
  • void close()isinasara ang output stream;
  • void flush()nililimas ang lahat ng buffer ng output;
  • abstract void write(int oneByte)nagsusulat ng 1 byte sa output stream;
  • void write(byte[] buffer)nagsusulat ng byte array sa output stream;
  • void write(byte[] buffer, int offset, int count)nagsusulat ng isang hanay ng mga count byte mula sa isang array, simula sa offset na posisyon.
Narito ang ilan sa mga inapo ng OutputStreamklase:
  1. DataOutputStream. Isang output stream na may kasamang mga pamamaraan para sa pagsusulat ng mga karaniwang uri ng data ng Java.

    Isang napakasimpleng klase para sa pagsulat ng mga primitive na uri ng data at string ng Java. Malamang na mauunawaan mo ang sumusunod na code kahit na walang paliwanag:

    
    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);
    
       }
    }
    

    Mayroon itong magkakahiwalay na pamamaraan para sa bawat uri — writeDouble(), writeLong(), writeShort(), at iba pa.


  2. FileOutputStream. Ang klase na ito ay nagpapatupad ng mekanismo para sa pagpapadala ng data sa isang file sa disk. Sa pamamagitan ng paraan, ginamit na namin ito sa huling halimbawa. Napansin mo ba? Ipinasa namin ito sa DataOutputStream, na nagsilbing 'wrapper'.

  3. BufferedOutputStream. Isang buffered output stream. Wala ring kumplikado dito. Ang layunin nito ay kahalintulad sa BufferedInputStream(o BufferedReader). Sa halip na ang karaniwang sunud-sunod na pagbabasa ng data, nagsusulat ito ng data gamit ang isang espesyal na 'cumulative' buffer. Ginagawang posible ng buffer na bawasan ang bilang ng beses na na-access ang data sink, sa gayon ay tumataas ang pagganap.

    
    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);
         }
    }
    

    Muli, maaari mong paglaruan ang code na ito sa iyong sarili at i-verify na gagana ito sa mga totoong file sa iyong computer.

Magkakaroon tayo ng hiwalay na aralin tungkol sa FileInputStream, FileOutputStreamat BuffreredInputStream, kaya sapat na itong impormasyon para sa unang kakilala. Ayan yun! Umaasa kaming nauunawaan mo ang mga pagkakaiba sa pagitan ng mga interface at abstract na mga klase at handang sagutin ang anumang tanong, maging ang mga tanong na panlilinlang :)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION