Java Programming - (3)

kangking·2024년 5월 28일

Java

목록 보기
3/10
post-thumbnail

추상클래스

추상 메소드를 포함하고 있는 클래스이다.

추상메소드:

선언부만 있고 구현부는 없는 메소드


//추상 메서드를 하나라도 가지고 있으면
//클래스도 abstract키워드를 명시
abstract class AbClass{

	//선언부 | abstract 키워드로 추상메서드임을 명시
	public abstract void abTest(){
    	//구현부
    }
    
}
  • 추상메소드는 객체를 생성할 때 구현해도 되지만 그렇게는 잘 사용하지 않는다.

인터페이스

추상 메소드만으로 이루어진 클래스를 의미하며, 인터페이스 안에 만들어지는 메소드들은 전부 추상메소드기 때문에 abstract키워드를 명시하지 않아도 된다.

  • 인터페이스를 상속받으면(Implements) 반드시 모든 메소드를 오버라이딩하여 구현해야함

  • 변수도 만들 수 있으나 잘 사용하지 않으며, 만들시 반드시 값을 지정해줘야 함

  • 메소드가 구현되어있지 않기 때문에 객체를 직접 생성할 수 없고, 인터페이스를 구현한 구현체로 객체를 만든다.

구현체

//인터페이스를 상속받아 구현하는 구현체, 인터페이스는 구현체로 객체화 가능하다.
	public class InterfaceImplements1 implements InterfaceTest{
    
      //오버라이딩 해야할 메소드1

      //오버라이딩 해야할 메소드2

      //오버라이딩 해야할 메소드3
    }

다형성

하나의 변수에 서로 다른 클래스를 구현한 객체를 저장할 수 있는 것 (일반적으로 상속관계에 한정)

	//자기 타입으로 자신 객체 생성
	InterfaceImplements1 it01 = new InterfaceImplements1();
    InterfaceImplements2 it02 = new InterfaceImplements2();
    //부모 인터페이스 타입으로 자식1 객체 생성
    InterfaceTest it03 = new InterfaceImplements1();
    //부모 인터페이스 타입으로 자식2 객체 생성
    InterfaceTest it04 = new InterfaceImplements2();
  • 부모 타입의 변수에 자식타입의 구현체들을 담을 수 있다.

다형성의 장점

  • 유지보수: 여러 객체를 하나의 타입으로 관리할 수 있어 유지보수가 용이하다.
  • 재사용성: 객체의 재사용이 쉬워 재사용성이 높아진다.
  • 느슨한 결합: 클래스 간의 의존성을 줄여 확장성은 높아지고 결합도는 낮아진다.

업캐스팅

자식 타입을 부모 타입으로 형변환 시키는 것

  • 일반적으로 부모타입으로의 업캐스팅은 자동으로 이루어진다

  • 부모 타입으로 업캐스팅을 하면 자식타입에서 새롭게 정의되거나 추가된 기능과 속성은 사용할 수 없기 때문에, 실제 사용할 때는 반드시 다운캐스팅을 해서 원래 타입으로 바꿔줘야한다.

다운캐스팅

부모 타입을 자식 타입으로 형변환 시키는 것

  • 업캐스팅된 자식 타입의 새롭게 변경된 기능과 속성을 사용할 수 있도록 원래타입으로 바꿔준다. 객체앞에 (타입)을 명시해준다
	Car c1 = new Bmw();
    //부모타입에서 정의되지 않은 자식타입의 메소드는 접근불가
    c1.bmwNewFunction();
    //다운캐스팅하여 다시 원래타입으로 변경
    c1 = (Bmw)c1;
    //이제 자기 타입으로 변경되었기 때문에 접근가능
    c1.bmwNewFunction();

예외처리

문법적으로 틀린 것은 아니지만 프로그램이 실행중에 발생할 수 있는 다양한 문제에 대한 처리를 하는 코드

예외를 방치하면 프로그램이 종료되는데, 이를 방지하기 위해 프로그램에 예외가 발생할 경우 이에 대한 처리를 해주어 프로그램이 계속해서 정상 동작할 수 있도록 한다.

  • try catch

    가장 간단하게 예외처리를 할 수 있는 문법으로, try문 안에 예외가 발생할 것 같은 코드를, catch문 안에 예외 발생시 처리할 코드를 입력하여 프로그램을 동작하게 한다.

        Integer num01 =10;
        Integer num02 = 0;
        Integer result;
        
        //try catch는 모든 블록이 각각의 필드이기 때문에
        //밖에 선언해야 안에서 쓸 수 있다. 안에서 선언하면
        //해당 필드에서밖에 못씀
        try {
            result = num01 / num02;
		
        //Exception은 최상위 예외이기 때문에 다 잡을 수 있지만
        //다양한 예외 종류마다 처리가 달라야한다면
        //Exception을 상속받는 예외 클래스별로 catch처리한다.
        }catch (ArithmeticException e1){
        	//큰 범위로 예외를 처리하기 전에 디테일하게 처리
            e1.printStackTrace();
            result = 10;
        } catch (Exception e2){
            e2.printStackTrace();
            result = 0;
        }
		//0으로 나누면 예외가 발생하지만 처리했기 때문에
        //에러 로그는 찍히고 프로그램은 다음까지 정상동작한다.
        //try catch를 쓸 때 변수가 초기화 되어있는지확인해야하고,
        //해당 구문안에서 선언되지 않았는지도 확인해야한다.
        System.out.println(result);

throws

예외 처리를 바로 하지 않고, 해당 메소드를 호출한 곳으로 예외를 떠넘기는 키워드

해당 예외가 발생한 메소드를 최초 호출한 코드는 예외처리가 되어있어야 한다. (순수 Java 한정)

  • 보통은 예외때 별도 처리를 하기 보단 logger를 사용해서 log를 수집하는 컴퓨터에 일정한 규격으로 보내서 파악하고 처리한다.

입출력스트림

~와의 통로라는 의미
일반적으로는 H/W장치와의 통로라고 생각하면 편하다.

  • HDD와의 통로? => 파일 저장 및 로드
  • 랜카드와의 통로? => 네트워크 통신
  • 모니터와의 통로? => 화면에 표시

파일 스트림

프로그램 기준으로 HDD에서 파일을 읽어오는 것이기 때문에 읽기 스트림: InputStream

저장은 HDD로 내보내는 것이기 때문에
저장 스트림: OutputStream이다.

  • read() 메소드는 1바이트(16진수 2자리)씩 읽어온다
  • main 메소드의 실행시 넘겨주는 매개변수 args 배열은 IDE에서 아래와 같이 경로를 지정해줄 수도 있다.,

  • 스트림을 사용하면 반드시 다 쓰고 닫아줘야 한다.(열었을 때의 역순으로 닫아야 함)

  • 입력 스트림 사용 예시

try {
	//파일과의 통로를 열어서 바이트 단위로 데이터를 읽어오는 객체
	FileInputStream fileInputStream = new FileInputStream("/Users/kangking/zzz.txt");

	//글자 단위로 데이터를 읽어오는 스트림. 인코딩을 지정할 수 있다.
	InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"UTF-8");

	//읽어온 내용을 담는다 (Buffer는 일종의 완충제 역할 - 속도가 빠름) 스캐너보다 빠름
	BufferedReader br = new BufferedReader(inputStreamReader);

	int res;
	while ((res = br.read()) != -1){
		System.out.print((char) res);
	}
	br.close();
	inputStreamReader.close();
	fileInputStream.close();
}catch (Exception e){
	e.printStackTrace();
}

소켓통신

남의 컴퓨터에 실행중인 남의 프로그램과의 통로를 열어주는 스트림

OSI7레이어중 4계층까지 알아서 해주는 스트림

서버 소켓

서버 소켓은 클라이언트의 요청을 대기하기 위한 장치로 생성자에 포트번호를 명시해주고, accept() 메소드를 사용하여 해당 포트로 클라이언트가 연결될 때 까지 대기한다.

	//port번호를 생성자에 넘겨주어 해당 포트로 오는 요청에 대해 대기
    serverSocket = new ServerSocket(9999);
    
    //accept()로 대기하다가, 연결되면
    //클라이언트 소켓의 정보를 담을 Socket 변수에 연결결과를 담아준다. 
    Socket clientSocket = serverSocket.accept();

소켓의 입력 스트림

소켓이 연결되면 소켓과 대상간 스트림이 개방되며 InputStream에 해당 스트림 연결을 빌려와 사용할 수 있다.

소켓의 아웃풋 스트림

InputStream과 마찬가지로 OutputStream을 통해 연결된 스트림을 빌려와 사용할 수 있다.

즉, Socket으로 스트림을 개방하고, 해당 스트림에서 발생하는 Input과 Output을 InputStream, OutputStream으로 가져와 사용할 수 있다.

profile
하루하루 의미있게

0개의 댓글