Java 101 Ep06. Objects Oriented Programming- Fundamentals.

Junhyeok Choi·2023년 2월 23일

Java 101

목록 보기
7/10

A만 객체지향 정리하고, 그 중에서도 나는 여기선 클래스에 대해서만 다룰 거임. 여기는 책 쓰는 곳이 아니니 대충 적어라. 메모장마냥 파편처럼 흩어진 프로그래밍 지식에 대해서 history / CS 지식 / Syntax 를 체계적으로 통합하고자 하는 것임. 대충 써. 본질만 쓰자.

package calculator;
// 값을 넣어주는 곳(Front)
public class Ui {

	public static void main(String[] args) {
		Calculator cal = new Calculator();
		int result = cal.sum(10, 20);    //실제 화면
		System.out.println(result);
		cal.save(result);
	}

}

A) History

  • Problem : (1) 과거엔 시스템을 만들고, 그 시스템이 완벽하면 그 전산시스템에 맞춰서 일을 했다. - 즉, 유지보수 어렵고, 경직적 시스템임.
    (2) 스파게티 코드 : 절차지향 언어는 꼬이기 쉽다.

  • Reason : Too big. 코드가 너무 길어서 생기는 문제

  • Basis for Solution : 건축에서 아이디어가 생김. ISO라고 건설을 할 때도 표준화된 자재를 사용하기 시작함. 예전엔 처음부터 아무것도 없는 0에서 코드를 짰지만, CS도 마찬가지로 해보자라는 이야기가 나옴. 1980년대 OOAD(Object Oriented Analysis Designe)이라는 개념이 등장함. 일종의 철학인데, 잘게 쪼개자는 것임.

  • Solution : Java와 UML
    이에 따라 지금까지도 쓰인느 표준화된 UML이 등장. Unified Modeling Language. 분석 표준화된 모델을 지금도 씀. 과거엔 그림을 처음부터 미켈란젤로처럼 그려야했지만, 이제는 미켈란젤로의 완성된 그림을 일부 가져다가 붙일 수 있게 된 것이다. 즉, OOAD는 철학이고, UML은 이를 가능하게 하는 설계도 툴이다.
    1990년대 중반 이를 가능케 하는 순수 100% 객체지향 언어인 Java가 등장하고, Java를 가지고 구현하는 것이 가능해짐. 특히, WWW를 짜는데 특화된 장점이 있었다. 객체의 가장 강력한 장점은 현실세계에 있는 모든 것들을 잘게 쪼개서 SoftWare로 구현해낼 수 있었기 때문임. 대부분의 회사는 이러한 객체 디자인 설계도가 정형화되어있다. 잘 설계된 설계도를 잘 구현되는 것이다. 알고리즘은 이미 다 짜여져있다. 클래스 안에 있는 attribute

객체가 어렵게 느껴지는 이유가 뭘까?

  • 객체라는 말이 매우 추상적인 이야기다. 직관적으로 받아들이기 위해선 그냥 characterized block. 특징 있는 블록 정도로 생각해보는 게 좀 더 직관적일 것이다. 그 블록의 개념이 작을수도 있고 클 수도 있다.

그래서 객체란...

큰 코드를 잘게 잘게 모듈로 쪼개는 것. 그게 객체지향 프로그래밍의 핵심임.
이 잘게 쪼개는 아이디어가 (1) 소량의 코드로 대량생산 (2) 유지보수


B) Computer Science of "CLASS"

Reference : 자바 스트링풀 관련된 소중한 정보
https://jake-seo-dev.tistory.com/17

객체지향은 Java만 가능하다. C++, JavaScript도 객체지향하는 성향이 90% 정도 되지만, 순수 객쳊향은 Java 언어 하나 뿐이다. 그래서 많이 쓰는 것이다.다시 말해서, 현실의 요소는 매우 복잡하다. CS는 이 현실의 요소를 매우 잘게 쪼갠다. 카트라이더에서 사람과 카트가 있다면, 사람 class 와 카트 class 이런식으로 나눈다. 그럼 이러한 설계도 하에서 사람들은 각각의 다양한 instance를 만들어낼 수 있다. 객체 지향에 대한 직관적인 해석은 이렇다.

객체가 가지고 있는 여러가지 성능 중 하나. (1) 대량 생산이 가능.
하나의 클래스(객체)에서 여러가지 인스턴스(객체를 통해 만들어낸 사례)를 대량 생산 가능.
여러가지 클래스는 서로 연관관계를 갖게 되는데 ---> 이 개념이 상속- 포함관계이다.
사실상 핵심은 각 개체의 관계를 배우는 것이 핵심이다.

B- 0) 용어 정리

예를 들어, rx는 instance 변수, a는 argument 변수, k는 local 변수
이런 명칭이 있을 때, 이를 구분하기가 매우 어려운데 이걸 딱 잘라서 이건 뭐 저건 뭐라고 구분하면 너무 어렵다.. 하지만 정말 직관적으로 설명하자면,
클래스 위 필드값 영역에 있는 변수는 instance 변수, argument 변수는 메소드안 변수값. local 변수는 괄호 안에 있는 변수라고 생각하면 대충 직관적으로는 느껴진다. 하지만, 이는 당연히 기능에 따라 다른 거고, 자세한 건 textbook p.374

public final double rx;
public charge ( double a, double b, double c) {
 double k = a;
}

일반적으로, Computer Science는 Property - Value로 나누고, UML에선 속성과 행위로 나눈다 .

클래스는 설계도. -----> 설계도를 바탕으로 만들어지는 것이 인스턴스 객체. 그 설계도에는 속성(attribute)과 행위로 나뉜다.

B - 1) Initialize

왜 초기화를 시켜줘야하는가? 그건 constructor 와 매우 밀접한 관련이 있다. 한마디로, 자바는 memory leak를 방지하기 위해서 초기화를 매번 해준다. 즉, NEW 연산자로 CLASS가 호출될 때마다 CONSTRUCTOR가 초기화해준다. 마치 메소드의 로컬변수처럼.

Why do we need constructor? 객체 생성(new 생성자 호출) and 필드 초기화
In my analysis, It is very simple and straightforward. Object itself doesn't have any meaning unless they are recalled by another objects. Before this chapter, we only tackled with single class hitherto. But, in genral, there is no 'public void string args' method in classes.
(RELATIONS) Therefore, if it is being called by other clasees, it needs to be initialzied in a clean slate. For example, if you have recalled a specific object multiple times, there are many hash memories or heap memories. It should be cleaned up to prevent 'MEMORY LEAK'.

  • Java automatically invokes a constructor when a client program uses the keyord new.


    In the other hand, as for method, when a client invokes a method, the system initializes the argument variables with client values; executes statements until reaching a return statemnt; and returns the computed value to the client, with the same effect as if the method invocation in the client were replaced with that return value.

B - 2) Method의 modifier
static이 무슨 의미일까? 왜 필요할까?

Introduction to Java 에선 이렇게 지칭한다.

Static methods support a key concept that will pervade your approach to programming from this point forward :
Whenever you can clearly seperate tasks within programs, you should do so.

cf. 근데 이게 static이란 게 method의 signature 안에서만 쓰이는 건 아니고, 실제로 알고리즘 짜고 코딩 하다보면, static을 변수에도 지정할 때가 많다. 특히 클래스 내에서 필드 변수값에 static 을 달라고 알람이 올 때가 있는데, 이게 어떨 때냐면...
내가 만약 다른 클래스에서 원하는 특정 클래스의 변수값을 받고 싶으면...꼭 java 알람에서 static을 달라고 나온다.
그러니깐, 일종의 접근자인 셈이다. 우리가 같은 객체끼리는 this. 이라는 accessor를 이용해서 모두 접근하고 정보를 가져왔지. 이 때는 메모리상 this(주소값). 이 담긴다고 말했고, 담기는 장소는 힙 메모리라고 했어.
하지만 다른 객체끼리는 어떨까? 다른 클래스나 다른 객체의 내부 구성요소를 접근하고 싶다면...? 한마디로 옆집 작은 동생을 보고 싶다면, 일반적으론 옆집에 있는 작은 동생아 일루와! 이러면 되지만, CS에서는 이 개념이 아니야. 옆집에 있는 작은 동생 그런 개념이 아니고.
오히려, 이런 상황인 거야. 붕어빵 안에 들어있는 팥을 부르고 싶어! 사실 그 붕어빵 기계로 피자 붕어빵, 슈크림 붕어빵, 치즈 붕어빵 별의별 붕어빵을 만들 수 있잖아. 이해가 좀 되나? 클래스는 클래스 그 자체로는 의미가 없어. 다시 말하지만, 클래스는 기계에 불과하단 말야. 실제로 코드 보면 대부분 그냥 어떻게 argument 변수를 받으면, 이렇게 결과값을 도출할 거야(method 뭉탱이들)라고 정의되어있잖아.
그래서, 붕어빵 기계 그 자체를 아무리 불러봐야 의미가 없는 거지. 사실 붕어빵 기계를 부른 셈인거지. 붕어빵 기계의 구성요소를 부르고 싶다면, 기계로 뭐든지 붕어빵을 찍고 나서 (new 생성자)
그 붕어빵에 있는 팥을 선택해야하는 거야.
예제 1번 lebron처럼 말야.

Class King{
	void methodExample() {
    	System.out.println("Hello! World!");
    }
}

King lebron = new King();
lebron.methodExample(); 

근데 나는 그렇게 하기 싫은 거지.
예제 2번처럼

Class King{
	void STATIC methodExample() {
    	System.out.println("Hello! World!");
    }
}

King.methodExample();  // 오로지 이거 하나만...!

그럼 뭐가 장점이냐? 이거 한 줄 빠진 게 뭐가 장점이냐고? 장점이 아니고 이건 개념이 다른 거야. lebron과 달리 2번의 경우엔 객체 생성 없이 그냥 부를 수 있지. 즉, 언제 어디서든 부를 수 있는 거고, static 을 지정하는 순간. 나는 팥을 부른 게 아니고, 붕어빵 기계의 팥을 넣는 부속품을 직접 선택한 결과를 낳게 돼. 그럴 거면, 그 메소드에 내가 그걸 허락한다 / 안 허락한다를 명시해줘야하지 않을까?

그게 바로 static이야. 그게 만약 변수라면, static variable 그게 만약 method라면 static method 가 되는 거지.

예를 들어, 아래 학원 교재가 너무 잘 정리 되어있어서 이걸로 갈음한다.

그래서, 누군가가 한줄로 static을 설명하라고 하면, static 안 쓰면, 클래스를 불러오고 메소드를 불러와야하는데, static을 쓰면, 그냥 메소드 그대로 불러올 수 있어!


C) Syntax

cf. Public Static void main(String[] args) { };
이 것은 클래스를 실행해주는 효과가 있다. 그래서, 실행해주는 클래스가 아니라면 일반적인 객체에선 굳이 넣어줄 필요가 없다.

C-0) Principle & Structure

It realtes to the derived concepts in D) section.

C-0-0) Structure of Class : 3 PARTS - FIELD, CONSTRUCTOR, METHOD

  • Field : similar to Attribute
    It is very similar to concpets of variables. We call it member field as well. no difference.
    Further study on above.
    For example,
int fieldName;
  • Constructor(declare)
    Further concepts : this. accessor. // Overloading //

  • Method : Functions & Movement.
    I don't have to explain about it that much. It is just method. Similarly, it can be referred to the concepts of 'functions'.

C-0-1) Field

Compared to the local variance and global variance as I have found in JavaScript, concepts are very similar. Of course, It is totally different concepts and languages. But, as far as it has same attributes, I would rather understand FIELD as a global variance.

In my opinion, I think there should be no big difference even though you understand it as gloabl variance.

C-0-2) Constructor

  • 무조건 DEFAULT CONSTRUCTOR는 필수로 선언해줘야한다.
public class Car {
	public Car() { 
	} 
}
  • 무조건 클래스 이름과 동일해야 한다. 무조건 리턴값은 없어야한다. (void랑은 무관함. void는 method의 개념임)
    바로 이 특징 때문에, over-riding 이라는 개념이 나옴.
  • Derived Concepts : this();

C-0-3) Method

In general, method should follow following syntax.

public static int sum (int a, int b) {

}

(1)Accessor / (2) Modifier : static / (3) return type / (4) method name (arguments) {

}

public static int sum (int a, int b) : 이 부분을 signature part라고도 한다. 
{  } 는 method body라고도 한다. 
  • (1) Accessor
    Privte < Protected < Public
    I am not going to describe all these different attributes in this page as I can easily find in textbooks and also can be learned by practices.

  • (2) static or final
    왜 staatic이냐 아니냐에 대해선 많이 내용이 없을까? 간단하기 때문이다.
    클래스안에 비정적 메서드는 'static'을 생략한다. static과 non-static 메서드의 차이점은 간단하다. static 메서드는 객체에 상관없이 호출이 가능하다. 하지만 non-static 메서드는 특정 개체 전체를 대상으로 호출해야 한다. non-static 메서드를 호출하려면 object.method()로 호출, static 메서드는 class.method()로 호출하자.

  • (3) Return Type
    void타입 - 내부적으로 행위가 일어나고 끝나는 경우.
    예를 들어, 회원가입 축하합니다 메일을 보낼 때는 return값이 필요가 없다. 저 사람한테 진짜로 갔는지 안갔는지가 뭐가 중요한가.
    int 타입 / double 타입
    In most cases, we use int, double or void types. But, it differs to given situations.

C-0-4) How to access?

Bottom line is that data types are only two types. primitive type or reference type. Oh, I already knew.! No, You don't.

		for(Employee ar : arr) {
			System.out.println(ar);
		}
        

내가 예를 들어서, App이라는 클래스에서 작업을 하고 있는데, Manager라는 클래스에 접근을 하고 싶다.

(Class 이름) (인스턴스 이름) = new Class 이름(constructor 양식에 맞게)....

C-1) Encapsulation

In a nutshell, the process of sperating clients from implementations by hiding information is known as encapsulation.

  • Computer Science
    To enable modular programming, faciliate debugging, and clarify program code.

Problem : As project engineer relates it class to another class. It can affect or change codes of another class, which deteriorate its security and stability.

Solution : Protect your variables, constructor, and methods if you want.

  • protect constructor : Why do programmers protect their constructors when needed? Think about calendar.

Key of Solution : Access modifier.
Derived concepts : access modifier. It is a key tool to make Java encapsulation.

C-2) How to access?


D) Derived Concepts

D-1) Inheritance

D-2) Field & Constructor : "this." operator and "this( )."method

D-2-1) "this." accessor

Field에선 this. accessor를 쓰고

D-2-2) "this( )." method

위의 constructor를 부르기 위해 쓰는 method. arguments만 괄호 안에 넣어주면 된다.

Constructor에선 this().를 사용한다. 대신 constructor에선 메소드 맨 위에 써야 동일한 constructor를 불러온다.

	public Employee() {
		this.id = "3332223"; //id는 무조건 3332223으로 지정.
	}// basic constructor

	public Employee(String name, double salary) {
		this(); // 위의 constructor가 불러와짐. ---> 바로 이 때 쓰는 메소드
		this.name = name;
		this.salary = salary;
	}
    	public Employee(double salary) {
		this(name); // 위의 2번째 constructor가 불러와짐.
		this.salary = salary;
	}

D-2-1) What does these concepts stand for?

.this가 존재하는 이유는 지칭하기 위해서 존재하고,

this() 메소드가 존재하는 이유는 중복을 제거하기 우해 존재한다.

(1) ".this" accessor
So, basically, It refers to the reference value in Stack. In practice, we use ".this" accessor when we need to make codes clear or put same values to the exact same variance.
For example,

public static int Car(id, color, fuelsize){
	id = id; (x)
   	this.id = id; (o)
}

Basically, I have already magnified the importance of "."accessor to objects. As all the statements are the elements of objects, there should be some pointers. In reality, It is difficult to find a single ".this". It is because "this." accessor are mostly omitted as consoler automatically adds them up.


D-3) Method : Overloading

  • Reasons
    method의 이름이 동일하기 때문에 생긴다. method의 이름은 재활용 가능하다.
    (1) 변수의 이름이 다른 게 중요한 게 아니고, 본질적인 틀이 같은지를 본다.
    아래는 오류 코드이다.
	public static double sum2(int a, int b) {
		return a + b;
	}
	public static double sum2(int c, int d) {
		return c + d;
	}
  • 왜 메소드의 이름이 중복될 수 있도록 허락했을까?
    그렇게 안하면, 기능이 비슷한 메소드 이름을 수백만개 지정해야하기 때문임.
    예를 들어, 계산기 어플을 만든다고 하면, sum에 변수 2개 들어가면, sum2, 3개 들어가면 sum3... 이렇게 수백만개를 지정해야하기 때문임.

Syntax

  • Overloading은 메소드 이름은 같아도 되지만, return 변수 타입은 같아야한다. 예를 들어, public double sum(int a, int b) 와 public int sum(int a, int b)는 불가능하다. return 타입은 같아야 한다.
    근데...public double sum(int a, int b) 와 public int sum (int a, int b, int c)는 다르다.
  • 즉, 조금 세련되게 이야기하면, 메소드 시그니처는 같아야하지만, 오로지 argument만 다른 게 오버로딩이다.




> - 이름만 비슷해서 헛갈릴 수 있는 내용. 하지만, 그냥 다르다. 
Overloading vs Overriding
Over-loading : 
Over-ride : 
Management over-ride 처럼 over-ride는 좀 aggressive 한 개념이다. 

D- 4) Derived concepts : access modifier.--> Key to Encapsulation.

https://wikidocs.net/232

추가적으로 파생되는 개념이 getter 와 setter.
Encapsulation에서 파생되는 개념이 accessor modifier 인데, accessor modifier를 제어하기 위해 생긴 개념이 getter와 setter임.

접근 제어자는 3곳에 쓸 수 있다. < constructor / method / Field >.
사실상 클래스의 어느 파트든 다 쓸 수 있다고 생각하면 된다.
하지만, 흔히 오해하듯, class 앞에 붙은 public 은 접근제어자가 아니다.

Q. Class 앞에 public 이 있는 건 JVM 에서 해석하기 위해서 그냥 붙이는 건가요?
A. 그냥 JVM 에서 해석하기 위해 쓰는 Syntax 일 뿐. 접근제어자는 아니다. 그래서, Class에 private나 protected는 쓸 수가 없다.

하지만, 이 3곳 6모두 사용하는 건 불가능하다.

  • 이렇게 함으로써 다른 부서나 팀에서 우리 메소드를 잘못 가져가는 경우를 원천적으로 막음.

클래스는 보통 private로 선언하고, 그래서, getter와 setter가 필요한 경우는 클래스가 private한 경우다. 4가지 소스 : private < default < protected < public 순인데,
사실 아무것도 안 쓸수도 있다. 그게 default다.

public : 전부 다 어디든지 가능
protected : 같은 패키지까지만
default : protected 랑 비슷하다.
private : 정말 엄청 강력함. 같은 클래스만.

  • modifier를 생략할 수도 있다. 사실은 많은 경우 위의 3가지. 클래스 constructor method에서 접근제어자가 없는 경우를 많이 봤을텐데, 이 경우에는 같은 패키지 안에서만 접근 가능하다. 그걸 default라고 하는데 사실상 생략된 경우를 default라고 한다. (물론, 상속을 선언하면 달라지긴 한다)

  • 이렇게 너무 강력한 modifier들은 다른 클래스에서 불러오려고 하면, 뭔가가 안되는 경우가 많다. 보호는 받아야하지만 유연하게 처리를 하고 싶다면, getter와 setter를 같이 써줘야한다. (모두 private으로 되어있을 때 이렇게 한다)

profile
Just do it jun

0개의 댓글