~ 4월 8일, 객체지향 프로그래밍
일어나는 일을 시간순으로 프로그래밍
대표적으로, C 언어
객체를 정의하고, 객체 간 협력을 프로그래밍 하는 것
먼저 객체를 만들고 객체 사이에 일어나는 일을 구현하는 것입니다.
따라서, 객체를 먼저 정의하고, 각 객체가 어떤 기능을 제공하고 객체 간 협력을 어떻게 구현할 것인지 고민하는게 keyPoint
객체지향 프로그래밍은 클래스를 기반으로 프로그래밍
클래스는 객체의 속성과 기능을 코드로 구현한 것.
클래스의 이름은 대문자로 시작
문법
(접근 제어자) class 클래스이름 {
멤버 변수;
메서드;
}
클래스에 선언하는 멤버 변수는 다른 말로 속성, 특성으로 표현됩니다.
int studentID;
String studentName;
int grade;
String address;
멤버 변수는 기본자료형 || 참조자료형으로 나뉨.
클래스 내부에서 멤버변수를 사용해서 클래스 기능을 구현한 것을 멤버함수
|| 메서드
라고 합니다.
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까지 더한 값을 반환
}
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
가장마지막에 자료가 가장 먼저 삭제되는 구조이며,
쌓다라는 의미로, 데이터를 차곡차곡 쌓아올린 자료구조.
예) 웹 브라우저 방문기록 (뒤로가기)
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();
위와 같이 생성된 클래스를 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 : 외부 클래스에서 사용가능)
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 | 같은 클래스 내부에서만 접근 |
핥짝...