SW 개발 방법 단계
- 요구사항 수집
- 요구사항 분석
- 고수준 설계
- 상세 설계
- 구현
- 테스트
SW 개발 방법론
- 구조적 방법론
- 정보공학 방법론
- 객체지향 방법론
- 컴포넌트 기반 방법론
- 애자일 방법론
객체 지향 프로그래밍(Object Oriented Programming)
데이터와 데이터에 대한 연산을 수행하는 코드를 그룹화 한 객체를 중심으로 SW를 설계 개발하는 패러다임
시스템의 행위보다, 시스템에 참여하고 책임을 갖는 객체가 무엇인지에 주목
다수의 객체가 각자의 역할을 하고, 객체 간에는 메세지를 주고 받으며 전체 시스템을 구성
절차 지향 vs 객체 지향
절차 지향
- 시스템의 행위에 집중
- 절차 지향 모델링은 프로그램을 기능중심으로 바라보는 방식으로 "무엇을 어떤 절차로 할 것인가?"가 핵심이 된다. 즉, 어떤 기능을 어떤 순서로 처리하는가에 초점을 맞춘다.
객체 지향
- 시스템에 참여하는 요소들에 집중
- 객체 지향 모델링은 기능이 아닌 객체가 중심이 되며 "누가 어떤 일을 할 것인가?"가 핵심이 된다. 즉, 객체를 도출하고 각각의 역할을 정의해 나가는 것에 초점을 맞춘다.
객체 지향 프로그래밍의 장점
- 복잡한 SW 시스템이 역할/ 책임에 따라 모듈화 될 수 있음
- SW 구성 요소 간의 더 명확한 커뮤니케이션이 가능하다.
- 결과적으로 SW를 좀 더 쉽게 유지보수 할 수 있다.
++)
- 신뢰성 있는 소프트웨어를 손쉽게 작성할 수 있다. (개발자가 만든 데이터를 사용하기 때문에 신뢰할 수 있다.)
- 코드를 재사용하기 쉽다 (상속, 캡슐화, 다형성으로 인해 재사용할 수 있다.)
- 재수정 작업을 하여 업그레이드가 쉽다.
- 디버깅이 쉽다.
객체 지향 프로그래밍의 단점
- 절차지향 프로그래밍에 비해 느린 실행 속도
- 필요한 메모리양의 증가
클래스
- 클래스는 Java 프로그램의 기본 단위
- Java 프로그램은 한 개 이상의 클래스로 구성된다.
- 일반적으로 1개의 클래스는 1개의 Java 파일 안에 존재
객체는 속성과 행동을 가지고 있으며, 클래스는 객체를 만들기 위한 틀 or 템플릿이다.
이러한 객체 지향의 특징이 있다.
- 추상화(abstraction)
- 객체들의 공통적인 특징(기능, 속성)을 도출하는 것
- 객체지향적 관점에서는 클래스를 정의하는 것을 추상화라고 할 수 있다.(클래스가 없는 객체지향 언어도 존재 ex.JavaScript)
- 캡슐화(encapsulation)
- 실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있다.
- 객체가 독립적으로 역할을 할 수 있도록 데이터와 기능을 하나로 묶어 관리하는 것
- 코드가 묶여있어서 오류가 없어 편리하다.
- 데이터를 보이지 않고 외부와 상호작용을 할 때는 메소드를 이용하여 통신을 한다. 보통 라이브러리로 만들어서 업그레이드해 사용할 수 있다.
- 상속성(inheritance)
- 하나의 클래스가 가진 특징(함수, 데이터)을 다른 클래스가 그대로 물려받는 것
- 이미 작성된 클래스를 받아서 새로운 클래스를 생성하는 것
- 기존 코드를 재활용해서 사용함으로써 객체지향 방법의 중요한 기능 중 하나에 속한다.
- 다형성(polymorphism)
- 약간 다른 방법으로 동작하는 함수를 동일한 이름으로 호출하는 것
- 동일한 명령의 해석을 연결된 객체에 의존하는 것
- 오버라이딩(Overriding), 오버로딩(Overloading)
- 오버라이딩(Overriding) - 부모클래스의 메소드와 같은 이름을 사용하며 매개변수도 같되 내부 소스를 재정의하는 것
- 오버로딩(Overloading) - 같은 이름의 함수를 여러 개 정의한 후 매개변수를 다르게 하여 같은 이름을 경우에 따라 호출하여 사용하는 것
- 동적바인딩(Dynamic Binding)
- 가상 함수를 호출하는 코드를 컴파일할 때, 바인딩을 실행시간에 결정하는 것.
- 파생 클래스의 객체에 대해, 기본 클래스의 포인터로 가상 함수가 호출될 때 일어난다.
- 함수를 호출하면 동적 바인딩을 통해 파생 클래스에 오버라이딩 된 함수가 실행
- 프로그래밍의 유연성을 높여주며 파생 클래스에서 재정의한 함수의 호출을 보장(다형 개념 실현)
좋은 클래스 설계
- 꼭 필요한 최소한의 속성과 행위만 존재한다.
- 속성과 행위 모두 특정 객체와 높은 관련성이 있어야 한다.
- 너무 큰 규모의 클래스는 분할될 필요가 있다.
Java의 클래스
- 객체를 생성하기 위한 설계도
- 객체 생성을 위한 정보들을 포함하고 있다.
- 객체가 어떤 종류의 속성들을 가질 것인지
- 객체가 어떤 종류의 행위들을 할 것인지
선언 문법
- class 키워드가 사용된다.
- 클래스 이름을 선언하고 클래스 내부 구현 코드를 중괄호로 묶는다.
- 클래스 내부에는 변수들과 메소드들이 존재한다.
변수
- 멤버 변수 : 특정 객체와 연결된 변수의 하나이며, 해당 변수의 모든 메소드(멤버 함수)에 접근이 가능
- 인스턴스 변수 : 클래스에 정의될 변수
메소드
- 메소드 : static 키워드를 가지는 메소드
- 인스턴스 메소드 : static 키워드를 가지지 않는 메소드
객체의 생성
- 클래스로부터 객체를 생성
사용 예시) 클래스명 변수명 = new 클래스명();
- 예전에 Java를 처음 배울 당시 상속성이나 다형성의 개념을 모르고 클래스를 선언하여 사용하던 객체를 재사용할려고 해서 위처럼 선언했다가 난감했었던 일이 있었다.
- 저 new를 사용한 선언은 정말 새로 선언한 것이며 존재하던 User가 아니라 새로운 User를 새로 선언한 셈이다.
즉, 혼동하지말고 사용하도록 해야 한다.
- 객체를 생성하고 그 객체에 대한 참조 정보를 변수에 저장
객체의 멤버 변수 접근
- 점 연산자(dot operator)로 객체의 멤버에 접근 가능
- 멤버 변수
- 메소드
사용 예시) 객체참조변수명.멤버변수명 - 객체의 멤버 변수에 새로운 값을 저장
- 객체의 멤버 변수에 저장되어 있는 값을 사용
메소드(Method)
- 객체는 속성과 행위를 갖고 있고, 메소드는 객체의 행위를 정의
- 메소드는 함수와 거의 유사하다.
- input와 output이 존재하며 특정 작업을 수행
- input에는 보통 매개 변수, output에는 return 값이 들어간다.
- 그러나 함수와 다르게 독립적이지 않고 메소드는 특정 객체에 포함되어 있다.
함수(function)
- 특정한 작업을 수행하기 위한 코드들의 집합
- 특정 작업의 코드들을 모듈화하여 필요한 경우 호출
- 코드의 중복을 줄일 수 있음
메소드의 문법
- 메소드를 호출하기 위한 메소드의 이름 존재
- 특정 작업을 위한 메소드의 구현 코드가 중괄호 { } 내부에 구현된다.
[접근제어자] 리턴타입 메소드이름(파라미터1, 파라미터2, ...) {
메소드의 구현 코드;
return 리턴값;
}
- 메소드는 Input과 Output이 존재
- input은 없거나 1개 이상의 파라미터 리스트
- output은 없거나 리턴 값으로 표시
- 리턴 타입은 리턴 되는 값의 자료형(리턴 값이 없을 경우 void)
캡슐화
객체의 속성과 행동을 하나의 단위로 그룹화
객체의 속성과 행동을 은닉 (정보 은닉이라 한다.)
반드시 필요한 속성 및 행동만 외부에 노출
대부분의 속성 및 행동은 외부에서 접근하지 못하도록 막음
객체의 정보 은닉
객체 내부에는 외부에서 접근해서 변경하면 안되는 속성이 존재
반드시 필요한 멤버만 외부에 노출하여 결합도를 줄일 수 있음
접근 제어자 (객체의 정보 은닉 방법)
접근 제어자(Access Modifier)를 활용하여 멤버의 접근을 제어
Java 접근 제어자의 종류
접근 제어자 | 설명 |
public | 모든 곳에서 접근 가능 |
private | 외부에서 접근 불가 |
protected | 상속 관계에서 자식이 부모 멤버에 접근 가능 |
default | 같은 패키지 내부에서만 접근 가능. 접근 제어자 명시하지 않을 시에 해당된다. |
접근 제어자의 사용
- 클래스, 멤버 변수, 메소드에 활용
- 클래스는 class 키워드 앞에 명시
- public class User - 멤버 변수는 자료형 앞에 명시
- private String email; - 메소드는 리턴 타입 앞에 명시
- public boolean isOver20()
private 접근 제어자
- private으로 지정된 멤버는 외부에서 접근 불가 (말 그대로 private하다)
- private 멤버도 객체 내부에서는 접근 가능
- 보통 모든 멤버 변수는 private 으로 지정
- 외부에 반드시 노출이 필요한 메소드만 제외하고, 객체 내부에서만 활용되는 메소드도 private으로 지정
this의 개념과 활용
객체 내부에서의 this는 해당 객체 자신을 의미
public class User{
private String email;
public void setEmail(String email) {
this.email = email; // 왼쪽에 있는 email은 해당 객체 내부, 오른쪽 email은 파라미터이다.
}
}
변수의 이름이 중복되지 않는 경우 this로 명시하지 않아도 무방하다.
파라미터의 이름을 의미 있게 만들면, 멤버 변수의 이름과 보통 중복된다.
멤버 변수의 값을 저장 및 변경하는 Setter 메소드
- User 객체의 모든 private 멤버 변수에 값을 저장하는 메소드 추가
- 보통 1개의 멤버 변수의 값을 세팅하는 메소드는 set이라는 동사로 시작한다.
- Setter라고 보통 지칭한다.
객체의 private 멤버 변수의 값을 반환하는 메소드 추가
- User 객체의 모든 private 멤버 변수에 값을 반환하는 메소드 추가
- 보통 1개의 멤버 변수의 값을 반환하는 메소드는 get이라는 동사로 시작
- getter라고 보통 지칭한다.
생성자
- 객체가 생성되는 시점에 호출되는 특별한 형태의 메소드
- 객체가 생성되는 시점에 초기화를 하기 위해 사용됨
- 주로 생성자에서는 객체 멤버 변수의 초기화 작업을 한다.
- 멤버 변수를 명시적으로 초기화 하지 않은 경우 아래 값이 저장된다.
- 숫자형 변수는 0
- boolean 변수는 false
- 참조 변수는 null
생성자의 문법
- 생성자의 이름은 클래스의 이름과 동일
- 접근 제어자는 보통 public을 사용
- 0개 또는 1개 이상의 파라미터 선언 가능
- return 타입은 생략된다.
public 클래스이름(파라미터1, 파라미터2, ...) {
생성자 내부 코드;
}
Default 생성자
생성자를 명시적으로 추가하지 않은 경우 Default 생성자를 제공
1개 이상의 생성자를 명시적으로 구현한 경우는 제공하지 않음
같은 작업을 하지만 파라미터만 다른 메소드가 필요한 경우
- C언어 수학관련 함수 중 절대 값을 구하는 함수의 종류
- abs(), labs(), fabs, cabs() - 메소드를 사용할 때 동일 작업을 위한 다양한 이름의 메소드를 기억해야 한다.
- 메소드를 개발할 때 파라미터의 조합에 따라 다양한 이름을 생성해야 한다.
메소드 오버로딩
특정 클래스 안에서 파라미터가 다른 동일한 이름의 메소드를 선언
파라미터의 자료형 또는 개수가 다르면 동일한 이름 사용 가능
메소드 호출 시 파라미터 세팅 조건에 따라 호출되는 메소드가 결정된다.
리턴 타입은 메소드 오버로딩의 조건에 해당하지 않는다.
메소드 오버로딩의 적합한 예시
- public int add(int a, int b);
- public int add(int a, int b, int c);
- public double add(double a, double b);
메소드 오버로딩의 부적합한 예시
- public int add(int a, int b);
- public int add(int a, int b);
- public long add(int a, int b);
생성자 오버로딩
- 생성자도 특수한 형태의 메소드이기 때문에 오버로딩 적용 가능
- 초기화 원하는 멤버 변수만 선택해서 초기화 가능
- 생성자 오버로딩은 빈번하게 사용된다.
'Java' 카테고리의 다른 글
Java - 상속, 다형성, 메소드 오버라이딩, 컬렉션 (0) | 2022.01.25 |
---|---|
Java 입문 (제어문 및 연습문제 리뷰) (2) | 2022.01.17 |
Java 입문 (자료형 및 연산자) (2) | 2022.01.17 |