|  상속 (재사용 + 확장)

- 부모 - 자손의 상속 관점 보다는, 재사용과 확장으로 접근하는 것이 좋다

- 상속은, 상위 클래스의 특성을 하위 클래스에서 재사용하고, 거기에 덧붙여 확장할 수 있는 것을 말한다.

- 관계 : 상위 - 하위 / 슈퍼 - 서브

   * 상위로 갈수록 추상화, 일반화되며

   * 하위로 갈수록 구체화, 특수화된다. 

- 상속을 표현하는 문장 

구분 - 설명
포함 has a 클래스 내에서 인스턴스를 형성하여 사용
상속 is a kind of 클래스를 extends (확장하다)
구현 is able to 인터페이스를 implements (구현하다)

- 오버라이딩 : 상속 관계에 있는 상위 클래스로부터 물려 받은 메소드를 재정의한 것

 

|  상속의 장단점

장점 - 모듈화*를 통한 재사용
- 유지보수가 쉽고, 개발 시간이 단축된다.
- 코드가 통일성이 있고 간결해진다.
단점 - 상속 시 기능을 추가하고 변경할 때 버그가 발생하면 전반적인 검토가 불가피하다.
- 불필요한 기능까지 상속해야하는 경우가 있다. (특히 인터페이스의 경우)
- 상위 클래스의 구현이 하위 클래스에게 노출될 경우 캡슐화 원칙을 위반할 수 있다.
  ==> 강한 결합도 발생 

* 모듈화 : 소프트웨어를 각 기능별로 나눈 단위. 여기에서는 객체화로 보아도 무방하다.

 

|  결합도와 응집도

- 상속에 대한 이야기를 할 때 자주 나오는 이야기가 결합도와 응집도인 것 같다.

- 결합도와 응집도란 그럼 뭘까?

결합도 응집도
서로 다른 모듈 간에 상호 의존하는 정도 또는 연관된 관계 한 모듈 내부의 처리 요소들이 서로 연관되어 있는 정도
A - B 간에 결합도가 높을 경우,
- A를 변경하면,  B도 변경해야 한다.
- A를 변경한 후, B를 다른 코드에서 재사용하기 어렵다
A안에 a1, a2, a3 메소드들이 있다고 할 때,
각 메소드들이 A안에서 책임이 잘 뭉쳐져 있어
A가 독립적인 모듈로써 기능할 때 응집도가 높다고 한다.

 

상속에서는 여러 개의 하위 모듈이 하나의 상위 객체로부터 공통의 메소드를 사용하거나, 참조하기 때문에 지나치게 결합도가 높은 경우에는 차후에 수정을 할 때에 어려움이 발생할 수 있다. 

- 또한 상위 객체에서 접근제어자와 겟터(getter)/셋터(setter) 등으로 정보에 대한 접근을 제한하지 않았다면, 캡슐화(정보은닉)의 원칙도 깨어질 우려가 있다. 잘못하면 상속 후 하위 객체에서 상위 객체의 데이터에 접근을 할 수 있기 때문이다.

- 따라서, 상속 시 사전에 결합도와 응집도를 충분히 고려하는 게 필요하다.

 

|  상속시 메모리구조

- new 객체명() 를 통해 인스턴스를 생성할 때, 상속을 받은 경우, '나' 뿐만 아니라 '상위' 인스턴스도 함께 힙에 생성된다.

Static : 클래스 정보
Stack :
main() -> 하위 생성자 호출
Heap : 
하위 인스턴스, 상위 인스턴스

 

|  UML 표현 (출처 : https://gmlwjd9405.github.io)

(1) Logical

출처:https://gmlwjd9405.github.io/2018/07/04/class-diagram.html

(2) Physical

출처:https://gmlwjd9405.github.io/2018/07/04/class-diagram.html

 

|  상속을 표현한 코드

 

동물은 이름(name)과 나이(age)가 있으며, 자신을 소개(introduce)할 수 있다.

 

 '포유류'는 동물이다. (상속)

- Mammal is a kind of Animal.

 

포유류는 다른 동물처럼 이름과 나이가 있고, 자신을 소개할 수 있다.

포유류의 포유류의 평균 최대 수명(MAX_AGE)을 갖고 있다.

 

포유류는 자신을 소개할 때, 포유류의 평균 최대 수명을 함께 소개한다.

 

package inheritance;

// 동물
public class Animal {
    String name;
    int age;

    Animal () {}

    Animal (String name, int age) {
        this.name = name;
        this.age = age;
    }

    void introduce(){
        System.out.println("Hi, my name is " + name + ", and i am " + age + "years old.");
    }
}

// 포유류 
class Mammal extends Animal{
    final int MAX_AGE = 268;

    void introduce(){
        System.out.println("Hi, my name is " + name + ", and i am " + age + "years old.");
        System.out.println("I can only live MAX : " + MAX_AGE);
    }
}

// 파충류
class Reptile extends Animal{
    final int MAX_AGE = 20;

    void introduce(){
        System.out.println("Hi, my name is " + name + ", and i am " + age + "years old.");
        System.out.println("I can only live MAX : " + MAX_AGE);
    }
}

 

|  또다른 예시 코드

package inheritance;

class Vehicle {
	
	String name;
	double maxSpeed; 
	int maxCapacity;
	
	public Vehicle() {}
	
	public Vehicle(double maxSpeed, int maxCapacity) {
		super();
		this.maxSpeed = maxSpeed;
		this.maxCapacity = maxCapacity;
	}


	public void info() {
		System.out.println("== vehicle info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
	}
}

class Car extends Vehicle{
	
	final String name = "car";
	int gasDisplacement; // 배기량
	
	public Car() {}
	
	public Car(int gasDisplacement) {
		super(430,100);
		this.gasDisplacement = gasDisplacement;
	}

	public void info() {
		System.out.println("== Car info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
		System.out.println("gasDisplacement : " + gasDisplacement);
	}
}

class Train extends Vehicle{
	
	final String name = "train";
	final static String[] ALL_LINES = {"경부선", "호남선", "전라선", 
                                           "중앙선", "경의선", "경의선"}; // 나머지 생략  
	String line; // 노선
	
	public Train() {}
	
	public Train(String line) {
		super(330, 1000);
		this.line = line;
	}

	public void info() {
		System.out.println("== Train info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
		System.out.println("line : " + line);
	}
}

class Airplane extends Vehicle{
	
	final String name = "airplane";
	String departure;
	String arrival;
	
	public Airplane() {}
	
	public Airplane(String departure, String arrival) {
		super(1000, 200);
		this.departure = departure;
		this.arrival = arrival;
	}

	public void info() {
		System.out.println("== vehicle info ==");
		System.out.println("name : " + name);
		System.out.println("maxSpeed : " + maxSpeed);
		System.out.println("maxCapacity : " + maxCapacity);
		System.out.println("departure : " + departure);
		System.out.println("arrival : " + arrival);
	}
}

-- 테스트 코드

package inheritance;

public class Test {
	public static void main(String[] args) {
		Car car = new Car(1000);
		car.info();
		System.out.println();
		
		Train train = new Train(Train.ALL_LINES[1]);
		train.info();
		System.out.println();
		
		Airplane air = new Airplane("Seoul", "Reykjavik");
		air.info();
		System.out.println();
	}
}
== Car info ==
name : car
maxSpeed : 430.0
maxCapacity : 100
gasDisplacement : 1000

== Train info ==
name : train
maxSpeed : 330.0
maxCapacity : 1000
line : 호남선

== vehicle info ==
name : airplane
maxSpeed : 1000.0
maxCapacity : 200
departure : Seoul
arrival : Reykjavik

 

[참조]

스프링 입문을 위한 자바 객체 지향의 원리와 이해

https://madplay.github.io/post/coupling-and-cohesion-in-software-engineering

https://gmlwjd9405.github.io/2018/07/04/class-diagram.html

https://sujl95.tistory.com/32

 

 

|  추상화 (모델링)

- 현실 세계의 객체에서 필요한 부분만 뽑아 클래스로 만드는 작업을 말한다.

추상화란 구체적인 것을 분해하여 관심 영역에 있는 특성만 가지고 재조립하는 것(= 모델링)

[출처] 스프링 입문을 위한 객체 지향의 원리와 이해

 

|  추상화가 모델링인 이유

관심 영역(앱의 경계)에 따라 클래스 모델링이 달라진다.

- 현실 세계에서 물리적으로는 동일한 실체에 대해서도 관심 영역(여기서는 애플리케이션에 적용할 영역)이 어디냐에 따라서, 클래스 모델링이 달라진다.

Ex. 사람(객체)을 동물로 본다면 "다리 갯수", "자손 생식 방식" 등을 보겠지만, 고객으로 본다면 "연령대", "지출금액" 등을 볼 것이다.

 

|  추상화의 예시

[1] 상속을 통한 추상화와 구체화

- 상속 관계에서 상위 클래스로 올라갈 수록 추상화/일반화가 이루어지며,

- 상속 관계에서 하위 클래스로 내려갈 수록 구체화/특수화가 이루어진다.

 

[2] 인터페이스를 통한 추상화

- 인터페이스를 통해 공통된 메소드를 하나로 묶어 주는 것도 추상화이다.

- 예시 ) Map 인터페이스로부터 파생된, Hashtable과 HashMap

   * 두 객체는 기능적으로 거의 유사하지만 차이를 보인다.

   * Hashtable의 경우 key에 null을 넣을 수 없지만 HashMap은 가능하며, Hashtable은 HashMap과 달리 멀티 쓰레드 환경에 우수하다.

// Map 인터페이스로부터 구현된 클래스들

// 1. Hashtable
Hashtable<Integer, Integer> ht = new Hashtable<>();
ht.put(0, 10);
System.out.println(ht.get(0));

// 2. HashMap
HashMap<Integer, Integer> hm = new HashMap<>();
hm.put(0, 10);
System.out.println(hm.get(0));

 

|  UML 표현

- 앞에서 잠깐 언급했던 '사람'을 토대로 간단한 클래스 다이어그램을 만들면 아래와 같다.

Logical Physical

사람
이름
국가
연령
인사하다()
Person
+ name : String
+ nationality : String
+ age : int
+ sayHello() : void

 

 

[참조]

- [스프링 입문을 위한 자바 객체 지향의 원리와 이해], 김종민

- 기타 블로그

|  객체지향 프로그래밍 / 절차지향 프로그래밍

  절차 지향 프로그래밍(PP) 객체 지향 프로그래밍(OOP)
특징 일련의 동작(모듈, 함수)를 순차적으로 실행 객체(속성 + 기능) 간의 상호작용을 이용
포커스 명령어의 순서와 흐름 데이터의 속성(필드)과 기능(메서드)
장점 컴퓨터의 처리구조와 비슷해 속도가 빠르다 재사용성(상속), 유지보수 용이, 자연스러운 모델링*
단점 규모가 커질 수록, 추가 개발 및 유지보수 어려움 느린 개발 속도와 실행 속도. 높은 난이도

 

* 객체지향 프로그래밍은 하나의 방법론이지, 그것이 언어나 제품을 의미하는 것은 아니다.

* OOP나 PP 외에 CBD(Component-based development), SOA(Service-orient development)등 프로그래밍 방법론은 많다.

* OOP가 방법이라면, 자바는 언어이고, 스프링 프레임워크는 일종의 제품이다.

* OOP의 장점 중 자연스러운 모델링이라는 것은, 현실 세계와 가깝게 자연스러운 구현이 가능하다는 의미

 

[참조] 기계어 -> 어셈블리어 -> 컴파일언어(C언어) -> 자바 -> 스프링 프레임워크

더보기

- 기계어 : 0과 1의 나열이며, 컴퓨터 기종마다 쓰는 방식이 다르다.

  - 기계어는 컴퓨터를 움직이는 명령 소스 그 자체이다.

 

- 어셈블리어 : 기계어를 니모닉(ex.ADD)을 통해 사람이 이해할 수 있는 단어로 변경한 언어.

  - 슬프게도 이 또한 컴퓨터 기종마다 쓰는 단어가 다르다.

  - 다만 어셈블리어는 기계어와 1 : 1 로 대응하기 때문에 명령시 반응은 즉각적.

 

- 컴파일어 : 수학적인 기호를 통해 코딩을 하면, 그걸 컴파일하여 기계어로 번역하는 언어.

    "One Source, Multi Object, Use Anywhere"

   - 컴퓨터 기종과 상관없이 동일한 소스 코드를 사용

   - 그렇지만 운영체제에 따라 자료형 타입 크기가 달라지는 단점이 있다. 

     (ex. C언어의 int -> 어떤 OS는 int를 2바이트로 규정, 어떤 OS는 int를 4바이트로 규정)

 

- 객체지향 언어(C++, 자바...) 

  "One Source, One Object, Use Anywhere"

  - C++는 객체지향언어이지만, 객체지향이 아니게 사용될 수도 있다.

  - 자바에서 JVM을 통해 컴퓨터 기종과 상관없으며, 운영체제와도 상관없이 동일한 소스코드를 쓸 수 있게 됐다.

  * JVM은 말그래도 가상머신, 가상의 메모리 공간이다. 가상공간을 만들면 아무래도 메모리 소비는 더 많을 것.

     (JVM 사용에 따른 메모리 소비량은 그러나 하드웨어 기술이 발전함에 따라 사실상 큰 의미가 없어졌다)

 

- 스프링 프레임워크

  - POJO(Ioc/DI + PSA + AOP)를 통해 OOP를 일관성 있게 개발할 수 있는 프레임워크 제공

 

|  자바 프로그램의 구동

1. 자바와 가상 머신

- 자바 프로그램은 가상머신 안에서 구동되는 프로그램이다.

- 현실 세계의 하드웨어가 자바 가상 머신으로 옮겨졌다고 보면 된다.

- 가상 머신을 통해서 OS에 독립적인 실행이 가능해진 것이다.

- 일반 하드웨어와 JVM이 메모리를 사용하는 방식

(1) 일반 하드웨어 : 코드 실행 영역 + 데이터 저장 영역

(2) JVM : 코드 실행 영역 + [스태틱 영역 + 스택 영역 + 힙 영역]

현실  가상 동작
소프트웨어 JDK (개발 도구) 개발자는 JDK 환경에서 자바로 코드를 짠다 
운영체제 JRE (실행 환경) JRE가 JVM에서 프로그램을 돌린다
하드웨어 JVM (가상 머신) 가상의 컴퓨터다. 

 

2. 구동 순서

(1) 전처리 : 스태틱 영역에, java.lang패키지를 넣고, 모든 import 패키지와 클래스를 넣는다.

(2) 스택 : 메인 메소드(변수 x = 10) -> 다른 메소드 -> 다른 메소드...

(3) 힙 : 배열, 인스턴스 ..... (중간중간 힙 사용)

 

|  객체

- 객체란? 세상에 존재하는 모든 사물(Object)

- 클래스(분류)와 객체(실체)를 구분하는 것 : 클래스는 분류, 객체는 유일무이한 실체

  "쫀떡이, 나이가 몇살이니?" --> 고양이는 클래스, 쫀떡이는 객체 

객체 속성 (= 변수) 특성 및 상태 
행위 (= 메소드) 동작 또는 행위 

 

|  객체 지향의 4대 특성

캡슐화 정보 은닉
상속 재사용과 확장성
추상화 모델링
다형성 사용 편의

 

|  객체 지향의 5가지 원칙 - SOLID

SRP(Single Responsibility Principle) 단일 책임 원칙 작성된 클래스는 단 하나의 기능을 가지며,
모든 서비스는 하나의 책임을 수행하는데 집중돼야 한다.
OCP(Open-Closed Principle) 개방 폐쇠 원칙 소프트웨어의 구성요소(컴포넌트, 클래스, 모듈, 함수)는
확장에는 열려 있고, 변경에는 닫혀 있어야 한다.
LSP(Liskov Substitution Principle) 리스코프 치환 원칙 상위 타입의 객체를 하위 타입으로 바꾸어도
프로그램은 일관되게 동작해야 된다
ISP(Interface Segregation Principle) 인터페이스 분리 원칙 클라이언트는 이용하지 않는 메소드에 의존하지 않도록
인터페이스를 분리해야 된다
DIP(Dependency Inversion Principle) 의존 역전 법칙 클라이언트는 추상화에 의존해야 하며,
구체화에 의존해선 안된다

 

 

[참조]

- [스프링 입문을 위한 자바 객체 지향의 원리와 이해], 김종민

- https://www.nextree.co.kr/p6960/

- https://velog.io/@hanjoon_10/OOP-vs.-PP

|  개발 환경 구축

(1) 자바 환경 구축

- 자바는 JVM을 통해 모든 플랫폼(OS)에서 독립적으로 작동한다.

- 오라클사에서 JDK를 다운할 수 있다.(또는 openJDK 사용) 설치 사이트 바로가기

- 명령프롬프트(CMD)로 설치 환경 확인

- 시스템 환경 변수 설정

변수명 경로 예시
Path java.exe가 있는 경로 %JAVA_HOME%\bin
JAVA_HOME jdk폴더 경로 C:\myDev\jdk1.8.0_333

rf. 코딩 폰트 설치하기 : d2coding, jetbrains mono 폰트

rf. 맥에서 자바 설치하기 : [1] homebrew 설치 [2] 터미널에서 자바 설치

 

더보기

[ 시스템 환경 변수 - Path는 왜 넣는 걸까? ]

 

운영체제(OS)가 프로세스를 실행할 때 참조하는 값을 환경 변수라고 한다.

환경 변수에는 여러가지가 포함될 수 있는데, 이 중에서 Path는  말그대로 "경로"를 말한다.

Path를 통해서 한 번 경로를 입력해 두면, JDK 실행을 호출할 때 OS가 알아서 Path에 저장된 값를 참조한다.

 

※ 출처 : https://seol2.tistory.com/141

 

(2) 컴파일 및 실행

- 컴파일 및 실행과정

start ----------------> compiled ---------------> result
소스파일.java 컴파일러 : javac.exe 바이트코드 인터프리터 : java.exe 실행결과
class Main { //코드 } javac HelloWorld.java 000111101010001010...... java HelloWorld 안녕!

- 명령프롬프트 활용

- 에디터(IDE) 활용

에디터명 개인적인 비교 다운경로 사용자수 (*jlab 설문결과)
IntelliJ - 말끔한 UI
- 상세한 가이드 (ex. 메소드의 매개변수까지 자동 안내)
바로가기 약 40%
Eclipse - 각종 단축키를 활용하여 빠른 코딩 가능
  (ex. 만능해결사 ctrl + space)
- 워크 스페이스 구조를 상세히 안내
- 다소 올드한 UI와 복잡한 설정
바로가기 약 30%
Visual Studio - 과거에 자주 사용되던 에디터
- 다양한 플러그인을 사용할 수 있다
바로가기 그 외
이클립스를 설치하면 가장 먼저 해야할 것 : 인코딩 타입을 MS949 -> UTF-8로 바꾸어준다.
( 위치 : [Windows] - [Preference] - search : encoding, Workspace/CSS/HTML/JSP/XML 모두 UTF-8로 설정)
IntelliJ나 이클립스나 내장된 openJDK를 사용할 수 있다. * 되도록 오라클에서 JDK 설치 후 사용 권장
(단, IntelliJ는 openJDK를 선택해서 설치해야 한다. 이클립스는 기본적으로 설치된 openJDK가 있다)
이클립스 프로젝트에 JDK 경로 설정하기 (아래 '더보기' 선택)  

 

|  자바 확장자와 파일

구분 확장자 내용
자바 파일 소스파일.java, 바이트코드.class 소스코드, 이진코드
자바 아카이브 압축명.jar 패키지 포맷
: 자바코드 + 리소스 + 메타데이터 + 기타 
웹 아카이브 압축명.war 웹 패키지 포맷
: 서블릿 + JSP + 리소스(html,js,css...) + ...
엔터프라이즈 아카이브 압축명.ear application server에 배포하기 위해 jar과 war을 묶어놓은 파일

 

|  자바 구조와 문장

패키지 (선택) 첫글자 소문자로 표기, ' . '을 통해 상세 경로를 나타낸다. package java.util.Random
클래스 첫글자 대문자로 표기, 그 외는 식별자* 명명법을 따른다. class Main
    // 필드
    // 메소드
}

 

* 예약어 : 예약어는 이미 정의된 것 (ex. 기본형 변수, if/while.... )

* 식별자 : 사용자가 지정한 것 (대소문자 구분, 첫문자 숫자 불가, 공백사용 불가, 특수문자 $, _만 가능, 한글 사용 가능)

 

|  클래스

클래스 필드 변수 기본형 논리형/문자형/정수형/실수형
참조형 참조값(16진수의 주소)을 담는 변수
초기화블럭 변수 선언 및 초기화 후, 초기화 블럭을 통해 재초기화*
메서드 생성자 인스턴스 생성 시, 생성자 안에 인자를 넣어 변수 초기화 
일반 메서드 매개변수와 반환값을 갖는다
접근제어자* +, (default) all  

 

* 사용하는 접근제어자 표시 : all(모두 사용가능), +(public), #(protected) , (default), -(private) 

* 초기화 블럭 : static이 들어간 경우 클래스가 로딩될 때, 그렇지 않은 경우 인스턴스가 생성될 때마다 초기화를 한다. (일반적으로 리소스를 업로드할 때 쓴다.)

 

|  변수와 자료형

변수 구분 크기 범위 기본값
기본형 논리형 boolean 1byte false, true false
문자형 char 2byte 0 ~ 약 6만 '\u0000'
정수형 byte 1byte -128 ~ 127 0
short 2byte 약 -3만~약 3만 0
int 4byte 약 -20억 ~ 약 20억  0
long 8byte   0L
실수형 float 4byte   0.0f
double 8byte   0.0
참조형 -   JVM 크기에 따름
32bit(4byte)
/64bit(8byte)
  null

- 정수형에 대한 자세한 설명 (아래 '더보기')

더보기

(1) 진수 표현

int n10 = 10;   //10진수
int n2  = 0b10; // 2진수
int n8  = 010;  // 8진수
int n16 = 0xff; //16진수

// JDK 1.7부터는 '_'를 통해 자릿수를 표기할 수 있게 됐다.
n2 = 0b0000_0000_0000_0000_0000_0000_1010;

 

(2) 2진수의 음수 표현 (2의 보수)

//2의보수 [앞에서 마지막 전까지 반대, 마지막은 동일]
int n1 = 0b0000_0000_0000_0000_0000_0000_0000_1100; //12
int n2 = 0b1111_1111_1111_1111_1111_1111_1111_0100; //-12

//n1 + n2은 아래와 같다.
int n3 = 0b0000_0000_0000_0000_0000_0000_0000_0000; //0

(3) long과 short/byte

// short와 byte는 사칙연산 시 int로 반환된다. (내장된 연산장치가 int 단위로 반환하기 때문)
short n1 = 1;
short n2 = 2;
int res = n1 + n2;

// long의 표현
long n3 = 1L;

- 오버플로우와 언더 플로우

(1) 오버플로우 : 자료 범위를 넘어서 양수가 음수로 바뀌는 경우

(2) 언더플로우 : 자료 범위를 넘어서 음수가 양수로 바뀌는 경우

 

더보기
public class Test {
    public static void main(String[] args) {
        //int n = 30_0000_0000; --> 에러! 
        int n1 = 0b0111_1111_1111_1111_1111_1111_1111_1111; //int 최댓값 / int범위 : -2^31 ~ (2^31 - 1)
        int n2 = 0b1000_0000_0000_0000_0000_0000_0000_0000; //최댓값에 2진수 1을 더한 값
        System.out.println("n1 = " + n1); //n1 = 2147483647
        System.out.println("n2 = " + n2); //n2 = -2147483648 ---> 오버플로우

        int n3 = n2 - 1;
        System.out.println("n3 = " + n3); //n3 = 2147483647 ---> 이처럼 음수가 양수로 바뀌는 경우는 언더플로우

    }
}

- 문자형 : 유니코드에 따라 문자를 나타낸다

char c1 = '\u0000'; 
char c2 = '\uac00'; //'가'
//참조 : 한글 유니코드(UTF-8) https://jjeong.tistory.com/696

- 변수 표기법

표기법 어디에? 예시
파스칼 자바 : 클래스
c# : 변수, 클래스
class Car { }
Date, LocalDate, String, Scanner
카멜 자바 : 변수, 메소드 int speed, void speedTest(){}
스네이크 - 소문자 c, php void speed_test(){}
스네이크 - 대문자 SQL문법
자바 : 상수
SELECT * FROM member
final int MAX_SPEED
헝가리언  과거 변수 타입을 구분하기 위해 사용 int iMaxSpeed; int strUsername
케밥 html : class 구분
url 주소 표준 : '-'로 구분
<div class = "list-imgtxt">
http://www.naver.com/board-list //"_"가 아닌 "-"가 표준

 

|  연산자와 피연산자

- 단항 > 사칙연산 > 비교 > 대입, 크게 4가지의 방향으로 이해

- 아래의 어떤 연산자 보다도 가장 우선순위가 높은 것은 "(   )"

우선순위 연산자 이름 연산자 연산 방향
1 후위 단항 i++, i-- 왼쪽에서 오른쪽
2 전위 단항 ++i, --i, +val, -val, !
3 곱셈/나눗셈/나머지 *, /, %
4 덧셈 +
5 비트이동 >>, <<, >>>
6 관계 >, <, <=, >=, instanceOf
7 동등 ==, != 
8 비트 AND &
9 비트 배타적 ^
10 비트 OR |
11 논리 AND &&
12 논리 OR ||
13 조건 삼항 (조건) ? (참) : (거짓) 
14 대입 =, +=, -= .... 오른쪽에서 왼쪽

 

- 비트 연산자

연산자 이름 사용 의미
& 비트 AND op1 & op2 비트가 모두 1이면 결과는 1, 아니면 0
^ 비트 배타적 op1 | op2 비트가 적어도 하나가 1이면 결과는 1, 아니면 0
| 비트 OR op1 ^ op2 비트가 서로 다르면 결과는 1, 같으면 0
~ 보수(complement) ~op1 비트가 0이면 결과는 1, 0이면 1
// 2의 보수를 구하는 법
int i1 = i2;
int i2 = ~i1 + 1; //~ : 1의 보수, 1을 더하면 : 2의 보수

 

- 비트 이동

연산자 이름 사용 의미 비고*
>> signed left shift op1 >> op2 [기존부호] 오른쪽으로 op2비트만큼 이동 = op1 * 2^op2
<< signed right shift op1 << op2 [기존부호] 왼쪽으로 op2비트만큼 이동 = op1 / 2^op2
>>> unsigned left shift op1 >>> op2 [0으로 채움] 오른쪽으로 op2비트만큼 이동  

* 단, 변수의 Max크기까지만 가능하다. (ex. int 범위는 ~ 2^32까지)

 

- 형변환

(1) 자동 형변환 : 작은 범위에서 큰 범위의 자료형에 값을 넣을 때

(2) 명시적 형변환 : 큰 범위에서 작은 범위의 자료형에 값을 넣을 때. ex. int num = (int)(5/1.0);

 

- 연산 관련 예외

(1) ArithmeticException : (런타임 에러) 정수를 0으로 나눌 때

(2) Infinity : 실수를 0.0으로 나누면 무한대 

(3) byte와 short 산술 연산 : 모두 int로 변환되어 연산 수행

 

|  제어문과 반복문

구분 이름 코드 비고
제어문 조건문 if, if~else 자바는 if~else if~else가 없다
스위치문 switch~case default
반복문 - for, foreach
while, do while
break와 continue

 

■ 응집도와 결합도

https://medium.com/@jang.wangsu/%EC%84%A4%EA%B3%84-%EC%9A%A9%EC%96%B4-%EC%9D%91%EC%A7%91%EB%8F%84%EC%99%80-%EA%B2%B0%ED%95%A9%EB%8F%84-b5e2b7b210ff

 

[설계 용어] 응집도와 결합도

High Cohesion, Low Coupling, 응집도와 결합도 라는 설계관련 용어는 프로그래밍에 익숙하지 않은 사람들에게는 쉽게 익숙해지기가 처음에는 어려울 것 같아요.

medium.com

- 자바 스터디 그룹에서 매일 배운 내용을 돌아가며 요약하고 발표하고 있다.

- 최근 인터페이스를 다루었었는데, 그 때 응집도와 결합도에 대한 이야기가 나왔다. 정확히 무슨 말인지 이해가 가지 않았는데, 오늘 이에 대해 다시 이야기를 나누면서 자료를 찾아보니 이해가 조금 가게 된 것 같다.

 

[ 응집도와 결합도는 설계 용어이다 ]

- 모듈이란 클래스나 패키지, 라이브러리와 같이 프로그램을 구성하는 임의의 요소를 말한다.

- 좋은 설계는 높은 응집도와 낮은 결합도를 갖도록 모듈을 구성하는 것이다.

 

[1] 응집도란?

- 응집도는 쉽게 생각했을 때, "모듈 한 곳에 기능을 잘 모아놓은 것"인 것 같다.

- 위 링크에서는, 

  (1) 모듈이 하나의 목적을 수행하는 요소들간의 연관성 척도

  (2) 모듈 내부의 기능적인 응집 정도를 나타낸다.

  라고 설명을 해주었다.

 

[2] 결합도란?

- 결합도는 쉽게 생각했을 때, "모듈 하나의 수정이 다른 모듈에 영향을 미치는 정도"인 것 같다.

- 위 링크에서는, 

  (1) 다른 모듈과의 의존성의 정도

  (2) 모듈과 모듈 간의 상호 결합 정도

  라고 설명을 해주었다.

 

■ 프로시저란?

- 어떤 업무를 수행하기 위한 절차로 자주 쓰는 명령을 절차적으로 지정해둔 형태

 

■ 함수와 프로시져의 차이점

https://mjn5027.tistory.com/47

 

[ Oracle ] 프로시저와 함수의 차이

오라클을 사용하다보면 자주 접하게 되는 프로시저와 함수. ​ 이 둘의 정의와 차이점에 대해 알아보자. 프로시저(Procedure)란? 넓은 의미로는 어떤 업무를 수행하기 위한 절차를 뜻한다. ​ 예를

mjn5027.tistory.com

 

■ 프로시져 코딩 예시

-- 수정
create or replace procedure book_update(v_name IN varchar2, v_price IN number, v_idx IN number)
is
begin
   UPDATE book SET name = v_name, price = v_price WHERE idx = v_idx;
   commit;
end;
/


--삭제
create or replace procedure book_delete(v_idx IN number)
is
begin
   DELETE from book WHERE idx = v_idx;
   commit;
end;
/

-- 추가
create or replace procedure book_insert(v_name IN varchar2, v_price IN number)
is
begin
   INSERT INTO book VALUES((SELECT nvl(MAX(idx), 0) + 1 FROM book),v_name,v_price);
   commit;
end;
/

 

■ 명령 프롬프트에서 프로시저 생성 및 실행하는 법

 

 

■ CallableStatement를 사용하여 프로시져 구문 쓰기

- CallableStatement는 PreparedStatement를 상속한다.

package mymain;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
//import oracle.jdbc.driver.OracleDriver;

public class MyMain_DBTest2_프로시져 {
	
	//DB Driver Loading
	//메인 메소드가 시작되기 전에 먼저 0순위로 선작업.
	static {
		// 0. 객체가 생성 되기 이전에 클래스를 메모리에 적재 
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception{
		// 1. Connection을 얻어오기
		//(1) 연결경로, 사용자정보 가져오기
		//            jdbc:oracle:드라이버종류:@IP주소:포트:db아이디   <<- JavaEE에서 Data Source Explorer > Properties의 URL복사
		String url = "jdbc:oracle:thin:@localhost:1521:xe"; 
		String user = "test1";
		String pwd  = "test1";
		
		//(2) Connection 인스턴스를 싱글톤 방식으로 가져온다.
		Connection conn = DriverManager.getConnection(url, user, pwd);
		System.out.println("---------Success Connection-------");
		
		//2. Procedure사용할 객체
		String sql = "call book_insert(?, ?)";
		CallableStatement cstmt = conn.prepareCall(sql);
		
		//3. Parameter
		cstmt.setString(1, "And");
		cstmt.setInt(2, 22000);
		
		//4. 실행
		cstmt.executeUpdate();
		
		//5. 닫기 (열린 역순)
		cstmt.close();
		conn.close();
		
	}

}

 

 

[출처]

함수와 프로시저의 차이 https://mjn5027.tistory.com/47

■ 컴파일러 버전 바꾸기

- [프로젝트] - 오른쪽마우스 - [Properties] - [Java Compiler] 

- 체크를 풀어주고, 버전을 변경한다.

 

■ Facet도 같이 바꿔야한다.

■ MVC 모델이란?

https://m.blog.naver.com/jhc9639/220967034588

구분 내용
모델 애플리케이션의 데이터를 담고 CRUD하는 객체 (DAO 객체)
데이타를 기반으로 사용자들이 볼 수 있는 화면
컨트롤러 데이터와 사용자인터페이스 요소들을 잇는 다리역할
 

[개발자 면접준비]#1. MVC패턴이란

오늘은 개발자면접에 많이 나오기도 하는 MVC패턴에 대해서 알아보고자 합니다. 과연 MVC패턴이 무엇...

blog.naver.com

 

■ DB 모듈화 전체 구성

* 화살표 방향은 무시하고 전체적인 흐름만 보세요.

 

■ Connection(서버연결) 관리 객체

  드라이버를 로딩하고, DB 서버와 연결하는 객체 

 

- DAO가 Connection 관리 객체에게 DB 연결

  곧, Connection을 요청하면, Connection 인스턴스를 DAO에게 전달한다.

 

[코드 예시]

package service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBservice {
	
	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			System.out.println("드라이버를 찾을 수 없습니다.");
		}
	}
	
	private static DBservice single = null;
	
	public static DBservice getInstance() {
		
		if (single == null) {
			single = new DBservice();
		}
		
		return single;
		
	}
	
	private DBservice(){
		
	}
	
	public Connection getConnection() throws SQLException{
		
		Connection conn = null;
		
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String user = "test1";
		String pwd = "test1";
		
		conn = DriverManager.getConnection(url, user, pwd);
		
		return conn;
	}
	
}

 

■ VO (Value Object) : 칼럼의 맴버와 타입을 저장관리하는 객체

  DB의 테이블 칼럼을 필드맴버로 저장한 객체 

 

- 객체지향적으로 데이터의 속성 정보를 저장하는 객체이다.

- 일종의 구조체와 같아 보인다. 

   [Person이라는 객체 안에 name, age, addr]이 등록되는 것과 같이 객체의 속성을 저장한다.

 

Rf. 과거에 DTO (Data Tranfer Object) 라고도 불렀다.

    - VO는 읽기, DTO는 읽기/쓰기 모두 가능한 경우

 

[코드 예시]

package vo;

public class MemberVo {

	int ein;
	String name;
	String addr;
	String ssn; //주민번호
	int hireday;
	String id;
	String pwd;
	
	//Getter, Setter
	public int getEin() {
		return ein;
	}
	public void setEin(int ein) {
		this.ein = ein;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public String getSsn() {
		return ssn;
	}
	public void setSsn(String ssn) {
		this.ssn = ssn;
	}
	public int getHireday() {
		return hireday;
	}
	public void setHireday(int hireday) {
		this.hireday = hireday;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	
	
	
}

 

■ DAO (Data Access Object) - DB정보를 CRUD하는 객체

  데이터를 DB에서 불러와, LIST형태로 저장하는 객체   *데이터 CRUD 담당    

 

- 기능 : Create / Read/ Update / Delete

- 메서드 : insert / select / update / delete

 

   selectList()       -->   테이블의 리스트 정보를 선택하여 반환
   insert(VO)       -->   신규 레코드 삽입
   update(VO)     -->    기존 레코드 수정
   delete(칼럼명)  -->   칼럼 삭제

 

[코드 예시]

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import service.DBservice;
import vo.MemberVo;

public class MemberDao {
	
	private static MemberDao single = null;
	
	private MemberDao() {};
	
	public static MemberDao getInstance() {
		
		if (single == null) {
			single = new MemberDao();
		}
		
		return single;
	}
	
	public List<MemberVo> selectList(){
		
		List<MemberVo> list = new ArrayList<MemberVo>();
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = "SELECT * FROM member";
		
		try {
			conn = DBservice.getInstance().getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			
			while (rs.next()) {
				
				MemberVo vo = new MemberVo();
				
				vo.setEin(rs.getInt("ein"));
				vo.setName(rs.getString("name"));
				vo.setAddr(rs.getString("addr"));
				vo.setSsn(rs.getString("ssn"));
				vo.setHireday(Integer.parseInt(rs.getString("hireday"))+1900);
				vo.setId(rs.getString("id"));
				vo.setPwd(rs.getString("pwd"));
				
				list.add(vo);
				
			}
			
		} catch (Exception e) {
			
		} finally {
			try {
				if (rs != null) rs.close();
				if (pstmt != null) pstmt.close();
				if (conn != null) conn.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		
		return list;
	}
	
}

 

+ Recent posts