JavaRush /จาวาบล็อก /Random-TH /ความแตกต่างระหว่างคลาสนามธรรมและอินเทอร์เฟซ

ความแตกต่างระหว่างคลาสนามธรรมและอินเทอร์เฟซ

เผยแพร่ในกลุ่ม
สวัสดี! ในการบรรยายนี้ เราจะพูดถึงว่าคลาสนามธรรมแตกต่างจากอินเทอร์เฟซอย่างไร และดูตัวอย่างที่มีคลาสนามธรรมทั่วไป ความแตกต่างระหว่างคลาสนามธรรมและอินเทอร์เฟซ - 1เราทุ่มเทการบรรยายแยกต่างหากเกี่ยวกับความแตกต่างระหว่างคลาสนามธรรมและอินเทอร์เฟซ เนื่องจากหัวข้อนี้มีความสำคัญมาก คุณจะถูกถามเกี่ยวกับความแตกต่างระหว่างแนวคิดเหล่านี้ใน 90% ของการสัมภาษณ์ในอนาคต ดังนั้นโปรดเข้าใจสิ่งที่คุณอ่าน และหากคุณไม่เข้าใจบางสิ่งอย่างถ่องแท้ โปรดอ่านแหล่งข้อมูลเพิ่มเติม ดังนั้นเราจึงรู้ว่าคลาสนามธรรมคืออะไรและอินเทอร์เฟซคืออะไร ตอนนี้เรามาดูความแตกต่างของพวกเขากันดีกว่า
  1. อินเทอร์เฟซอธิบายเฉพาะพฤติกรรมเท่านั้น เขาไม่มีโชคลาภ แต่คลาสนามธรรมนั้นมีสถานะ: มันอธิบายทั้งสองอย่าง

    ลองใช้คลาสนามธรรม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(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();
    }

    เราไม่สามารถสร้าง ตัวแปร ส่วนตัวภายในอินเทอร์เฟซได้ ทำไม เนื่องจาก ตัวแก้ไข ส่วนตัวถูกสร้างขึ้นเพื่อซ่อนการใช้งานจากผู้ใช้ แต่ไม่มีการใช้งานภายในอินเทอร์เฟซ: ไม่มีอะไรจะซ่อนอยู่ที่นั่น

    อินเทอร์เฟซอธิบายลักษณะการทำงานเท่านั้น ดังนั้นเราจะไม่สามารถใช้ getters และ setters ภายในอินเทอร์เฟซได้ นั่นคือธรรมชาติของอินเทอร์เฟซ: มีไว้เพื่อจัดการกับพฤติกรรม ไม่ใช่สถานะ

    Java8 แนะนำวิธีอินเทอร์เฟซเริ่มต้นที่มีการนำไปใช้งาน คุณรู้เกี่ยวกับพวกเขาแล้ว ดังนั้นเราจะไม่ทำซ้ำ

  2. คลาสนามธรรมเชื่อมโยงและรวมคลาสที่มีความสัมพันธ์ใกล้ชิดกันมาก ในเวลาเดียวกัน อินเทอร์เฟซเดียวกันสามารถนำไปใช้โดยคลาสที่ไม่มีอะไรเหมือนกันเลย

    กลับมาที่ตัวอย่างของเรากับนก

    คลาสนามธรรมของเราBirdจำเป็นสำหรับการสร้างนกตามคลาสนั้น มีเพียงนกเท่านั้นและไม่มีใครอื่น! แน่นอนว่าพวกเขาจะแตกต่างออกไป

    ความแตกต่างระหว่างคลาสนามธรรมและอินเทอร์เฟซ - 2

    ด้วยอินเทอร์เฟซFlyableทุกอย่างจะแตกต่างออกไป อธิบายเฉพาะพฤติกรรมที่สอดคล้องกับชื่อเท่านั้น - "การบิน" คำจำกัดความของ "การบิน" "สามารถบินได้" รวมถึงวัตถุหลายอย่างที่ไม่เกี่ยวข้องกัน

    ความแตกต่างระหว่างคลาสนามธรรมและอินเทอร์เฟซ - 3

    ตัวตนทั้ง 4 นี้ไม่เกี่ยวข้องกันแต่อย่างใด ฉันจะพูดอะไรได้บ้าง ไม่ใช่ทั้งหมดที่มีชีวิตด้วยซ้ำ อย่างไรก็ตาม พวกมันทั้งหมดFlyableสามารถบินได้

    เราจะไม่สามารถอธิบายสิ่งเหล่านี้โดยใช้คลาสนามธรรมได้ ไม่มีสถานะทั่วไปหรือช่องที่เหมือนกัน ในการจำแนกลักษณะของเครื่องบิน เราอาจจำเป็นต้องระบุข้อมูลในช่อง “รุ่น”, “ปีที่ผลิต” และ “จำนวนผู้โดยสารสูงสุด” สำหรับคาร์ลสัน มีทุ่งนาสำหรับขนมหวานที่เขากินวันนี้ และรายชื่อเกมที่เขาจะเล่นกับเดอะคิด สำหรับยุง...เอ่อ...เอ่อ...เราไม่รู้ด้วยซ้ำ...อาจจะเป็น “ระดับน่ารำคาญ” เหรอ? :)

    สิ่งสำคัญคือเราไม่สามารถอธิบายโดยใช้คลาสนามธรรมได้ พวกเขาแตกต่างกันเกินไป แต่มีพฤติกรรมทั่วไป: พวกมันบินได้ อินเทอร์เฟซนี้เหมาะสำหรับการอธิบายทุกสิ่งในโลกที่สามารถบิน ว่ายน้ำ กระโดด หรือมีพฤติกรรมอื่น ๆ ได้

  3. คลาสสามารถใช้อินเทอร์เฟซได้มากเท่าที่ต้องการ แต่สามารถสืบทอดจากคลาสเดียวเท่านั้น

    เราได้พูดคุยเกี่ยวกับเรื่องนี้มากกว่าหนึ่งครั้งแล้ว ไม่มีการสืบทอดหลายรายการใน 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ไบต์ของอินพุต ส่งคืนจำนวนไบต์ที่ถูกละเว้น
ฉันแนะนำให้คุณศึกษารายการวิธีการทั้งหมด มีคลาสผู้สืบทอดมากกว่าหนึ่งโหลจริงๆ นี่คือตัวอย่างบางส่วน:
  1. FileInputStream: ประเภทที่พบบ่อยInputStreamที่สุด ใช้เพื่ออ่านข้อมูลจากไฟล์
  2. StringBufferInputStream: มีประโยชน์อีกประเภทInputStreamหนึ่ง มันเปลี่ยนสตริงให้เป็นสตรีมข้อมูลInputStreamอินพุต
  3. 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เป็น "เสื้อคลุม" หลังจากนั้นเราจะอ่านไบต์จากไฟล์และแปลงเป็นอักขระ และต่อๆ ไปจนกว่าไฟล์จะสิ้นสุด อย่างที่คุณเห็นไม่มีอะไรซับซ้อนที่นี่ คุณสามารถคัดลอกโค้ดนี้และรันบนไฟล์จริงบางไฟล์ที่เก็บไว้ในคอมพิวเตอร์ของคุณ :) คลาสOutputStreamคือคลาสนามธรรมที่กำหนดเอาต์พุตสตรีมไบต์ ดังที่คุณเข้าใจแล้ว นี่คือสิ่งที่ตรงกันข้ามกับInputStream'a มีหน้าที่รับผิดชอบไม่ใช่ว่าจะอ่านข้อมูลจากที่ไหน แต่มีหน้าที่ส่งข้อมูลไปที่ใด เช่นเดียวกับInputStreamคลาสนามธรรมนี้จัดเตรียมกลุ่มวิธีการทำงานที่สะดวกให้กับผู้สืบทอดทั้งหมด:
  • int close()ปิดกระแสเอาต์พุต
  • void flush()ล้างบัฟเฟอร์เอาต์พุตทั้งหมด
  • abstract void write (int oneByte)เขียน 1 ไบต์ไปยังสตรีมเอาต์พุต
  • void write (byte[] buffer)เขียนอาร์เรย์ไบต์ไปยังสตรีมเอาต์พุต
  • void write (byte[] buffer, int offset, int count)เขียนช่วงจำนวนไบต์จากอาร์เรย์ โดยเริ่มต้นที่ตำแหน่งออฟเซ็ต
นี่คือทายาทบางส่วนของชั้นเรียนOutputStream:
  1. 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()และอื่นๆ

  2. ระดับ FileOutputStream . ใช้กลไกในการส่งข้อมูลไปยังไฟล์บนดิสก์ ยังไงก็ตาม เราใช้มันไปแล้วในตัวอย่างที่แล้ว คุณสังเกตเห็นไหม? เราส่งผ่านมันไปภายใน DataOutputStream ซึ่งทำหน้าที่เป็น "wrapper"

  3. BufferedOutputStream. กระแสเอาต์พุตบัฟเฟอร์ ไม่มีอะไรซับซ้อนเช่นกัน สาระสำคัญก็เหมือนกับในBufferedInputStream(หรือBufferedReader'a) แทนที่จะใช้การบันทึกข้อมูลตามลำดับตามปกติ จะใช้การบันทึกผ่านบัฟเฟอร์ "การจัดเก็บ" พิเศษ ด้วยการใช้บัฟเฟอร์ คุณสามารถลดจำนวนการเดินทางไปกลับไปยังปลายทางข้อมูลได้ และด้วยเหตุนี้จึงปรับปรุงประสิทธิภาพได้

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

    อีกครั้งคุณสามารถ "เล่น" ด้วยโค้ดนี้ด้วยตัวเองและตรวจสอบว่ามันจะทำงานอย่างไรกับไฟล์จริงบนคอมพิวเตอร์ของคุณ

คุณสามารถ อ่านเกี่ยวกับทายาท ได้ ในเนื้อหา " ระบบ InputStreamอินพุต/ เอาท์พุต " โอ้และ เราจะมีการบรรยายแยกกันด้วย จึงมี ข้อมูลเพียงพอสำหรับคนรู้จักครั้งแรก นั่นคือทั้งหมด! เราหวังว่าคุณจะเข้าใจความแตกต่างระหว่างอินเทอร์เฟซและคลาสนามธรรมเป็นอย่างดี และพร้อมที่จะตอบคำถามใด ๆ แม้แต่คำถามที่ยุ่งยาก :) OutputStreamFileInputStreamFileOutputStreamBufferedInputStream
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION