
-
인터페이스는 동작만 설명합니다. 상태가 없습니다. 그러나 추상 클래스는 상태를 포함합니다. 둘 다 설명합니다.
예를 들어
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(); }
인터페이스 내부에 개인 변수를 선언할 수도 없습니다 . 왜? 사용자로부터 구현을 숨기기 위해 private 한정자가 만들어졌기 때문 입니다. 그리고 인터페이스에는 내부에 구현이 없습니다. 숨길 것이 없습니다.
인터페이스는 동작만 설명합니다. 따라서 인터페이스 내부에 getter 및 setter를 구현할 수 없습니다. 이것이 인터페이스의 특성입니다. 인터페이스는 상태가 아니라 동작과 함께 작업하는 데 필요합니다.
Java 8에는 구현이 있는 인터페이스에 대한 기본 메서드가 도입되었습니다. 당신은 이미 그들에 대해 알고 있으므로 우리는 반복하지 않을 것입니다.
-
추상 클래스는 매우 밀접하게 관련된 클래스를 연결하고 통합합니다. 동시에 단일 인터페이스는 전혀 공통점이 없는 클래스에 의해 구현될 수 있습니다.
새의 예로 돌아가 보겠습니다.
추상 클래스
Bird
는 해당 클래스를 기반으로 새를 생성하는 데 필요합니다. 새만 있고 다른 것은 없습니다! 물론 다양한 종류의 새들이 있을 것입니다.인터페이스를 사용하면
CanFly
모든 사람이 자신의 방식으로 작업을 수행할 수 있습니다. 이름과 관련된 동작(비행)만 설명합니다. 관련 없는 많은 것들이 '날 수 있다'.이 4개의 엔터티는 서로 관련이 없습니다. 그들은 모두 살아 있지도 않습니다. 그러나 그들은 모두
CanFly
.추상 클래스를 사용하여 설명할 수 없습니다. 동일한 상태 또는 동일한 필드를 공유하지 않습니다. 항공기를 정의하려면 모델, 생산 연도 및 최대 승객 수에 대한 필드가 필요할 것입니다. Carlson의 경우 오늘 먹은 모든 과자를 위한 필드와 남동생과 함께 할 게임 목록이 필요합니다. 모기의 경우, ...어... 나도 모르겠어... 아마도 '성가심 수준'? :)
요점은 그것들을 설명하기 위해 추상 클래스를 사용할 수 없다는 것입니다. 그들은 너무 다릅니다. 그러나 그들은 공유된 행동을 가지고 있습니다. 그들은 날 수 있습니다. 인터페이스는 날고, 수영하고, 점프하거나, 다른 행동을 보일 수 있는 세상의 모든 것을 설명하는 데 적합합니다.
-
클래스는 원하는 만큼 많은 인터페이스를 구현할 수 있지만 하나의 클래스만 상속할 수 있습니다.
우리는 이미 이것을 두 번 이상 언급했습니다. Java는 클래스의 다중 상속이 없지만 인터페이스의 다중 상속을 지원합니다. 이 점은 이전 항목에서 부분적으로 이어집니다. 인터페이스는 종종 공통점이 없는 많은 다른 클래스를 연결하는 반면 추상 클래스는 매우 밀접하게 관련된 클래스 그룹에 대해 생성됩니다. 따라서 이러한 클래스를 하나만 상속할 수 있다는 것이 이치에 맞습니다. 추상 클래스는 'is-a' 관계를 설명합니다.
표준 인터페이스: InputStream 및 OutputStream
우리는 이미 입력 및 출력 스트림을 담당하는 다양한 클래스를 살펴보았습니다. 그리고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
. An이 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
와 BufferedInputStream
그것을 '감싸는' a입니다. 그런 다음 파일에서 바이트를 읽고 문자로 변환합니다. 파일이 끝날 때까지 그렇게 합니다. 보시다시피 여기에는 복잡한 것이 없습니다. 이 코드를 복사하여 컴퓨터의 실제 파일에서 실행할 수 있습니다 :) 클래스는 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