절차 지향 프로그래밍과 반대되는 말로
(Procedure Programming)
절차 지향은 함수가 코드의 기본 단위가 된다는 말, 그래서 대표적인 절차지향인 C언어에서는
구조체와 함수는 결합할 수 없다 (간접적으로 포인터를 활용하면 가능)
반대로 객체지향 프로그래밍의 특징을 살펴보자면
클래스는 자료형이고 객체는 실제 데이터이기 때문에
하나의 클래스를 이용하여 여러 객체를 생성할 수 있다
public static void main(String[] args) throws Exception {
int n1 = 10;
int n2 = 20;
System.out.println(n1); // 함수를 내장하고 있지 않아서 외부에서 직접 출력함수를 사용해서 처리해야 한다 (println은 n1이라는 변수에 내장된 함수가 아님)
System.out.println(n2);
Process p1 = Runtime.getRuntime().exec("notepad"); // 메모장 실행 프로세스를 저장한 객체 p1
Process p2 = Runtime.getRuntime().exec("mspaint"); // 그림판 실행 프로세스를 저장한 객체 p2
Thread.sleep(2000);
p1.destroy(); // 객체는 스스로 어떤 작업을 수행할 수 있는 함수(메서드)를 내장하고 있다
Thread.sleep(2000); // 어떤 메서드는 객체 없이 클래스에서 바로 호출할 수도 있다
p2.destroy();
}
public class EX02 {
public static void main(String[] args) {
// 클래스를 활용하지 않은 형태로 코드를 진행한다면
String name = "홍길동";
int age = 20;
System.out.printf("이름은 %s이고, 나이는 %d살 입니다\n", name, age);
// 클래스를 활용하여 코드를 진행한다면
// 1) 만들어진 클래스로 객체를 생성
Student st1 = new Student();
// 2) 객체의 멤버 필드는 일반 변수처럼 사용하면 된다
st1.name = "이지은";
st1.age = 31;
// 3) 객체의 멤버 메서드는 객체를 통하여 바로 호출할 수 있다
st1.show(); // 메서드의 내용이 아무리 길어도 호출을 통하여 손쉽게 지시할 수 있다
Student st2 = new Student();
st2.name = "나단비"; // 멤버 필드는 객체마다 다른 속성을 저장할 수 있다
st2.age = 5;
st2.show(); // 같은 메서드를 호출해도 저장된 값이 다르니 결과가 달라진다
}
}
❗기본 생성자 : 매개변수를 전달 받지 않는 생성자
class Product{
String name;
int price;
// 메서드 (상품정보를 간략히 출력하는 기능)
void show() {
System.out.printf("%s : %,d원\n",name, price);
}
// 생성자
Product() {
System.out.println("비어있는 Product 객체 하나 생성");
}
// 생성자는 함수이므로, 오버로딩이 가능하다
// 함수이름이 같아도, 매개변수 타입이 다르거나 순서가 다르다면 여러개 정의할 수 있다
Product(String name, int price){
// 하나의 클래스로 여러 객체를 생성할 때, 현재 작업중인 객체 자기 자신을 가리키기 위해
// this라는 키워드를 사용한다
this.name = name; // 전달받은 이름을 멤버 필드 name에 저장한다
this.price = price; // 전달받은 가격을 멤버 필드 price에 저장한다
System.out.println("데이터를 전달받아서 Product 객체 하나 생성");
}
}
public class Ex03_Constructor {
public static void main(String[] args) {
Product p1 = new Product();
p1.name = "아메리카노";
p1.price = 2000;
p1.show();
// 초기값을 전달하여 객체를 생성했기 때문에, 대입 과정을 생략할 수 있다
Product p2 = new Product("돌체라떼", 4000);
p2.show();
// 자바는 생성자를 호출하지 않으면 객체를 생성하지 않는다
// Product p3 = null;
// p3.show();
// 클래스를 작성할 때, 생성자를 아예 손대지 않으면(만들지 않으면)
// 컴파일 시에 클래스에 기본 생성자 코드를 추가해준다
// 기본 생성자 : 매개변수를 전달받지 않는 생성자
}
}
필드(field)
메서드(method)
생성자
package oop;
class Pos {
// 필드
int x,y;
// 메서드
void show() {
System.out.println("x : " + x + ", y : " + y);
}
// 생성자
// 여기서 this의 3가지 용법
// (this.(member) : 해당 객체의 멤버 호출, this() : 나와 같은 이름의 함수(생성자)
// this : 객체의 참조 주소값 자체)
// 생성자 내부에서 다른 생성자를 호출하기 위해서는 반.드.시 첫번쨰 줄에서만 호출할 수 있다
// why? 생성이 마무리 되고나서 값을 채워주는것이 낫기 때문에
//(만약에 생성이 뒤에 되면 초기값으로 초기화 될 수 있기 때문)
Pos() {
System.out.println("기본 생성자 호출 !!");
}
// Constructor call must be the first statement in a constructor
// 생성자 호출은 반드시 생성자 내의 첫번째 줄에서만 이루어져야 합니다
Pos(int x , int y){
this();
System.out.println("오버로딩 생성자 호출 !!");
this.x = x;
this.y = y;
}
}
public class Ex04 {
public static void main(String[] args) {
Pos ob1 = new Pos(); // 값을 전달하지 않으면
ob1.show(); // 필드의 초기값은 0이다
System.out.println("---------------------");
Pos ob2 = new Pos(3,4);
ob2.show();
}
}
위의 코드를 실행하면 콘솔창은 아래와 같이 뜬다
클래스에 작성된 멤버 요소에 대해 접근할때 그 제한을 설정하는 키워드
접근 제어자에 대한 간단한 코드를 보자
class Test{
private int n1 =1 ;
int n2 = 2;
protected int n3 = 3;
public int n4 = 4;
void show() {
System.out.println("n1 : " + n1);
System.out.println("n2 : " + n2);
System.out.println("n3 : " + n3);
System.out.println("n4 : " + n4);
}
}
public class Ex06_AccessModifier {
public static void main(String[] args) {
Test t1 = new Test();
t1.show();
// The field Test.n1 is not visible
// 공개하지 않았기 때문에, 외부에서 볼 수 없다 (존재하지 않는다라고 하지 않고 보이지 않는다 라고 함)
// System.out.println("n1 : " + t1.n1);
System.out.println("n2 : " + t1.n2);
System.out.println("n3 : " + t1.n3);
System.out.println("n4 : " + t1.n4);
// private 필드의 값은 직접 참조할 수 없다
// 그러나, t1.show()의 형태처럼 [내부 메서드]를 통해서는 접근할 수 있다
// 특정 필드의 값을 반환하는 메서드를 getter라고 한다
// 특정 필드에 값을 대입하는 메서드를 setter라고 한다
// getter와 setter는 접근제한자 개념에 의해 만들어진 요소이고
// 필드는 private, 메서드에는 public을 걸어주는 것이 일반적이다
// 단, 누구나 참조할 수 있어야 하는 static final 필드는 public을 걸어준다
// java.lang.Integer
System.out.println(Integer.MIN_VALUE);
}
}
위의 코드를 보면 System.out.println("n1 : " + t1.n1);을 실행했을때
오류 메세지인 (The field Test.n1 is not visible)이 뜨는 것을 볼 수 있는데
not exist가 아니라 not visible인 것은 위의 Test클래스에 n1은 private처리가 되어있기 때문에
Ex06_AccessModifier 클래스 소속인 메인 메서드는 Test클래스의 n1을 가져 올 수 없다
그러나, private의 특징이 같은 클래스 내에서는 활용이 가능하므로 메서드를 이용해서는 가능하다.