실제 세계를 모델링하여 소프트웨어를 개발하는 방법으로서, 객체지향 프로그래밍에서는 데이터와 절차를 하나의 덩어리로 묶어서 생각한다.
코드를 작성하는 방법 중 하나
물이 위에서 아래로 흐르는 것처럼 순차적인 처리가 중요시되며 프로그램 전체가 유기적으로 연결되도록 만드는 프로그래밍 기법
대표적으로 C언어가 있다
절차 지향
은 데이터를 중심으로 함수를 구현하고,
객체 지향
은 기능을 중심으로 메소드를 구현한다.
절차 지향
은 실행 순서,절차가 더 중점이 되고,
객체 지향
은 필요한 객체들의 종류와 속성 등이 더 중점이 된다.
절차 지향의 반대는 객체지향이 아니고, 객체지향의 반대는 절차지향이 아니다!!!!!!!
더 나은 방법은 없고, 성격에 따라 다를 뿐이다
객체지향 프로그래밍에서 특정객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀 객체를 정의하기 위한 메소드와 필드(변수)로 구성 자바에서 모든 코드는 반드시 클래스 안에 존재해야 하며 서로 관련된 코드들을 그룹으로 나누어 별도의 클래스 구성
public class Car {
int speed = 0;
String name;
String color;
void information(){
System.out.println(name);
System.out.println(color);
}
void move(){
System.out.println(name + " move");
}
void speedUp(){
speed += 10;
}
void speedDown(){
speed -= 10;
}
void stop(){
speed = 0;
System.out.println(name + " stop");
}
}
Car라는 클래스를 만들어봤다. 이 클래스는 기본적으로 speed
, name
, color
이라는 필드를 가지고 있고 information()
, move()
, speedUp()
, speedDown()
, stop()
이라는 메서드를 가지고 있다.
메모리에 할당된 객체
하나의 클래스로부터 여러 개의 인스턴스를 생성할 수 있는데 이렇게 생성된 인스턴스는 독립된 메모리 공간에 저장된 자신만의 필드를 가질 수 있다.
클래스에서 정의한 것을 토대로, 메모리(실제 저장공간)에 할당된 것으로 프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간을 의미하며, 변수, 자료구조, 함수 또는 메소드가 될 수 있다.
모든 실재하는 대상을 객체라고 볼 수 있다.
객체와 인스턴스는 얼핏 보면 같은 개념인줄 알 수 있지만 약간 다르다.
객체는 우리가 클래스로 구현할 어떤 것이라고 할 수 있다.
인스턴스는 그 객체를 실체화 시킨 것이다.
위에 만들어놓은 Car 클래스를 사용하기 위해서는 객체를 생성해 주어야 한다.
Car nicecar = new Car();
nicecar
라는 객체를 만들었다 → 인스턴스화
어떠한 특정 작업을 수행하기 위한 명령문의 집합 클래스의 기능(동작)에 해당하는 구현 부분으로 해당 메소드 호출 시 메소드의 블럭({})에 해당하는 부분 실행
void information(){
System.out.println(name);
System.out.println(color);
}
void move(){
speed += 10;
System.out.println(name + " move");
}
void speedUp(){
speed += 10;
}
void speedDown(){
speed -= 10;
}
void stop(){
speed = 0;
System.out.println(name + " stop");
}
위의 코드에는 information()
, move()
, speedUp()
, speedDown()
, stop()
라는 5개의 메서드를 만들어 놓았다.
객체 지향적 설계를 통해 소프트웨어를 개발하면 코드의 재사용을 통해반복적인 코드를 최소화하고, 보다 유연하고 변경이 용이한 프로그램을 만들 수 있다. → 이러한 특징들은 객체 지향 프로그래밍의 4가지 특성에서 오는 것인데, 지금부터 한번 알아보자!!!
실제 세상을 객체화하는게 아니라 필요한 정보만을 중심으로 간소화하는것. 객체의 공통적인 속성과 기능을 추출하여 정의하는것.
public interface Vehicle {
public abstract void information();
public abstract void move();
public abstract void speedUp();
public abstract void speedDown();
void stop();
}
위의 코드를 보면 public abstract 라는 코드가 있는데 추상메소드를 선언하는 코드다
Vehicle이라는 인터페이스
를 만들어서 탈것의 공통적인 기능을 추상메소드로 만들어줬다.
public class Car implements Vehicle {
int speed = 0;
String name;
String color;
int wheels = 4;
public void information() {
System.out.println(name + "Car");
System.out.println("Color : " + color);
System.out.println("Wheels : " + wheels);
}
public void move() {
speed += 10;
System.out.println(name + " move");
}
public void speedUp() {
speed += 10;
}
public void speedDown() {
speed -= 10;
}
public void stop() {
speed = 0;
System.out.println(name + " stop");
}
}
Vehicle
인터페이스를 받은 Car
클래스
public class Motorcycle implements Vehicle {
int speed = 0;
String name;
String color;
int wheels = 2;
public void information() {
System.out.println(name + " Motorcycle");
System.out.println("Color : " + color);
System.out.println("Wheel : " + wheels);
}
public void move() {
speed += 10;
System.out.println(name + " move");
}
public void speedUp() {
speed += 10;
}
public void speedDown() {
speed -= 10;
}
public void stop() {
speed = 0;
System.out.println(name + " stop");
}
}
Vehicle
인터페이스를 받은 Motorcycle
클래스
Car
과 Motorcycle
클래스 둘다 Vehicle
인터페이스에 있는 추상 메소드 들을 구현해주었다.
자식 클래스에서 오버라이딩해야만 사용할 수 있는 메소드 자바에서 추상 메소드를 사용하는 목적은 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함
abstract 반환타입 메소드이름();
추상화를 통해 객체를 정의했다면, 객체에 필요한 데이터나 기능(메소드)을 책임이 있는 객체에 그룹화 시켜 주는것 객체에 직접적인 접근을 막고 외부에서 내부의 정보에 직접접근하거나 변경할 수 없고, 객체가 제공하는 필드와 메소드를 통해서만 접근가능
캡슐화의 가장 큰 장점
외부에서 객체접근하는데 있어서 정보를 숨기고 객체의 연산을 통해서만 접근이 가능하게 하는 것
캡슐화를 하기 위해서는 접근제어자를 통한 설계가 잘 이루어져야 한다. 자신 내부의 모듈은 감추고, 다른 모듈의 내부 작업도 직접적으로 개입하지 못하도록 설계해야한다.
접근제어자에 대한 내용은 아래에 정리하거나 따로 글을 쓸 예정이다
상위 클래스의 기능을 하위 클래스가 사용할 수 있는 개념. 상쇽이 필요한 이유는 여러 객체에서 사용되는 기능을 하나의 클래스로 분리해서 사용할 수 있도록 위함이다 → 중복되는 코드의 재사용성을 위함 기존의 클래스를 재활용하여 새로운 클래스를 작성하는 자바의 문법 요소
위에서 구현한 Car
과 Motorcycle
클래스에서 Vehicle
인터페이스에서 추상메소드로 선언한 information()
, move()
, speedUp()
, speedDown()
, stop()
들을 구현해줬는데 두개의 클래스에서의 메소드 내용이 겹친다.
그리고 speed
, name
, color
, wheel
이라는 필드들도 겹친다.
이를 해결해주기 위해 Vehicle2
라는 클래스를 만들어 상속을 통해 문제를 해결해보겠다!
Vehicle2
라는 부모 클래스를 만들어보자
public class Vehicle2 {
int speed = 0;
String name;
String color;
int wheels;
public void information() {
System.out.println(name + "Car");
System.out.println("Color : " + color);
System.out.println("Wheels : " + wheels);
}
public void move() {
speed += 10;
System.out.println(name + " move");
}
public void speedUp() {
speed += 10;
}
public void speedDown() {
speed -= 10;
}
public void stop() {
speed = 0;
System.out.println(name + " stop");
}
}
Car
클래스와 Motorcycle
클래스와 별로 다를건 없어보인다. 두 클래스의 공통된 부분을 합쳐서 만들어줬다.
이제 Vehicle
클래스를 상속받아 Car
클래스와 Motorcycle
클래스를 바꿔보자
Car 클래스
public class Car extends Vehicle2 {
int wheels = 4;
public void openWindow(){
System.out.println("창문을 활짝 엽니다");
}
@Override
public void information(){
System.out.println("Name : " + name);
System.out.println("Color : " + color);
System.out.println("Wheels : " + wheels);
}
}
extends
명령어를 통해 부모클래스인 Vehicle2
를 상속받았다.
부모클래스에 이미 정의되어있는것들을 다시 써줄 필요가 없어 재사용성이 좋다.
openWindow()
라는 메소드를 새로 만들어줬는데 이 메소드는 부모클래스인 Vehicle2
에서는 사용할 수 없는 확장된 메소드이다
Motorcycle 클래스
public class Motorcycle extends Vehicle2 {
int wheels = 2;
public void stunt(){
System.out.println("바이크가 묘기를 부립니다!");
}
@Override
public void speedUp(){
speed += 15;
}
@Override
public void information(){
System.out.println("Name : " + name);
System.out.println("Color : " + color);
System.out.println("Wheels : " + wheels);
}
}
Motorcyle
클래스도 Vehicle2
클래스를 상속받았다.
@Override
를 통해 speedUp()
메소드를 재정의 해줬다.
부모클래스인 Vehicle2
는 speed
를 10씩 올리는 반면에 재정의를 통해 speed
를 15씩 올리게 해줬다.
다음은 Car
클래스와 Motorcycle
클래스의 객체를 생성해서 각각 동작해본 코드다
public class Control {
public static void main(String[] args){
Car nicecar = new Car();
Motorcycle goodmotorcycle = new Motorcycle();
nicecar.name = "nicecar";
nicecar.color = "purple";
goodmotorcycle.name = "goodmotorcycle";
goodmotorcycle.color = "black";
nicecar.information();
goodmotorcycle.information();
nicecar.openWindow();
goodmotorcycle.stunt();
nicecar.move();
goodmotorcycle.move();
nicecar.speedUp();
goodmotorcycle.speedUp();
nicecar.printSpeed();
goodmotorcycle.printSpeed();
}
}
해당 코드의 결과는 이렇게 나온다
하나의 객체나 메소드가 여러가지 다른 형태를 가질 수 있는 성질
다형성은 조사할게 많아보이니까 나중에 따로 글써서 정리해야겠당