[JAVA-4] 클래스 기본

ParkJunHa·2023년 9월 26일

객체지향 프로그래밍

절차 중심이 아닌 객체 중심으로 프로그래밍 하는 것

객체지향 언어는 절차지향과 다르게 순서와 과정을 중요하게 생각하지 않는다.
사람이 사고하는 방식을 그대로 프로그래밍에 적용한 것이며, 사람의 관점에서 프로그래밍 하기 때문에 이해하기 쉽고 각 기능들을 모듈화 하기 쉽다.

모듈화란 각 기능을 부품화 한다는 의미이며, 필요할 때마다 조립해서 사용할 수 있다.

객체 지향 언어의 특징

  • 사람이 행동하고 생각하는 방식으로 프로그래밍
  • 순서 과정이 중요하지 않음
  • 이해하기 쉽고, 모듈화 하기 쉽다
  • 재사용성이 높고, 유지보수가 용이
  • 설계 중심 언어

객체 지향 프로그래밍 과정

  1. 아이디어 도입 : 구현될 프로그램에 대한 요구를 나타낸다.
  2. 아이디어 분석 : 주체의 관점에서 아이디어를 분석한다.
  3. 객체 추출 : 주체의 관점에서 객체를 추출한 후 속성과 동작을 나열한다.
  4. 객체 모델링 : 개발자의 관점에서 객체의 속서오가 동작을 정제한다.
  5. 클래스로 변환 : 객체를 클래스로 변환한다.
  6. 인스턴스 생성 및 사용 : 메모리에 인스턴스로 생성한 후 사용한다.

객체 추출

객체의 속성과 동작을 추출한다. 객체가 가지고 있는 특성과 그 객체가 동작하는 방법을 나열한다.
이 객체의 속성은 개발자가 아닌, 일반인(주체)의 입장에서 각 객체의 속성과 동작을 추출한다.

예를 들어 랜터카 회사에 대한 객체가 있다고 가정하자.

  • 직원
속성동작
이름, 나이, 직급빌려준다, 예약을 확인한다, 차량을 관리한다
  • 고객
속성동작
이름, 주소, 나이, 전화번호예약한다, 사용한다, 지불한다

객체 모델링

프로그래밍에 필요하지 않는 속성이나 동작은 배제하고, 실제 객체 추출에서는 파악되지 않았지만 프로그래밍시에는 필요한 속성이나 동작이 있다면 추출한다.

객체 추출 단계에서 만든 속성과 동작이 모두 실제 프로그래밍에 사용되는 것은 아니기 떄문에 객체 모델링 단계에서는 실제 프로그래밍에 필요한 속성과 동작을 정제한다.

위의 예시를 그대로 가져온다면 아래와 같다

  • 직원
속성동작
이름, 직급빌려준다, 예약을 확인한다
  • 고객
속성동작
이름, 주소, 전화번호, 아이디, 비밀번호예약한다, 사용한다, 지불한다

클래스 변환

객체 모델링을 통해 추출된 객체를 자바 클래스로 변환하는 것

클래스 UML 표기법을 이용한다. 이는 분석, 설계시에 작업한 결과물을 문서화 할 때 사용하는 일종의 표기법이다.

  • + : public
  • # : protected
  • - : private
UML
Student (클래스 명)
- name : String- address : String (변수명 : type)
+ Study() : String+ getTest() : String (method1() : return type)

이때 객체명은 클래스명으로 변환, 속성은 맴버 변수로 변환, 동작은 매서드로 변환된다.
멤버 변수는 객체 모델링에서 추출한 속성을 클래스에서 표현하는 변수이며, 맴버 필드, 인스턴스 변수, 속성 이라고도 한다.

지정자

  • 접근 지정자 : public, private, protected
  • 일반 지정자 : static, abstract, final 등

일반적으로 접근지정자와 일반지정자를 조합하여 사용한다.

[접근 지정자] [일반 지정자] 데이터 형 변수

위에 있는 UML을 기준으로 클래스를 하나 만들어보겠다.

package com.chapter5;  
  
public class ExStudent {  
    private String name;  
    private String address;  
      
    public void study(){  
        System.out.println("공부를 합니다.");  
    }  
    public String getText(String score){  
        return score;  
    }  
}
  • getter 메서드 : 멤버 변수의 값을 얻어올 때 사용
  • setter 메서드 : 멤버 변수의 값을 할당할 때 사용

아래는 getter, setter메서드를 적용한 Student 클래스이다.

package com.chapter5;  
  
public class ExStudent {  
    private String name;  
    private String address;  
  
    public String getName(){  
        return name;  
    }  
    public String getAddress(){  
        return address;  
    }  
    public void setName(String _name){  
        name = _name;  
    }  
    public void setAddress(String _address){  
        address = _address;  
    }  
}

멤버 변수의 접근지정자가 private이므로 직접 접근이 불가능 하나, getter, setter메서드는 public이므로 호출할 수 있다.

클래스 인스턴스

정의한 클래스를 이용하여 컴퓨터의 메모리에 클래스의 속성과 기능을 가지는 객체

클래스는 일종의 설계도 또는 명세서와 같은 의미이다. 우리는 클래스 자체를 사용할 수 없다. 우리가 클래스를 실제로 사용하기 위해서는 클래스 내에 있는 변수와 메서드를 실제로 메모리에 생성해야 한다. 실제 클래스가 메모리에 생성된 상태를 클래스 인스턴스 또는 클래스 객체 라고 한다.

인스턴스 생성법

앞서 만든 Student클래스 인스턴스를 생성하는 방법을 보인다.

Student s;
s = new Student();
// 생성된 인스턴스는 같은 클래스 타입 참조 변수에 할당해야 한다.

실행 클래스

객체 지향 프로그래밍에서 분석, 설계 과정을 거쳐 클래스를 만들었으면 최종적으로 각 클래스의 기능을 조립하여 하나의 완성된 기능을 하는 프로그램을 구현하는 컨베이어 벨트와 같은 기능을하는 실행클래스라는 개념이 필요하다.
실행 클래스는 각 기능을 하는 클래스들의 인스턴스를 생성한 뒤, 각 클래스 인스턴스를 초기화하고, 각 클래스 인스턴스로 원하는 작업을 하여 최종 결과를 만들어낸다. 따라서 실행 클래스에는 반드시 프로그램의 시작점 역할을 하는 main메서드가 존재해야 한다.

import com.chapter5.ExStudent;  
  
public class Main {  
    public static void main(String[] args) {  
        ExStudent s;  
        s = new ExStudent();  
  
        s.setName("이순신");  
        String name = s.getName();  
        System.out.println("학생 이름은 "+name);  
    }  
}

용어

  • 주체(Object) : 일반 사용자, 사람
  • 객체(Subject) : 주체가 바라본 대상 (사람, 사물, 개념)
  • 속성(Property) : 객체가 가지고 있는 특징이나 상태
  • 동작 : 객체가 수행하는 기능, 업무 및 행위

실습

[[3. 자바 명령문과 배열#배열 (array)|배열]]의 요소의 총 합과 평균을 구하는 기능과 배열의 요소의 값을 오름차순으로 출력해주는 기능을 하는 클래스 구현

UML 구현

UML
ArrayTest
- arr : int []
+ arrSum() : int+arrAvg() : int
//Main.java
import com.chapter4.practice;  
import com.chapter5.ExArrayUtil;  
  
public class Main {  
    public static void main(String[] args) {  
        ExArrayUtil util;  
        util = new ExArrayUtil();  
        int[] arr = {1,2,3,4,5};  
        util.setArray(arr);  
        System.out.println(util.arrSum());  
        System.out.println(util.arrAvg());  
    }  
}
//ExArrayUtil.java
package com.chapter5;  
public class ExArrayUtil {  
    private int[] ar;  
    public void setArray(int[] changedArray){  
        ar = changedArray;  
    }  
    public int[] getArray(){  
        return ar;  
    }  
  
    public int arrSum(){  
        int s = 0;  
  
        for(int i = 0; i < ar.length; i++){  
            s += ar[i];  
        }  
        return s;  
    }  
  
    public float arrAvg() {  
        int avg = this.arrSum() / ar.length;  
        return avg;  
    }  
}

이때 getter를 사용해 배열을 출력할때는 아래와 같이 사용한다.

System.out.println(util.getarray().toString())

생성자(Constructor)

클래스가 객체 생성될 때 맨 처음 호출되는 것
반드시 클래스 명과 동일 해야 함.

생성자는 메모리에 크랠스 인스턴스를 생성시킬 때나 인스턴스 생성 시 인스턴스 변수를 초기화 하는 용도로 사용된다.
생성자에는 클래스 명을 반드시 써주어야 하고, 앞에 [[4. 클래스 기본#지정자|접근 지정자]]를 지정해주어야 하며, 매개 변수도 지정해주어야 한다.

형식

[접근 지정자] 클래스 명 ([매개 변수]){
	// 인스턴스 변수 초기화
	// 명령문
}

생성자의 형식은 메서드와 비슷하나 리턴 타입이 없다. 또한 사용자가 생성자를 만들어주지 않으면 자동으로 컴파일 시 디폴트 생성자를 추가한다.

특징

  • 메서드와 비슷한 기능을 한다
  • 리턴 타입이 없다
  • 생성자를 구현해주지 않으면 컴파일러가 자동으로 디폴트 생성자를 추가한다
  • 생성자를 명시적으로 구현하면 디폴트 생성자는 추가되지 않는다.

앞선 Student클래스에 생성자를 추가해본다.

package com.chapter5;  
  
public class ExStudent {  
    private String name;  
    private String address;  
  
    public ExStudent(String _name){  
        name = _name;  
    }  
    public ExStudent(){  
  
    }  
    public String getName(){  
        return name;  
    }  
    public String getAddress(){  
        return address;  
    }  
    public void setName(String _name){  
        name = _name;  
    }  
    public void setAddress(String _address){  
        address = _address;  
    }  
}

나중에 나올 개념인 것 같은데 생성자 오버로딩을 통해 만약 이름이 주어져 인스턴스가 생성된다면 첫번째 생성자를 그렇지 않다면 두번째 디폴트 생성자를 호출하여 초기화 한다.

//main.java
ExStudent std1, std2;
std1 = new ExStudent("홍길동");
std2 = new ExStudent;

주의해야 할 점

사용자 지정 생성자를 만든 경우 디폴트 생성자를 따로 만들어주지 않으므로, 습관적으로 디폴트 생성자를 만들어주는 습관이 필요함.

오버로딩

생성자 오버로딩(overloading)

생성자를 여러개 만드는 방법을 생성자 오버로딩이라고 하며 사용 이유는 다음과 같다.

  1. 다양한 초기화 옵션 제공: 클래스가 여러 개의 생성자를 가지면 사용자는 객체를 원하는 방식으로 초기화할 수 있습니다. 이는 사용자의 요구에 따라 다양한 초기화 방법을 제공할 수 있는 유연성을 제공합니다.
  2. 편의성: 생성자 오버로딩은 사용자에게 편의성을 제공합니다. 예를 들어, 사용자는 필요한 정보만을 제공하여 객체를 생성할 수 있으며, 다른 정보는 기본값으로 설정될 수 있습니다.
  3. 가독성: 다양한 생성자를 사용하면 코드의 가독성을 향상시킬 수 있습니다. 사용자는 어떤 생성자가 어떤 목적으로 사용되는지 명확하게 이해할 수 있습니다.
  4. 타입 안정성: 생성자 오버로딩을 사용하여 다양한 데이터 유형을 처리할 수 있으므로, 타입 안정성을 유지하면서 객체를 생성할 수 있습니다.

생성자 오버로딩을 할 때는 각 매개변수의 개수, 타입, 순서를 다르게 하여 사용해야 한다.

메서드 오버로딩

생성자 오버로딩과 마찬가지로 같은 클래스 내에 동일한 이름의 메서드가 여러개 존재하는 것을 의미한다.

반드시 메서드 매개변수 형식이 달라야하며, 리턴타입은 달라도 상관없다.

public class ClassUtil{
	public void get(){...}
	public void get(int n){...}
	public int get(String n, int a){...}
}

패키지(package)

같은 기능을 하는 클래스들을 모아놓은 그룹

특징

  • 같은 기능을 하는 클래스들을 편리하게 관리하기 위해 사용한다
  • 윈도우의 폴더와 비슷하다
  • 자바에서 제공하는 API는 모두 패키지로 제공된다.

형식

package pack;
package test1, test2;
  • 반드시 클래스 첫 라인에 사용한다
  • 패키지 명은 소문자를 사용한다
  • 자바 파일 최상단에 한 번만 선언한다.

명명법

각 회사에서 사용하는 도메인 이름을 역순으로 배열하여 사용하고 있다.(역도메인 명명법)
예를 들어 jweb.com이라는 회사에서 어떤 프로그램을 패키지로 개발한다고 하면 아래와 같을 것이다.

패키지명.프로젝트명.기능명.클래스명
	# com.jweb.prjname.member.MemWindow

import

패키지가 다른 클래스에 접근할 때 사용한다.

형식

import package_name.class_name;
import package_name *;
  • 반드시 클래스보다 먼저 선언되어야 한다
  • 모든 자바 API를 사용할 때에는 반드시 import해야 한다.
  • java.lang 패키지는 자동으로 import된다.
  • import문은 여러 번 사용될 수 있다.

[[2. 자바의 기본 문법#기본형|기본형 변수]]와 [[2. 자바의 기본 문법#참조형|참조형 변수]]

  • 기본형 변수에 실제 값이 저장된다.
  • 참조형 변수에는 메모리에 생성되어 있는 인스턴스의 위치 값을 저장한다.
profile
PS린이

0개의 댓글