일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 오블완
- 붕대 감기 자바
- CPU
- 프로그래머스 붕대 감기
- 멀티태스킹
- 객체지향
- hackerrank
- 중첩 break
- spring security 설정
- 다형성
- 자바의 정석
- 프로그래머스
- 혼공얄코
- spring security
- continue 사용법
- 붕대 감기
- 오버로딩
- 멀티프로세싱
- SQL Mapper
- java
- 입출력
- 오버라이딩
- 티스토리챌린지
- break 사용법
- 자바의정석
- contiune
- 리눅스
- 캡슐화
- over()
- 쿠키
- Today
- Total
쉽게 쉽게
객체지향언어(특징, 추상화, 상속) 본문
이 글은 '자바의 정석'의 내용을 기반으로 공부한 내용을 덧붙인 글입니다.
1. 객체지향언어 특징
자바의 특징 중 자바에는 객체지향의 특징인 추상화, 상속, 캡슐화, 다형성이 잘 적용되어 있다고 했었다.
이를 기반한 객체지향언어의 장점은 이렇다.
★ 객체지향언어의 장점
(1) 코드의 재사용성이 높다.
새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있다.
(2) 코드의 관리가 용이하다.
코드 간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경할 수 있다.
(3) 신뢰성이 높은 프로그래밍을 가능하게 한다.
제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 코드의 중복을 제거하여 오동작을 방지할 수 있다.
객체지향의 특징인 4가지 특성을 알아보기 이전에 객체지향언어에서 사용되는 변수의 종류에 대해 알아보면 좋다.
2. 변수의 종류
class Variables{
int iv; // 인스턴스 변수
static int cv; // 클래스 변수(static변수, 공유 변수)
void method(){
int iv = 0; // 지역변수
}
}
(1) 인스턴스 변수(instance variable)
클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다.
인스턴스는 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다.
(2) 클래스 변수(class variable)
클래스 변수는 인스턴스변수 앞에 static을 붙이기만 하면 된다.
클래스 변수는 모든 인스턴스가 공통된 저장공간을 공유하게 된다.
클래스 변수는 인스턴스 변수와 달리 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다.
클래스가 메모리에 로딩될 때 생성되어 프로그램이 종료될 때까지 유지되며, public을 붙이면 같은 프로그램 내에서 어디서나 접근할 수 있는 '전역변수'의 성격을 갖는다.
(3) 지역변수(local variable)
메서드 내에 선언되어 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다.
굳이 클래스를 나누고 메서드를 만들어 사용하는 이유는?
(1) 높은 재사용성(reusability)
한 번 만들어 놓은 메서드는 몇 번이고 호출할 수 있으며, 다른 프로그램에서도 사용이 가능하다.
(2) 중복된 코드의 제거
같은 코드를 여러 곳에 반복되는 문장들 대신 메서드를 호출하는 한 문장으로 대체할 수 있다.
코드의 중복이 제거되고, 변경사항이 발생했을 때 메서드만 수정하면 되므로 관리가 용이하다.
(3) 프로그램의 구조화
작은 프로그램을 작성할 때는 상관없지만 규모가 커지면 몇 만 줄이 넘는 코드를 일일이 작성할 수 없다.
규모가 큰 프로젝트에서 문장들을 작업단위로 나눠서 여러 개의 메서드에 담아 프로그램 구조를 단순화시킬 수 있다.
이제 객체지향의 특성인 추상화, 상속, 캡슐화, 다형성 그 특징들에 대해 하나씩 설명해 본다.
3. 객체지향의 특징
(1) 추상화
추상이란 “사물이나 표상을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출하여 파악하는 것”
객체 지향 프로그래밍에서 의미하는 추상화는 객체의 공통적인 속성과 기능을 추출하여 정의하는 것을 의미한다.
예를 들어 자동차와 트럭은 모두 이동 수단이며 전진과 후진을 할 수 있다는 공통점을 가진다.
여기서 추상화를 통해 공통적인 기능(메서드)과 공통적인 속성(변수)을 추출하여 추상 클래스(abstract class)와 인터페이스(interface)로 정의하여 사용할 수 있다.
아래는 이동수단의 출발과 정지 기능을 추출한 인터페이스이다.
public interface Vehicle {
void start();
void stop();
}
이처럼 객체 지향 프로그래밍에서는 역할과 구현의 분리를 통해 보다 유연하고 변경에 열려있는 프로그램을 설계할 수 있다.
(2) 상속
상속이란 기존의 클래스를 재활용하여 새로운 클래스를 작성
추상화의 연장선으로, 상속은 클래스 간 공유될 수 있는 속성과 기능들을 상위 클래스로 추상화시켜 하위 클래스들이 모두 상위 클래스의 속성과 기능들을 간편하게 사용할 수 있도록 한다.
public class Vehicle {
void start(){ //탈 것이 출발하는 메서드
생략...
}
void stop(){ //탈 것이 정지하는 메서드
생략...
}
}
public class car extends Vehicle {
void openWindow() { //자동차가 창문을 여는 메서드
생략...
}
}
자동차는 탈것(vehicle)을 상속받음으로써 출발, 정지, 창문을 여는 메서드 총 3개의 기능을 사용할 수 있게 된다.
또한 상위 클래스의 기능과 속성들을 그대로 사용할 수도 있지만, 각각의 클래스의 맥락에 맞게 오버라이딩(method overriding)을 사용하여 내용을 재정의할 수도 있다.
★ super, super()
(1) super는 자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조하는 데 사용되는 참조변수이다.
멤버변수와 지역변수의 이름이 같을 때, this를 붙여 구별했듯이 상속받은 멤버와 자신의 멤버가 이름이 같을 때는 super를 붙여 구별할 수 있다.
super는 변수만이 아니라 메서드 역시 호출할 수 있다.
class Point {
int x;
int y;
String a() {
return "a :" + a;
}
}
class Point2 extends Point {
int z;
String a(){ //오버라이딩
return "a :" + a + ", z :" + z; // 그냥 썼을 경우
return super.a() + + ", z :" + z; // 조상의 메서드 호출시
}
}
조상클래스의 메서드에 내용을 추가할때는 super를 사용해서 작업하는 것이 효율적이다.
후에 조상클래스의 메서드가 변경되도 자동적으로 반영되기 때문이다.
(2) super()는 조상 클래스의 *생성자를 호출하는 데 사용된다.
생성자란?
생성자(constructor)란
생성자는 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드'이다.
인스턴스 변수의 초기화 작업(인스턴스 변수 초기화)에 주로 사용되며, 인스턴스 생성 시에 실행되어야 할 작업을 위해서도 사용된다.
(1) 생성자의 조건
(1) 생성자의 이름은 클래스의 이름과 같아야 한다.
(2) 생성자는 리턴 값이 없다.
(2) 생성자의 특징
(1) 생성자도 메서드이기 때문에 리턴값이 없다는 의미의 void를 붙어야 하지만, 모든 생성자가 리턴값이 없으므로 생략할 수 있게 한 것이다.
(2) 생성자도 오버로딩이 가능하며, 하나의 클래스에 여러 개의 생성자가 존재할 수 있다.
(3) 생성자라는 용어로 인해 오해할 수 있지만, 생성자는 단순히 인스턴스 변수들의 초기화에 사용되는 특별한 메서드일 뿐이다.
★ 연산자 new가 인스턴스를 생성
Card c = new Card();
수행되는 과정
1. 연산자 new에 의해서 메모리(heap)에 Card클래스의 인스턴스가 생성된다.
2. 생성자Card()가 호출되어 수행된다.
3. 연산자 new의 결과로, 생성된 Card인스턴스의 주소가 반환되어 참조변수 c에 저장된다.
(4) 모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야 한다.
컴파일할 때, 소스파일(*. java)의 클래스에 생성자가 하나도 정의되지 않은 경우 컴파일러가 자동적으로 기본 생성자를 추가하여 컴파일한다.
(5) 생성자 간에도 서로 호출이 가능하다.
단 2가지의 조건을 만족해야 한다.
(1) 생성자의 이름으로 클래스이름 대신 this()를 사용한다.
*this()는 생성자, this는 참조 변수 둘은 다른 것이다.
(2) 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.
Car(String color)
door = 5; // 첫번째줄
Car(color, "auto", 4);
// 에러1. 생성자를 두번째 줄에서 다른 생성자 호출
// 에러2. this(color, "auto", 4);로 해야함
다른 생성자를 첫 줄에서만 호출이 가능하도록 한 이유는 생성자 내에서 초기화 작업도중에 다른 생성자를 호출하게 되면, 호출된 다른 생성자 내에서도 멤버변수들의 값을 초기화할 것이므로 다른 생성자를 호출하기 이전의 초기화 작업이 무의미해질 수 있기 때문이다.
super()는 생성자의 첫 줄에서 호출되어야 한다.
이유는 자손 클래스의 멤버가 조상 클래스의 멤버를 사용할 수도 있으므로 조상의 멤버들이 먼저 초기화되어 있어야 하기 때문이다.
또한 첫 줄에 호출되지 않으면 컴파일러가 자동적으로 super();를 생성자 첫 줄에 삽입하여 호출한다.
class Point { //조상 클래스
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Point2 extends Point{ //자손 클래스
int z;
Point2(int x , int y, int z){
this.x = x;
this.y = y;
this.z = z;
}
}
이 예제를 실행하면 컴파일 에러가 발생한다.
이유는 Point클래스의 생성자에서 Point를 찾을 수 없다는 내용이다.
Point2(int x , int y, int z){
super(); // 컴파일러가 자동으로 추가
this.x = x;
this.y = y;
this.z = z;
}
컴파일러가 자동으로 추가하는 생성자 때문에 기본 생성자인 Point()를 호출하고 Point클래스에는 Point()가 정의되지 않았기 때문에 에러가 나타난다.
Point2(int x , int y, int z){
super(x, y); // 조상클래스의 생성자 Point(int x, int y) 호출
this.z = z;
}
이런 식으로 수정하면 에러가 사라진다.
3. 캡슐화
캡슐화란 클래스 안에 서로 연관 있는 속성과 기능들을 하나의 캡슐(capsule)로 만들어 데이터를 외부로부터 보호하는 것을 말한다.
자바 객체 지향 프로그래밍에서 캡슐화를 구현하기 위한 방법은 크게 두 가지가 있다.
먼저는 접근제어자(access modifiers)를 활용하는 것으로 접근제어자는 클래스 또는 클래스의 내부의 멤버들에 사용되어 해당 클래스나 멤버들을 외부에서 접근하지 못하도록 접근을 제한하는 역할을 한다.
두 번째 방법으로는 getter/setter 메서드를 사용하는 방법이 있다.
모든 속성값들을 private 접근 제어자로 선언하고, getter/setter 메서드의 접근제어자만 public으로 열어두어 선택적으로 외부에 접근을 허용할 속성과 그렇지 않을 속성을 getter/setter 메서드를 통해 설정할 수 있는 방법이다.
4. 다형성
어떤 객체의 속성이나 기능이 그 맥락에 따라 다른 역할을 수행할 수 있는 객체 지향의 특성을 의미한다.
대표적인 예로 우리가 앞서 본 오버라이딩과 오버로딩(method overloading)이 있다.
캡슐화, 다형성, 오버라이딩, 오버로딩은 다음 게시글에서 자세히 설명하도록 하겠다.
2023.03.17 - [개발공부/Java] - 객체지향언어(캡슐화, 다형성)
공부하면서 참고했던 글입니다.
잘못된 내용이 있다면 지적부탁드립니다. 방문해주셔서 감사합니다. |