객체분해 (chapter7)


사람의 기억은 '단기'/'장기' 기억이 있음
일반적으로 단기기억 -> 장기기억으로 옮겨짐

조지밀러의 매직넘버 7
“단기 기억 공간에 일반적으로 5 ~ 9개의 아이템을 집어 넣을 수 있다”

저자가 말하고 싶은 것은?

“핵심은 실제로 문제를 해결하기 위해 사용하는 저장소는
장기 기억 저장소가 아닌 단기 기억 저장소이다”

  • 하지만 단기기억 공간에는 공간의 제약이 있다
    • 불필요한 정보를 제거하고 현재의 문제 해결에 대한 핵심 정보만 남긴다 (추상화)
    • 추상화의 일반적인 방법은 문제의 크기를 줄이는 것
    • 이처럼 큰 문제를 작은 문제로 나누는 것을 분해 라 한다

추상화와 분해는 인류가 창조한 가장 복잡한 문제 해결 방법
그 분야는 바로 소프트웨어이다

아래에서 객체 분해에 대해 알아보자

  • 프로시저 추상화와 데이터 추상화
  • 프로시저 추상화와 기능 분해
  • 모듈
  • 데이터 추상화와 추상 데이터 타입
  • 클래스

프로시저 추상화와 데이터 추상화

어셈블리어? 숫자로 된 기계어 범벅 …

  • 고수준 언어, 기계적 사고를 강요하는 낮은 수준의 명령어들을 탈피를 시도
  • 인간의 눈높이에서 기계 독릭접이고 의미 있는 추상화를 제공하려는 시도

현대적인 프로그래밍 언어를 특징 짓는 두 가지 추상화 메카니즘

  1. 프로시저 추상화
  2. 데이터 추상화
    소프트웨어는 데이터를 이용해 정보를 표현하고 프로시저를 이용해 데이터를 조작
    시스템을 분해 하려면 프로시저/데이터 추상화에서 중심으로 할 것을 정해야 한다
  • 프로시저 추상화

    • 소프트웨어가 무엇을 해야 하는지 추상화
    • 프로시저 중심 시스템 분해 -> 기능분해
  • 데이터 추상화

    • 소프트웨어가 무엇을 알아야 하는지 추상화
    • 데이터 중심 시스템 분해 -> 두가지 방법이 존재
      • 데이터를 중심으로 타입 추상화 -> 추상 데이터 타입
      • 데이터를 중심으로 프로시저를 추상화 -> 객체 지향

프로시저 추상화와 기능 분해

  • 기능 vs 데이터

    • 기능이 오랜 시간 시스템 분해의 기준으로 사용됨
    • 알고리즘 분해, 기능 분해 라고도 함
    • 기능 분해의 관점에서 추상화의 단위는 프로시저
  • 프로시저

    • 반복적으로 실행되거나 거의 유사하게 실행되는 작업들을 하나의 장소에 모아 놓음
    • 로직을 추상화하고 중복을 방지하는 추상화 방법
  • 전통적인 기능 분해 방법

    • 하향식 접근법
      • 시스템을 구성하는 가장 최상위 기능을 정의
      • 이 최상위 기능을 작은 단계의 하위 기능으로 분해해 나감
      • 분해의 마지막 하위 기능이 프로그래밍 언어로 구현
  • 급여 관리 시스템

급여 계산을 풀어서 하향식으로 구현하였다. 보기에는 이상적으로 보인다

하향식 기능 분해의 문제점

  1. 하나의 메인 함수라는 비현실적인 아이디어
    • 대부분의 시스템에서는 하나의 메인 기능이란 개념은 존재하지 않음
    • 대부분의 경우 추가되는 기능은 최초에 배포된 메임 함수의 일부가 아님
    • 새로운 기능 추가시, 매번 메인 함수를 수정
      • 큰 틀을 바꾸는 것이기 때문에 급격한 변경 가능성이 생김
  1. 비즈니스 로직과 사용자 인터페이스의 결합
    • 설계 초기 단계부터 입력 방법과 출력 양식을 함께 고민하도록 강요 ..
      • (사용자로부터 소득 세율 입력 받고, 급여를 계산하여 출력)
    • 문제는 사용자 인터페이스 변경은 자주 바뀌는 부분
    • 사용자 인터페이스가 바뀌지만 이 부분이 비즈니스 로직에도 영향을 주는 기이한 설계
  1. 성급하게 결정된 실행 순서

    • ‘무엇을 해야 하는지’가 아니라 ’어떻게 동작 해야하는지’에 초점을 맞춘다
    • 절차적인 순서로 진행 되기에 시간의 제약이 생긴다
    • 실행 순서나 조건, 빈복적인 제어 구조를 미리 결정해야 분해를 진행할 수 있다
      • 중앙집중 제어 스타일로 귀속
      • 모든 제어의 흐름 결정이 상위 함수에서 이뤄지게 된다
      • 따라서, 기능의 변경이 일어나게 되면 상위 함수까지 모두 수정이 발생
  2. 데이터 변경으로 인한 파급효과

    • 어떤 함수가 어떤 데이터를 사용하는지 추적이 어렵다
    • 데이터가 어떤 함수에 의존하는지 파악하기 위해서는 모든 함수를 열어 화인해야 한다
  • 하향식 접근법은 하나의 알고리즘 구현이나 배치 처리에는 적합

모듈

하향식 접근법은 위에 언급한 것처럼 많은 고통을 수반한다.
본질적인 문제를 해결하기 위해 접근을 통제하는 방법을 이용해야 한다

정보 은닉과 모듈

* 퍼블릭 인터페이스를 제공하여 접근을 통제한다 -> 정보 은닉
* 외부에 감춰야 하는 비밀에 따라 시스템을 분할하는 모듈 분할 원리
* 모듈은 변경 가능성 있는 비밀은 내부로 감추고 쉽게 변경되지 않을 인터페이스를 외부에 제공
  • 모듈
    • 서브 프로그램 이라기보다는 책임의 할당이다
    • 모듈이 감추어야 할 것
      • 복잡성
      • 변경 가능성


이전 전역변수 였던 $employees, $basePays, $hourlys 등이 모듈 내부에 선언되었다

모듈의 장점과 한계

  1. 모듈 내부의 변수가 변경 되더라도 모듈 내부에만 영향을 미친다
  2. 비즈니스 로직과 사용자 인터페이스에 대한 관심사를 분리한다
  3. 모듈화를 진행하여 네임스페이스 오염을 방지한다
    1. 내부변수, 함수를 이용하기 때문

모듈은 프로시저 추상화 보다는 높은 추상화 개념을 제공한다.
다만, 인스턴스의 개념을 제공하지 않기 때문에 모듈은 단지 모든 직원 정보를 가지고 있는 모듈일 뿐이다

(여기서 말하는 모듈은 우리가 아는 모듈이 아닌 프로시저의 추상화를 데이터와 함수의 단위로 묶은것 같다 ..)


데이터 추상화와 추상 데이터 타입

추상 데이터 타입

  • 타입
    • 변수에 저장할 수 있는 내용물의 종류와변수에 적용될 수 있는 연산의 가짓수
    • 저장된 값에 대해 수행될 수 있는 연산의 집합을 결정

리스코프
“추상 데이터 타입
추상 객체의 클래스를 정의한 것으로
추상 객체에 사용할 수 있는 오퍼레이션을 이용해 규정된다”

추상 데이터 타입을 정의하려면

  • 타입 정의를 선언할 수 있어야 한다
  • 타입의 인스턴스를 다루기 위해 오퍼레이션 집합을 정의할 수 있어야 한다
  • 제공된 오퍼레이션을 통해서만 데이터를 조작할 수 있어야 한다 (퍼블릭 인터페이스)
  • 타입에 대해 여러개의 인스턴스를 생성할 수 있어야 한다

클래스

클래스는 추상 데이터 타입인가?

  • 데이터 추상화를 기반으로 시스템을 분해하는 공통점이 있다
  • 명확히는 조금 다르다
    • 클래스는 상속과 다형성을 지원한다
      상속과 다형성을 지원 -> 객체지향 프로그래밍
      지원 X -> 객체기반 프로그래밍 이라 부른다

  • 둘의 차이는 무엇일까?
    • 추상 데이터 타입은 오퍼레이션에 종속된다
    • 클래스 객체는 이러한 차이를 다형성으로 해결한다
    • 이처럼 기존 코드에 아무런 영향을 미치지 않고 새로운 객체 유형과 행위를 추가할 수 있는 객체지향의 특성을 개방-폐쇄 원칙이라 한다

참조

  • 오브젝트, 코드로 이해하는 객체지향 설계 - 7장. 객체분해 (조영호님 저)

'Books > Object' 카테고리의 다른 글

[Object] 유연한 설계  (0) 2021.06.28
[Object] 의존성 관리하기  (0) 2021.06.10
[Object] 객체 분해  (0) 2021.05.29
[Object] 메시지와 인터페이스  (0) 2021.05.25
[Object] 책임 할당하기  (0) 2021.05.16
[Object] 설계 품질과 트레이드오프  (0) 2021.05.08
블로그 이미지

사용자 yhmane

댓글을 달아 주세요

프로토타입

객체 생성자

객체를 생성하는 함수를 생성자 함수라고 부릅니다. 대문자로 선언한고 new로 할당하여 사용합니다.

function Animal(type, name, sound) {
    this.type = type;
    this.name = name;
    this.sound = sound;
    this.say = function() {
      console.log(this.sound);
    }
}

const dog = new Animal('개', '두부', '멍멍');
const cat = new Animal('고양이', '휴지', '야옹');
dog.say();
cat.say();
  • this.say가 매번 할당 되고 있음

프로토타입

객체 생성자로 만든 함수에 공유할수 있는 값이나 함수를 설정하는 것

// 적용전
function Animal(type, name, sound) {
    this.type = type;
    this.name = name;
    this.sound = sound;
}

function say() {
    console.log(this.sound);
}

dog.say = say;
cat.say = say;
const dog = new Animal('개', '두부', '멍멍');
const cat = new Animal('고양이', '휴지', '야옹');
dog.say();
cat.say();
// 적용후
function Animal(type, name, sound) {
    this.type = type;
    this.name = name;
    this.sound = sound;
}

Animal.prototype.say = function() {
    console.log(this.sound);
}

Animal.prototype.value = 1;
const dog = new Animal('개', '두부', '멍멍');
const cat = new Animal('고양이', '휴지', '야옹');
dog.say();
cat.say();

객체 생성자 상속

call을 이용해 javascript도 상속을 구현할 수 있다

//  상속을 사용하지 않을 경우
function Dog(name, sound) {
    this.type = '개';
    this.name = name;
    this.sound = sound;
}

function Cat(name, sound) {
    this.type = '고양이';
    this.name = name;
    this.sound = sound;
}

Dog.prototype.say = function() {
    console.log(this.sound);
}

Cat.prototype.say = function() {
    console.log(this.sound);
}

const dog = new Dog('두부', '멍멍');
const cat = new Cat('휴지', '야옹');
// 상속을 적용
function Animal(type, name, sound) {
    this.type = type;
    this.name = name;
    this.sound = sound;
}

Animal.prototype.say = function() {
    console.log(this.sound);
}

function Dog(name, sound) {
    Animal.call(this, '개', name, sound);
}

function Cat(name, sound) {
    Animal.call(this, '고양이', name, sound);
}

Dog.prototype = Animal.prototype;
Cat.prototype = Animal.prototype;

const dog = new Animal('개', '두부', '멍멍');
const cat = new Animal('고양이', '휴지', '야옹');
dog.say();
cat.say();

클래스

ES6에서 클래스 문법이 도입 되었다. 프로토타입 작업을 조금 더 간략하게 사용할 수 있게 되었다.

class Animall {
    constructor(type, name, sound) {
      this.type = type;
      this.name = name;
      this.sound = sound;
    }
    say(){
        console.log(this.sound);
    }
}

const dog = new Animal('개', '두부', '멍멍');
const dog = new Animal('고양이', '휴지', '야옹');

dog.say();
cat.say();

클래스 상속

객체 생성자와 마친가지로 클래스 상속이 가능

class Animall {
    constructor(type, name, sound) {
      this.type = type;
      this.name = name;
      this.sound = sound;
    }
    say(){
        console.log(this.sound);
    }
}

class Dog extends Animal {
    constructor(name, sound) {
      super('개', name, sound);
    }
}

class Cat extends Animal {
    constructor(name, sound) {
      super('고양이', name, sound);
    }
}

const dog = new Dog('두부', '멍멍');
const dog = new Cat('휴지', '야옹');

dog.say();
cat.say();
블로그 이미지

사용자 yhmane

댓글을 달아 주세요

들어가며


 이전 포스팅에서 자바의 클래스에 대하여 알아보았습니다. 이번 포스팅에선 자바의 클래스에서 한단계 더 나아간 인터페이스와 추상클래스에 대하여 알아보도록 하겠습니다.


추상클래스와 인터페이스

 

인터페이스와 추상 클래스는 객체지향적 개념을 개발에 적용하며 설계를 확장하거나 향후 변경하기 쉬운 구조를 지원하는 요소입니다기본적인 속성과 필요한 메서드의 형태(프로토타입만) 기술하고세부적인 내용은 실제 구현 클래스에서 담당합니다.” 


 자바 실무에서 가장 많이 쓰이는 내용이 아닐까 라고 생각합니다. 공통적인 내용을 추상적으로 만들어 설계하는 곳에서 많이 사용됩니다. 실무에서는 보통 선임개발자가 추상클래스/인터페이스를 설계하여 공통된 로직을 적용하고 후임 개발자들이 내용들을 구현하는 용도로 많이 사용됩니다. 아래는 추상클래스와 인터페이스에 대한 내용을 간략히 표로 정리한 것입니다.


 

 추상 클래스

 인터페이스 

 상속 

 단일상속 

 다중상속 

 구현 

 extends 

 implements 

 추상메서드 

 0개 이상 

 모든 메서드 

 객체생성 

 생성불가 

 생성 불가 


  • 추상클래스

 추상클래스는 일반적인 클래스의 추상화 버전입니다. 추상클래스는 개념이나 사물에서 공통되는 특징이나 속성을 추출하여 설계하는 것입니다.

  • 인터페이스
 인터페이스는 추상클래스와 개념상 거의 동일하지만 아래와 같은 차이가 있습니다.

    • 인터페이스는 일반 메서드를 포함할 수 없으며, 모두 추상 메서드로만 구성합니다.
    • 일반 멤퍼 필드는 없고, public, static, final로 선언한 상수만 있습니다. (java8 부터는 생략 가능)
    • 다중 상속이 가능합니다.

추상클래스 예제

abstract class MyAbstractClass {
int num1, num2;
int result;

void calc() {
result = num1 + num2;
}

abstract int getResult();    // 추상메서드는 선언만
}

class MyClass extends MyAbstractClass  {    // extends로 상속 받음
int getResult() {
return result;
}
}

인터페이스 예제

Interface MyInterface {
public static final num = 1000;
public abstract int getResult();
}

class MyClass implements MyInterface {    // implements로 구현 받음
public int getResult() {
return num + 1000;
}
}



참조

- 자바의 정석

- Just 자바

블로그 이미지

사용자 yhmane

댓글을 달아 주세요

들어가며


  이전 포스팅에서 변수와 자료형에 대하여 학습하였습니다. 자료형에는 기본 자료형과 참조 자료형이 있는데 래퍼클래스는 참조 자료형입니다. jdk 1.5이전에는 둘의 구분이 명확하였지만 오토박싱언박싱이 지원되면서 구분이 모호해진 경우가 있습니다. 하지만 Wrapper 클래스를 써야 하는 경우도 많이 있으니 Wrapper 클래스에 대하여 학습해 보도록 하겠습니다.



Wrapper 

 

 Wrapper 클래스는 기본 자료형 byte, short, int, long 과 같은 자료형에 대하여 객체 타입으로 만든 클래스를 통칭합니다. 참조 자료형은 아래표와 같습니다. Wrapper 클래스는 객체를 생성할 수 있습니다. 


 기본형

 참조형(Wrapper)

 byte

 Byte

 short

 Short

 int

 Int

 long

 Long

 float

 Float

 double

 Double

 char

 Char

 boolean

 Boolean


  • Wrapper 사용 목적

기본형 타입이 아닌 Wrapper가 사용 되어야 하는 경우가 있습니다.
  1. 매개변수로 객체를 이용할 때 (일반적으로 Object를 명시합니다. 최상위 클래스)
  2. 기본형 값이 아닌 객체로 저장할 때
  3. 객체간의 비교가 필요 할 때 (equals()로 비교할 때 Wrapper 클래스는 주소값 비교가 아닌 값을 비교한다. 즉, equals 함수에 대하여 Overriding 되어 있다)

 주로 인터페이스로 부터 매개변수의 값을 모두 열어 둘때, Wrapper 클래스를 많이 사용하게 됩니다. 이외에도 Wrapper 클래스는 MIN, MAX, SIZE, TYPE 등의 변수들도 가지고 있습니다.



boxing, unboxing


 boxing과 unboxing은 기본 자료형과 Wrapper 클래스간의 데이터 변환을 의미합니다. 즉, 기본형 -> Wrapper로 가는 것을 감싸준다/담는다 하여 boxing이라 하고 Wrapper -> 기본형으로 가는 것을 unboxing이라고 합니다. jdk1.5 부터는 auto로 변환이 가능하니 조금 더 사용이 수월해 졌습니다.


boxing, unboxing


Integer num1 = new Integer(40);    => boxing

int num2 = num.intValue(); => unboxing


Autoboxing, Autounboxing


Integer num1 = 10;

int num2 = num1;


 

정리

 

  • 코드를 작성할 때 기본 자료형을 일반적으로 많이 이용합니다

  • 기본 자료형을 클래스로 사용해야 할 경우가 있다 

  • 공통코드로 매개변수를 클래스를 이용할 때, 객체간의 비교가 필요할 때 사용합니다

  • Autoboxing/unboxing 을 지원하니 생성자로 생성하거나 함수를 이용하여 형변환을 할 필요가 없습니다.


출처


- 자바의 정석

- just 자바


블로그 이미지

사용자 yhmane

댓글을 달아 주세요

들어가며


  이전 포스팅에선 자바의 객체지향과 클래스에 대해 알아보았습니다. 이번 포스팅에선 java의 lang 패키지내 String 클래스에 대하여 알아볼 것 입니다.



String

 

   String 클래스는 문자열을 처리하는 자료형의 개념으로 사용하였습니다. 이전 예제에서도 private String name으로 선언하여 사용하였습니다. 그러나 사실 Stringchar, int, double 등과 같은 자료형이 아닌 자바 클래스입니다.


  • String 선언 방법
String str = new String("홍길동");

또는 

String str = "홍길동";

String은 클래스이기 때문에 인스턴스를 만들고 참조변수인 str로 사용해야 합니다. 그러나 자바에서는 편의상 String을 객체 생성 구문이 아닌 변수 선언과 동일하게 사용할 수 있게 만들었습니다!!


  • String 연산
System.out.println("1학년 " + " 5반 " + "홍길동");

String str1 = "안녕하세요";
String str2 = "홍길동입니다";

System.out.println(str1 + " " + str2);

이처럼 자바에서는 문자열을 간편하게 처리할 수 있기 때문에 다른 언어에 비해 문자열을 사용하는 비중은 높은 편입니다. 하지만, 자바에서 문자열 연산시 생각치 못한 부분이 있기 때문에 잘 염두해 두어 사용해야 합니다.

str1 = str1 + str2 = "안녕하세요.홍길동입니다" 라는 문자로 변환이 되는데, 변수에 새로운 값을 대입하는 개념이 아니라 새로운 객체를 생성하고 참조하는 주소값을 변경하는 방식이기 때문에 성능적으로 조금 떨어지는 모순이 생깁니다. 따라서, 단순 조회가 아닌 문자열의 연산할 경우 StringBuffer 클래스 사용을 권장하고 있습니다!!



StringBuffer, StringBuilder


 자바에서는 문자열을 처리하는 3가지 클래스가 존재합니다. String, StringBuffer, StringBuilder가 있고 일반적으로는 String을 많이 이용합니다. String / StringBuffer, StringBuilder의 차이는 immutable이라는 특성입니다. String은 불변의 객체인데 위의 설명과 같이 새로운 연산을 수행하게 되면 객체를 새로 할당하여 주입시켜 주는 방식이기 때문에 concat과 같은 연산이 많을 경우에는 mutable한 StringBuffer와 StringBuilder를 사용하는 것이 유리합니다.


  • String 클래스 사용이 적절한 경우
 결론적으로, String 클래스는 참조 연산이 적고, 조회용으로 쓰기에 적합한 클래스 입니다.
 (JDK 1.5 이후로 String의 성능 이슈로 인해 줄에 한해 '+' 연산 처리를 할 떄는 내부적으로 StringBuilder로 처리한다고 합니다)

  • StringBuffer, StringBuilder 차이
 우선 두 클래스의 함수는 서로 호환이 되기 때문에 적절한 상황에 맞추어 사용하면 됩니다. 둘의 차이는 멀티 쓰레드 환경 지원 여부입니다. StringBuffer 클래스의 경우 synchronized 키워드 사용이 가능하기 때문에 동기화가 가능합니다. 반대로 StringBuilder 클래스의 경우 멀티쓰레드 지원이 불가능합니다. 하지만, 단일 쓰레드 환경에서는 StringBuilder의 성능이 조금 더 우세하기 때문에 일반적으로 연산을 많이 할경우 StringBuilder를 사용하면 됩니다.

 

정리

 

  • 문자열 단순 조회시 String 클래스를 사용하는 것이 좋음

  • 연산이 빈번하게 일어날 경우 StringBuffer/StringBuilder를 사용하는 것이 유리

  • StringBuilder > StringBuffer 보다 성능면에서 유리하기에 단일 쓰레드 환경이라면 StringBuilder를 사용할 것

  • Null 값에 연산을 수행하려고 할 경우 당연히 NullPointerException이 발생함으로 유의하여 사용할 것


출처


- 자바의 정석

- just 자바

블로그 이미지

사용자 yhmane

댓글을 달아 주세요

들어가며



 이전 포스팅에선 클래스와 객체, 인스턴스의 차이를 간략히 알아보았습니다. 이번 포스팅에선 클래스의 대해 알아볼 것인데 클래스는 프로그래밍의 설계도라고 생각하시면 됩니다


클래스


 

자바에서 클래스(class)란 객체를 정의하는 틀 또는 설계도라고 합니다. 자바에서는 이러한 설계도인 클래스(class)를 가지고 여러 객체를 생성하여 사용하게 됩니다. 클래스는 객체의 상태를 나타내느 필드(field)와 객체의 행위를 나태는 메서드(method)로 구성됩니다.


- 클래스 작성 규칙

  • 숫자로 시작하지 않는다

  • 첫글자는 대문자로 시작한다

  • 일반적으로 카멜 케이스(둘 이상의 단어가 연결 되었을 때, 두번째 단어의 첫글자는 대문자)를 사용한다

class Student
class CityCode
class ItemOrder


  • 필드

객체지향 개념에서 속성에 해당하는 것으로 멤버 변수라고도 합니다. 구조는 다음과 같습니다.


private String name; 한정자 / 자료형 / 변수명


  • 메서드

객체지향 개념에서 행위에 해당하는 것으로, 클래스를 사용하여 실행하는 동작입니다. 구조는 다음과 같습니다.


public int add(int a, int b) { 한정자 / 리턴값 / 함수명(매개변수 ,,,)

return a + b;            리턴키워드 리턴값

}


접근 한정자 - 외부 클래스에서 해당 클래스에 접근하는 범위를 지정합니다. 범위는 아래 표와 같습니다.

 한정자

클래스 내부 

동일 패키지 

하위 클래스 

그외 여역 

 public

 o

 o 

 o 

 o 

 protected

 o 

 o 

 o 

 x 

 default (기본, 생략가능)

 o 

 o 

 x 

 x 

 private

 o 

 x 

 x 

 x 


인스턴스


 클래스를 이용하여 객체를 생성 하게 되는데, 객체를 new 키워드로 할당하게 되면 인스턴스가 생성되어 집니다. 인스턴스가 생성될 때에는 메모리에 올라간 상태입니다.


 인스턴스 생성 방법


Student student = new Student(); 

클래스   참조변수  생성자

  • 생성자

생성자는 클래스나 인스턴스를 생성할 때 호출하는 특수한 목적의 메서드입니다. 일반적으로 변수를 초기화하거나 필요한 다른 개체를 생성하는 작업을 처리합니다. new 키워드를 사용하여 객체를 생성하는 시점에 호출되며, 클래스는 하나 이상의 생성자를 가질 수 있습니다.


생성자 예제

 public class Student {
private String name;
private int age;

public Student() {        // 기본생성자
name = "윤호";
age = 20;
}

public Student(String name, int age) { // 파라미터가 있는 생성자
this.name = name;
this.age = age;
}
}


public class Main {

public static void main(String[] args) {

Student student = new Student();


System.out.println("학생의 이름 : " + student.getName()); // 윤호

System.out.println("학생의 나이 : " + student.getAge());    // 20


Student a = new Student("철수", 30);

System.out.println("학생의 이름 : " + a.getName());          // 철수

System.out.println("학생의 나이 : " + a.getAge());             // 30

}

}


메서드 오버로딩, 오버라이딩


 마지막으로 자바의 객체지향 특성중 다형성과 관련된 기법인 메서드 오버로딩과 오버라이딩에 대하여 알아보겠습니다.

  • 메서드 오버로딩

 메서드 이름을 동일하지만 파라미터가 다른 여러 메서드를 만드는 것을 말합니다.

메서드 오버로딩 특징

- 메서드 이름이 동일합니다.
- 파라미터의 개수 또는 자료형이 다릅니다.
- 파라미터는 같고 리턴 변수의 자료형이 다르면 오버로딩은 성립하지 않습니다.

메서드 오버로딩 예제

public class OverloadingEx {
public int sum(int num1, int num2) {
return num1 + num2;
}

public int sum(int num1, int num2, num3) {
return num1 + num2 + num3;
}

public static void main(String[] args) {
OverloadingEx  ex = new OverloadingEx();
System.out.println(ex.sum(1,2));            // 3
System.out.println(ex.sum(3,4,5));          // 12
}
}
  • 메서드 오버라이딩

 메서드 오버라이딩은 상위 클래스에서 정의한 메서드를 서브 클래스에서 재정의하는 것을 말합니다.

메서드 오버라이딩 특징

- 메서드 이름이 동일합니다.
- 파라미터와 리턴값이 동일합니다.

메서드 오버라이딩 예제

class Person {
public void run() {
System.out.println("뛴다");
}
}


class Student extends Person {
public void run() {
System.out.println("엄청 빨리 뛴다");
}
}

public class Test {
public static void main(String[] args) {
Person person = new Person();
Student student = new Student();

person.run();    // 뛴다
student.runt();    // 엄청 빨리 뛴다
}
}



출처



- 자바의 정석

- just 자바

블로그 이미지

사용자 yhmane

댓글을 달아 주세요

들어가며


 이전 포스팅까지는 자바의 기초문법에 대하여 정의하였습니다. 기본적인 문법구조나 변수 선언등에 대해서 알아보았고, 이번 포스팅에선 자바의 가장 두드러지는 특징인 객체지향의 대하여 알아보도록 하겠습니다.


객체지향의 개념


 객체지향이란 컴퓨터 프로그래밍 패러다임중의 한 종류입니다. 기존 명령어를 중심으로 나열하는 프로그래밍기법에서 벗어나, 객체 모델을 바탕으로 프로그램을 구체화하고 개발하는 프로그래밍 기법을 의미합니다. 객체지향의 특징에는 상속, 추상화, 다형, 추상화 이라는 특징이 있습니다.

 위에 언급된 특성은 객체지향의 핵심적인 특징으로 꼭 이해하시고 가야 합니다. 객체지향의 특징을 설명하기 전에 클래스, 객체, 인스턴스를 짚고 넘어가도록 하겠습니다.


  • 클래스

멤버변수와 함수로 구성된 논리적인 설계도


class Student {

private String name;

private int age;

}


  • 객체

클래스에 선언된 모응 그대로 생성된 실체


public class Main {

public static void main(String[] args) {

Student student;

}

}


  • 인스턴스

생성되어진 객체가 메모리에 올려진 것


public class Main {

public static void main(String[] args) {

Student student = new Student();

}

}


객체와 인스턴스는 일반적으로는 통용하여 표현하나, 메모리에 올려진 여부로 객체와 인스턴스를 판단합니다.



객체지향의 특징


 객체지향에는 다음과 같은 특징이 있습니다. 캡슐화, 상속, 다형성, 추상화 모두 중요한 개념입니다. 


  • 캡슐화

 캡슐화는 생성한 객체를 어떤 메서드와 필드로 어떻게 일을 수행할지 외부에 숨기는 특성을 말합니다. 캡슐화 은닉화 라고 하며 보호하고자 하는 데이터의 값을 외부에서 직접 접근하는 것을 방지하기 위해 나온 개념입니다. 접근제어자를 이용하여 값을 은닉하고, public method로 값을 통제합니다.


캡슐화 예제

 class Student {
private String name;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge() {
this.age = age;
}
}


public class Main {

public static void main(String[] args) {

Student student = new Student();


student.setName("윤호");

student.setAge(20);


System.out.println("학생의 이름 : " + student.getName());

System.out.println("학생의 나이 : " + student.getAge());

}

}


  • 상속

 클래스는 추상화된 슈퍼클래스와 구체화된 서브 클래스로 구성됩니다. 예를 들면 사람(슈퍼클래스)와 학생(서브클래스)
 지정 예약어 extends를 이용하여 상속을 이용합니다. 하나의 부모클래스는 여러 자식을 가질 수 있지만, 반대는 성립하지 않습니다.
 자식은 부모의 값이나 행위를 상속받아 사용할 수 있습니다. 

상속 예제

class Person {
private String name;
private int age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge() {
this.age = age;
}

public void run() {
System.out.println("달리기를 합니다");
}
}

class Student extends Person() {
public void study() {
System.out.println("공부를 합니다");
}
}


public class Main {

public static void main(String[] args) {

Student student = new Student();


student.setName("윤호");

student.setAge(20);


System.out.println("학생의 이름 : " + student.getName());

System.out.println("학생의 나이 : " + student.getAge());


student.run();

student.study();

}

}


  • 다형성

 클래스의 상속 관계를 이용하여 슈퍼클래스가 같은 서브 클래스의 동일한 요청을 다르게 처리할 수 있는 특징을 말합니다. 예를 들어, 사람이라는 클래스가 있고 아침에 이동하다는 행위를 합니다. 사람을 상속받은 학생클래스는 아침에 학교로 이동하고, 사람을 상속박은 직장인 클래스는 아침에 회사로 이동합니다. 아래 예제를 보도록 하겠습니다.

다형성 예제


class Person {
public void move() {
System.out.println("이동합니다");
}
}

class Student extends Person() {
@Override
public void move() {
System.out.println("학교로 이동합니다");
}
}

class Student extends Worker() {
@Override
public void move() {
System.out.println("일터로 이동합니다");
}
}

public class Main {

public static void main(String[] args) {

Student student = new Student();

Worker worker = new Worker();


student.move();

worker.move();

}

}


  • 추상화

 매우 중요한 개념입니다. 객체의 공통된 특징을 묶어서 추출한다는 개념인데, 다음 포스팅에서 클래스에 대하여 설명하며 추상클래스, 인터페이스와 함께 덧붙이도록 하겠습니다.


정리

 

 이번 포스팅에선 자바의 핵심 개념인 객체지향에 대하여 글을 작성하였습니다. 자바는 프로그램을 구조화하는 특징을 가졌으며 추상화, 상속, 캡슐화, 다형성라는 중요한 특성이 있습니다. 이러한 기능으로 구조적으로 재활용성이 높아져 생산성이나 유지보수 효율성을 높인 프로그래밍 언어입니다!!


출처


- 자바의 정석

- just 자바

블로그 이미지

사용자 yhmane

댓글을 달아 주세요