드디어 객체 에 들어왔다. 객체와 관련된 수업은 굉장히 중요하나, 사실 14일에 열심히 듣지 않은 관계로 지금 이렇게 쓰고 있다
객체지향
객체지향 프로그래밍이란, 현실세계의 객체(사물, 개념)을 클래스(class)와 객체(object)의 개념으로 컴퓨터에서 구현하는 것을 의미한다. 객체간의 상호작용을 프로그래밍으로 만든 것이 객체지향 언어라고 보면 된다.
객체지향의 3대 원칙
캡슐화 상속 다형성
객체
클래스대로 new 연산자를 호출해서 메모리 heap에 적재된 결과물(instance)을 객체라고 한다.
클래스
객체를 정의한 것. 객체의 설계도와 틀. 사물이나 개념의 공통요소를 용도의 맞게 추상화(abstraction)한 것.
코딩에서 추상화는 클래스를 작성하는 것이라고 볼 수 있다.
- 속성(field, attribute) : 정적인 상태
- 기능(method, operation) : 동적인 작동
학생클래스를 통해 이를 더 직관적으로 이해해보자.
public class Student {
// 속성(field)
private String name;
private char gender;
private int age;
// 기능(method)
public void introduce() {
System.out.printf("안녕하세요, 저는 %s입니다. %c자, %d살입니다. 잘부탁드립니다.%n", name, gender, age);
}
// setter
public void setName(String name) {
this.name = name;
}
public void setGender(char gender) {
this.gender = gender;
}
public void setAge(int age) {
this.age = age;
}
// getter
public String getName() {
return name;
}
public char getGender() {
return gender;
}
public int getAge() {
return age;
}
}
public class StudentMain {
public static void main(String[] args) {
// 학생데이터
Student hong = new Student();
// 속성대입
// hong.name = "홍길동";
// hong.gender = '남';
// hong.age = 20;
hong.setName("홍길동");
hong.setGender('남');
hong.setAge(20);
// 기능호출
hong.introduce();
Student sin = new Student();
// sin.name = "신사임당";
// sin.gender = '여';
// sin.age = 22;
sin.setName("신사임당");
sin.setGender('여');
sin.setAge(22);
sin.introduce();
}
}
new를 통해서 student() 클래스를 부르고, 그 안에있는 속성(field)과 기능(method)을 사용하여 여러명의 학생 정보를 입력하고 불러낼 수 있다. (무제한 사용이 가능)
캡슐화 (encapsulation)
캡슐화란, 추상화를 통해 정의된 데이터와 기능들을 하나로 묶어 관리하는 기법이다.
클래스 외부에서의 데이터 직접 접근을 막고, 대신 데이터를 처리하는 함수(method)들을 클래스 내부에 작성해 데이터에 접근하는 방식이다.
캡슐화의 원칙
field : 클래스의 멤버 변수에 대한 접근 권한은 private
method : 클래스 멤버 변수에 대한 연산처리를 하는 method를 클래스 내부에 작성하고, 이 클래스는 외부에서 접근할 수 있도록 public으로 설정한다.
은행계좌 class를 통해 이를 직관적으로 이해해보자.
public class Account {
// 필드의 접근제한자 private - 클래스 내부에서만 접근이 가능
private String name;
private long balance;
/**
* 입금 메소드
*/
public void deposit(long money) {
if(money > 0)
balance += money;
else
System.out.println("입금액이 유효하지 않습니다.");
}
/**
* 출금 메소드
*/
public void withdraw(long money) {
if(money <= balance)
balance -= money;
else
System.out.println("잔액이 부족합니다.");
}
/**
* getter
*/
public String getName() {
return this.name;
}
public long getBalance() {
return balance;
}
/**
* setter
*/
public void setName(String name) {
this.name = name;
}
public void setBalance(long balance) {
this.balance = balance;
}
}
this
this는 현재 객체를 가리키는 숨은 참조 변수이다.
getter와 setter
getter
- get + 대문자로 시작하는 필드명
- 매개변수 없음
- 리턴타입과 필드타입과 동일
setter
- set + 대문자로 시작하는 필드명 userId -> setUserId
- void
- 매개변수
public class AccountMain {
public static void main(String[] args) {
Account acc = new Account();
// acc.name = "홍길동";
// acc.balance = 1_000_000;
acc.setName("홍길동");
acc.setBalance(1_000_000);
System.out.printf("%s님의 계좌 잔액은 %d원입니다.%n", acc.getName(), acc.getBalance());
// 1.구조체처럼 사용(캡슐화 적용전)
// 구조체의 속성에 직접 접근해서 처리하기 때문에 문제가 생길수 있다.
// 입금
// acc.balance *= 500_000;
// acc.balance += -500_000;
// System.out.printf("%s님의 계좌 잔액은 %d원입니다.%n", acc.name, acc.balance);
// acc.balance -= 3_000_000;
// System.out.printf("%s님의 계좌 잔액은 %d원입니다.%n", acc.name, acc.balance);
// 2. 캡슐화 적용후
// acc.deposit(500_000);
acc.deposit(-500_000);
System.out.printf("%s님의 계좌 잔액은 %d원입니다.%n", acc.getName(), acc.getBalance());
acc.withdraw(500_000);
acc.withdraw(5_000_000);
System.out.printf("%s님의 계좌 잔액은 %d원입니다.%n", acc.getName(), acc.getBalance());
}
}
1. 구조체처럼 사용할 경우 private이기 때문에 데이터에 직접 접근할 수 없다.
2. Account에서 데이터를 public으로 해서 데이터를 변경 가능할 경우, 데이터가 계속 바뀌는 문제가 생긴다.
3. 캡슐화 적용 후 입출금메소드(method)만 사용 가능한 것을 확인할 수 있다.
클래스의 접근제한자
.java파일 안에는 단 하나의 public class만 존재할 수 있다.
public : 모든 패키지에서 접근가능(import문 사용시 어디든지 사용 가능)
default : 같은 패키지에서만 사용 가능
다음과 같은 구조에서, 확인해보면 쉽다.
package kh.java.oop.access.modifier._class;
public class A {
}
class B {
}
UML 다이어그램
- private
+ public
~ default
# protected
밑줄 static
UML다이어그램을 통해 쉽게 class를 이해하고 의사소통 할 수 있다.
위 사진과 같은 양식을 가지는 것을 잊지 말자.
다이어그램 작성을 위해 starUML을 다운로드하자.
오늘은 객체에 들어가면서 많은 것들을 배웠다. 이제부터 집중 초 집중이 필요할 것 같다.