컴퓨터는 노가다에 최적화된 기계고, 그걸 이용하는 사람은 똑똑하고 게을러야한다. (애당초 똑똑하고 게으른 인간이 만든게 컴퓨터 아닌가.) 따라서 문장을 입력할때 중복되는 값은 최대한 줄이고 짧게만 치고싶은게 컴퓨터를 이용하는 사람, 즉 프로그래머의 마인드셋이다. 이걸 우리는 효율성이라고도 부른다.
예시를 한번 들겠다. 메서드를 공부할때 '청소'라는 행위를 예로 들었다.
청소기 돌리기 + 걸레질하기 + 쓰레기 버리기 = 청소
근데 '집안일'이라는 차원에서 접근해보자. 과연 집안일이 청소뿐인가? 아니다, 요리도 있고 빨래도 있고 설거지도 있다.
장봐오기 + 재료 손질하기 + 조리하기 = 요리
더러운 그릇 불리기 + 수세미로 닦기 + 물로 헹구기 = 설거지
청소하고 요리하고 설거지해란 말은 '집안일' 해라로 축약될수 있다. 이게 바로 메서드에서 객체로 넘어가는 순간이다.
똑같은 코드를 여러번 치기 싫어서 반복문을 만들고, 그 반복문도 치기 싫어서 반복문을 묶어 메서드를 만든 우리의 자랑스러운 인간. 근데 메서드도 쌓이고 쌓이니 호출하고 또 호출하고, 그러는게 영 귀찮다. 메서드도 묶어서 이렇다 할만한게 필요하다고 생각했고, 그렇게 나온게 객체다.
(그럼 객체의 반대는 무엇이 될까? 바로 절차이다. C언어의 특징인 절차지향은 데이터, 기능, 함수 등을 합치지 않고 다 따로 둔다. 따라서 단위가 작고 속도가 빠르다.)
객체는 메서드와 변수의 묶음이다. 근데 이 조합이란게 제멋대로 하면 영 거시기하다. 다양한 재료라도 잘 조합하면 월남쌈, 잡채가 되는데 마음대로 조합하면 개밥이 되는것 처럼 우리는 레시피가 필요하고, 그 레시피가 클래스라 보면 되겠다.
객체에서의 변수는 데이터고, 메서드는 기능이다.
사전적 의미 : 물건이나 어떠한 대상
프로그래밍에서의 의미 : 프로그램에서 표현하고자 하는 기능을 묶기 위한 단위
객체 = 데이터(변수,프로퍼티=멤버변수) + 기능(메서드=함수)
클래스와 객체의 관계 : 객체를 생성하기 위해서는 객체의 설계도(클래스)가 필요하다.
<자동차 클래스의 예>
<작성 방법>
class 클래스이름 {
멤버변수;
void 메서드이름() {
...
}
}
<객체의 생성 방법>
// 객체의 선언
클래스이름 객체이름;
// 객체의 할당
객체이름 = new 클래스이름(); // 생성자
// 선언과 할당의 통합
클래스이름 객체이름 = new 클래스이름();
<객체의 사용>
// 객체 안에 포함된 변수의 값을 다른 변수에 복사하는 경우
값 = 객체이름.멤버변수;
// 객체 안에 포함된 변수의 값에 다른 값을 대입하는 경우
객체이름.멤버변수 = 값;
// 객체 안에 포함된 메서드를 호출하는 경우
객체이름.메서드이름(); // this가 안되는 이유
// 객체 안에 포함된 메서드에 파라미터를 전달하는 경우
객체이름.
<실습 01>
class Student {
/** 멤버변수의 선언 + 할당 */
// 문장을 표현할 수 있는 변수형
String name = "자바학생";
int age = 19;
}
public class Main01 {
public static void main(String[] args) {
/** 객체의 선언과 할당의 분리 */
Student std;
std = new Student();
/** 객체의 생성 (일괄지정) */
// Student std = new Student();
System.out.println("이름: " + std.name); // 객체이름.멤버변수 = 값
System.out.println("나이: " + std.age); // 객체이름.멤버변수 = 값
}
}
<멤버변수와 삽질>
<전역변수와 지역변수> - global vs local
<클래스 = 거푸집 이란건 알겠는데 어떻게 쓴다고?>
<클래스와 메서드의 변수를 구분해 봅시다.>
<정의>
<적용방법>
<getter, setter>
멤버변수가 은닉되면 데이터에 접근할 방법이 사라진다. 이는 프로그램의 근본적인 목적인 데이터를 다루는 것에 위반되므로 메서드를 통해 간접적으로 접근하는 방법이 마련되어야 한다.
getter : 은닉된 멤버변수의 값을 리턴하기 위한 메서드 (읽기)
읽어주는 것이므로 return값의 자료형을 지정해주어야한다.
setter : 파라미터로 전달된 값을 멤버변수에 복사하기 위한 메서드 (쓰기)
써주는 것이므로 void를 사용하고, 파라미터값에 데이터 타입을 지정한다.
상속에서 부모클래스를 상속받는 자식클래스를 다루며 심화로 들어갈 내용이다. 부모클래스의 멤버변수에 자식클래스가 접근하기 위해서 쓰는 값, 유전자 같은 개념으로 보면 되겠다.
<실습 01>
class Student {
// 은닉된 멤버변수 --> 현재 블록 안에서만 접근 가능함.
private String name;
private int age;
// 은닉된 멤버변수에 값을 넣는 방법 --> 메서드를 사용
// alt + shift +
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
// 은닉된 멤버변수의 값을 읽는 방법
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class Main01 {
public static void main(String[] args) {
Student s = new Student();
s.setName("JAVA학생");
s.setAge(20);
String name = s.getName();
System.out.println("이름: " + name);
int age = s.getAge();
System.out.println("나이: " + age);
}
}
<클래스와 접근 한정자> - 클래스에 접근 한정자를 지정한 경우
<클래스의 분리 - 접근 한정자의 역할>
<실습 02> - 회원정보를 표현하는 클래스의 작성
public class Member {
private String name;
private int age;
public Member(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/** 하나의 소스파일에는 하나의 public 클래스만 존재할 수 있기 때문에,
* Member클래스를 다른 파이롤 나누어 놓았다. */
public class Main02 {
public static void main(String[] args) {
Member s = new Member("JAVA학생", 20);
String name = s.getName();
System.out.println("이름: " + name);
int age = s.getAge();
System.out.println("나이: " + age);
}
}
public class JavaBeans {
private 자료형 멤버변수명;
public JavaBeans() {} // 생성자
public 자료형 getJavaBeans () { // getter
return 멤버변수명;
}
public void setJavaBeans ( 자료형 멤버변수명 ) { // 지역변수, setter
this.멤버변수명 = 멤버변수명;
}
// toString 포함
@Override
public String toString() {
return "멤버변수명 [ = " + getJavaBeans() + " ] ";
}
이 포스트는 itpaper.co.kr에서 제공되는 강의자료를 바탕으로 작성되었습니다.