Java OOP(1)

ChoRong0824·2023년 4월 4일
3

Java

목록 보기
9/31
post-thumbnail

~ 4월 8일, 객체지향 프로그래밍

OOP

  • 객체지향 프로그래밍, 객체를 기반으로 하는 프로그램

절차지향 프로그래밍

일어나는 일을 시간순으로 프로그래밍
대표적으로, C 언어

객체지향 프로그래밍

객체를 정의하고, 객체 간 협력을 프로그래밍 하는 것
먼저 객체를 만들고 객체 사이에 일어나는 일을 구현하는 것입니다.
따라서, 객체를 먼저 정의하고, 각 객체가 어떤 기능을 제공하고 객체 간 협력을 어떻게 구현할 것인지 고민하는게 keyPoint


클래스

  • 객체지향 프로그래밍은 클래스를 기반으로 프로그래밍

  • 클래스는 객체의 속성과 기능을 코드로 구현한 것.

  • 클래스의 이름은 대문자로 시작

  • 문법

(접근 제어자) class 클래스이름 {
	멤버 변수;
    메서드;
}

클래스에 선언하는 멤버 변수는 다른 말로 속성, 특성으로 표현됩니다.

  • 멤버변수 예시
	int studentID;
    String studentName;
    int grade;
    String address;

멤버 변수는 기본자료형 || 참조자료형으로 나뉨.

  • 기본자료형 (int,long, float, double 등), 참조자료형 (String, Date, Student등)

메서드

클래스 내부에서 멤버변수를 사용해서 클래스 기능을 구현한 것을 멤버함수 || 메서드 라고 합니다.

  • 예시
public void showStudentInfo(){
	Syso(studentName + "," + address); 
}

메서드는 함수의 한 종류입니다.

함수 먼저 확인하고, 자바에서 사용하는 메서드에 대해 자세히 공부하겠습니다.

함수란 ?

  • 하나의 기능을 수행하는 일련의 코드
1. 숫자 두 개 입력받아 더한다
2. 성적 두 개 더한다
3. 두 거리 더한다

1~3 경우에 더하기 기능을 수행하는 코드를 묶어서 '더하기 함수'로 만들 수 있습니다
이 처럼 함수는 어떤 기능을 수행하도록 미리 구현해 놓고 필요할 때마다 호출하여 사용할 수 있습니다.

  • 함수 정의
int add (int num1, int num2){ 
	int result;
    result = num1+num2;
    return result;
}
  • 해석,
    함수 반환형: int, 함수 이름 : add , 매개변수 num1, num2, return 예약어 : return
    매개변수,
    입력된 두 값은 함수를 호출할 때, 괄호 안의 자료형에 맞게 함수에 전달됩니다.
    함수는 넘겨받은 값으로 덧셈을 수행합니다. 이렇게 함수 내부에서 사용할 괄호 안의 변수를 매개변수라고 합니다.
    매개변수가 필요하지 않는 경우 도 있습니다.
int getTenTotal(){
	int i;
    int total = 0;
    for(i =1; i<=10; i++){
    	total +=i;
        }
      return total; // 1부터 10까지 더한 값을 반환
    }
  • 위 코드처럼 매개변수가 필요 없는 함수도 있습니다.
    getTenTotal() 함수의 기능은 1부터 10까지 더한 합을 반환합니다.
    즉, 함수에 전달할 값이 굳이 필요하지 않습니다.
    이런 경우에 함수는 매개변수가 필요 없고 함수를 수행한 결과 값만 있게 됩니다.

return 예약어와 반환형
add() 함수를 수행한 후 결과 값은 변수 result에 저장 됩니다. result에 저장된 결과 값은 함수를 호출했을 때, 반환되는 값이므로 '반환 값' 이라고 부릅니다. -> return, 결과 값을 반환 하는 예약어

반환 값이 없는 함수

void printAdd(String name){
	sout(name + " 님 안녕"); // 전달받은 매개변수 name을 사용해서 인사말 출력
    return; // 반환 값 없음
}

반환 값이 없다고 해서 반환형을 쓰는 위치를 비워두면 오류가 발생하니, 이 위치에 void라고 씁니다.
void : 비어있다는 의미로 '반환할 값이 없다'는 뜻의 예약어 입니다.

return 예약어는 함수 수행을 끝내고 프로그램 흐름 중에서 호출한 곳으로 다시 되돌아갈 때도 사용할 수 있습니다.
(활용 예시, 빅 O 알고리즘편 참고)

void Div( int num1, int num2){
if(num2 ==0){
	sout("나누는 수는 0 이 될 수 x);
    return; // 함수수행 종료 예약어 
    // 함수 수행을 종료하는 목적이므로 return 뒤에 값 기재 x
} else {
	int result = num1/num2;
	sout(num1+ "/" + num2 + "=" +result +"입니다");
    }}

함수 호출하고 값 반환하기

예) 두 정수를 더한 후 결과 값을 돌려주는 함수. -> 함수를 호출한다고 표현함

package exam;

public class FunctionTest{
	public static void main(String[] args){
    	int num1 = 10;
        int num2 = 20;
        
        int sum = add(num1, num2); // add() 함수 호출
        int subs = sub(num1, num2);
        int divs = div(num1, num2);
        int muls = mul(num1, num2);


        System.out.println(sum);
        System.out.println(subs);
        System.out.println(divs);
        System.out.println(muls);
	}
        
private static int add (int n1, int n2){
	int result = n1 + n2;
    return result;
    }
private static int sub (int a, int b){
	int result = a - b;
    return result;
	}
private static int div (int a, int b){
	int result = a/b ;
    return result;
	}
private static int mul (int a, int b){
	int result = a * b;
    return result;
	}
}

결과 값이 정수이기 때문에 반환형이 int형. (함수 호출부분)

참고 !
처음 공부하는 사람들은 함수를 호출할 때, 넘겨주는 변수 이름과 함수를 구현할 때 사용한 매개변수의 이름이 같아야 한다고 생각할 수 있습니다.
But,
이 둘은 전혀 상관 없습니다.

즉, 위 코드를 보면 매개변수 n1, n2는 실제 함수로 넘어온 두 값을 받아주는 역할을 합니다.
다시말해, n1, n2는 add() 함수에서 선언한 새로운 변수인 것입니다.
따라서 함수를 호출할 때 사용하는 변수 이름과 호출되는 함수에서 사용하는 변수는 서로 다른 변수이므로 이름이 같아도 되고 달라도 상관 없습니다. !!

함수 호출과 스택 메모리

함수를 호출하면 그 함수만을 위한 메모리 공간이 할당 되는데, 이 메모리 공간을 스택이라고 함.
즉, main()함수에서 사용하는 num1,num2변수와 add()함수에서 사용하는 변수는 서로 다른 메모리 공간을 사용하므로 이름이 같든 다르든 상관 없습니다.
이렇게 함수 내부에서만 사용하는 변수를 지역변수 라고하며, 지역변수는 스택 메모리에 생성됩니다.

간단하게, 운영체제 및 자료구조의 스택과 큐를 생각하면 됩니다.

  • 큐 : 선입선출 First In First Out
    예) 커피 주문 시, 먼저 주문한 사람이 먼저 커피 가져감

  • 스택 : 후입선출 Last In First Out
    가장마지막에 자료가 가장 먼저 삭제되는 구조이며,
    쌓다라는 의미로, 데이터를 차곡차곡 쌓아올린 자료구조.
    예) 웹 브라우저 방문기록 (뒤로가기)

함수를 사용하는 이유

  1. 기능을 나누어 코드를 효율적으로 구현 가능
  2. 중복되는 코드 막기 (같은 기능을 매번 코드로 만들지 x)
  3. 오류 수정에 용이

클래스와 인스턴스

public class Student{
	// 멤버 변수
	int studentID;
    String studentName;
    int grade;
    String address;
    
    // 메서드
    public String getStudentName(){
    	return studentName;
        }
    public void setStudentName(String name){
    	studentName = name;
        }
}

클래스를 사용하려면 먼저 클래스를 생성해야 합니다. 클래스를 생성하는 코드
클래스형 변수이름 = new 생성자;

  • 예시,
    Student studentAhn = new Student();
    Student 클래스 자료형으로 studentAhn 변수를 선언하고, new Student();로 Student 클래스를 생성하여 studentAhn에 대입한다는 뜻
    이때, studentAhn은 참조변수, 이 변수가 생성된 인스턴스를 가리킴

객체, 클래스, 인스턴스 관계

객체란 '의사나 행위가 미치는 대상'이며 이를 코드로 구현한 것이 클래스입니다.
그리고 클래스가 메모리 공간에 생성된 상태를 인스턴스라고 합니다.
또한 생성된 클래스의 인스턴스를 객체라고도 합니다.

인스턴스와 힙 메모리

클래스 생성자를 하나 호출하면 인스턴스가 힙 메모리에서 생성됩니다.
Student studentAhn = new Student();
위와 같이 생성된 클래스를 studentAhn 변수에 대입하면, 인스턴스가 저장된 메모리를 studentAhn 변수가 가리킵니다.
(studentAhn 변수는 지역변수, 지역변수는 스택 메모리에 생성됨)
but,
인스턴스는 힙 메모리에 생성됨.
즉, studentAhn에 인스턴스가 생성된 힙 메모리의 주소를 대입한다는 것임.

힙은 프로그램에서 사용하는 동적 메모리 공간입니다.
일반적으로 프로그램은 stack, heap, memory 이렇게 세 영역을 사용하는데, 객체가 생성될 때 사용하는 공간이 힙입니다.
힙은 동적으로 할당되며 사용이 끝나면 메모리를 해제해 주어야 합니다.
(c나 c++은 직접 해제, 자바는 가비지 컬렉터가 자동으로 해제)

정리

용어 설명
객체 객체 지향 프로그램의 대상, 생성된 인스턴스
클래스 객체를 프로그래밍하기 위해 코드로 만든 상태
인스턴스 클래스가 메모리에 생성된 상태
멤버 변수 클래스의 속성, 특성
메서드 멤버 변수를 이용하여 클래스의 기능을 구현
참조 변수 메모리에 생성된 인스턴스를 가리키는 변수
참조 값 생성된 인스턴스의 메모리 주소 값

생성자

클래스를 생성할 때 사용하는 함수.
클래스의 멤버 변수는 메서드에 의해 값이 변경될 수도 있지만, 처음 클래스를 생성할 때 값을 정해야하는 경우도 있습니다.
생성자가 하는 일은 클래스를 처음 만들 때 멤버 변수나 상수를 초기화 하는 것입니다.

참고 , 자바 컴파일러는 생성자가 하나도 없는 경우에만 디폴트 생성자를 제공합니다. 프로그래머가 생성자를 직접 추가하면 디폴트 생성자는 만들어지지 않습니다.
이런 경우, 매개변수가 있는 생성자로 호출 || 디폴트 생성자를 추가로 직접 구현하면 됨.

  • 디폴트 생성자 직접구현
//person.java
public class Person {
    String name;
    float height;
    float weight;

    public Person(){

    }
    public Person(String pname){
        name = pname;
    }
}
// personTest.java
public class PersonTest {
    public static void main(String[] args) {
        Person personMun = new Person();
    }
}

오버로드

OOP 에서 메서드 이름이 같고, 매개변수만 다른 경우를 overload라고 함.


클래스에 생성자가 두 개 이상 제공되는 경우를 생성자 오버로드 라고 함.
필요에 따라 매개변수가 다른 생성자를 여러 개 만들 수 있습니다.
클래스에 생성자를 여러 개 제공하면 이 클래스를 사용하는 코드에서는 원하는 생성자를 선택해 사용할 수 있습니다. 경우에 따라서는 클래스에서 일부러 디폴트 생성자를 제공하지 않기도 함.

//
public class Person {
    String name;
    float height;
    float weight;

    // 디폴트 생성자
    public Person(){}

    // 이름을 매개변수로 입력 받는 생성자
    public Person(String pname){
        name = pname;
    }
    // 이름 , 키 , 몸무게를 매개변수로 입력 받는 생성자
    public Person(String pname, float pheight, float pweight){
        name = pname;
        height = pheight;
        weight = pweight;
    }
}

//
public class PersonTest {
    public static void main(String[] args) {
        // 디폴트 생성자로 클래스를 생성한 후, 인스턴스 변수 값을 따로 초기화
        Person personMun = new Person();
        personMun.name = "seongjun";
        personMun.weight = 120F;
        personMun.height = 185.2F;

        // 인스턴스 변수 초기화와 동시에 클래스 생성
        Person personlittleJun = new Person("문성준", 185, 88);
        // 이렇게 하면 매개변수가 있는 생성자를 사용해서 생성자 내부에서 변수를 초기화 할 수 있도록 구현하여, 코드 간결함.
    }
}

정보 은닉

접근 제어자 : 생성자에 대한 접근 권한을 지정하는 예약어
(private : 내부 클래스에서만 사용, public : 외부 클래스에서 사용가능)

get(),set() 메서드

private으로 선언한 것을 외부 코드에서 사용하려면 ?
값을 얻는 get() getter , 값을 저장하는 set() setter 메서드를 사용.

// private 변수인 studentName에 접근해 값을 가져오는 public get() 메서드
public String getStudentName(){
	return student;
}
// private 변수인 studentName에 접근해 값을 지정하는 public set() 메서드
public void setStudentName(String studentName){
	this.studentName = studentName;
}
psvm(){
	Student studentMun = new Student();
    // setStudentName() 메서드를 홀용해 private 변수에 접근 가능
    studentMun.setStudentName("성준");
    sout(studentMun.getStudentName());

접근 제어자 설명
public 외부 클래스 어디에서나 접근 가능
protected 같은 패키지 내부와 상속 관계의 클래스에서만 접근할 수 있고, 그 외 클래스에서는 접근할 수 없음
아무것도 x default이며, 같은 패키지 내부에서만 접근가능
private 같은 클래스 내부에서만 접근
profile
컴퓨터공학과에 재학중이며, 백엔드를 지향하고 있습니다. 많이 부족하지만 열심히 노력해서 실력을 갈고 닦겠습니다. 부족하고 틀린 부분이 있을 수도 있지만 이쁘게 봐주시면 감사하겠습니다. 틀린 부분은 댓글 남겨주시면 제가 따로 학습 및 자료를 찾아봐서 제 것으로 만들도록 하겠습니다. 귀중한 시간 방문해주셔서 감사합니다.

1개의 댓글

comment-user-thumbnail
2023년 4월 10일

핥짝...

답글 달기