객체지향의 4가지 특징

rvlwldev·2023년 3월 28일
0

Java

목록 보기
7/8

캡슐화 (Encapsulation)

내가 생각하는 캡슐화는 하나의 어떤 로직, 데이터를 클래스 또는 객체로 묶어서 데이터의 손상을 방지하거나 정해진 규칙이나 로직에 따라서만 사용 가능하게 만드는 방식이다.
예를 들어 VO(Variable Object) 등의 패턴을 사용할 때 사용된다.
접근제어자의 이해가 필요하다.

// 코드 예시)
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        Student student = new Student("김송아", 20);

        System.out.println("학생성명 : " + student.getName());
        System.out.println("출생년도 : " + student.getBornYear());
    }
}
class Student {
	// 접근제어자로 외부로부터 데이터를 숨김
    private String name;
    private int age;

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

    public String getName(){
    	// 공백을 포함하는 규칙을 포함
        return String.join(" ", name.split(""));
    }

    public int getBornYear() {
    	// 출생년도를 구하는 로직을 포함
        return LocalDate.now().getYear() - age;
    }
}

추상화 (Abstraction)

공통적인 요소를 선별하고 정의하여 필수요소누락, 추가 등의 부분에서 실수를 방지한다.
전체적인 틀을 모델링하는 설계도와 비슷한 개념이다.

public interface IAnimal {
	
	// 구현해야할 메소드들
    void setName(String name);
    String getName();

    void setGender(String gender);

    void setSound(String sound);
    void sounds();
}
/*
IAnimal 인터페이스를 구현한다면
위 5개의 정의된 메소드를 모두 구현해야한다.
*/

public class lamb implements IAnimal {
    String name;
    String gender;
    String sound;

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

	@Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public void setSound(String sound) {
        this.sound = sound;
    }

    @Override
    public void sounds() {
        System.out.println(this.sound);
    }
}

다형성 (Polymorphism)

객체는 캐스팅해서 여러 타입의 형태를 가질 수 있다. ex) 한국은 국가이다.
하지만 모든 국가가 한국이 아니듯이 객체 간의 관계를 제대로 파악, 설계하는 것이 중요하다.

제네릭 와일드카드 구현할 때 이 개념을 모르면 캐스팅해서 파라미터를 넘길 때 얼탈 수도 있다. 참고

public class Country {
    public String hello() {
        return "shake hands";
    }
}

class Korea extends Country {
    @Override
    public String hello() {
        return "안녕하세요~";
    }
}

class Japan extends Country {
    @Override
    public String hello() {
        return "곤니찌와~";
    }
}

위와 같은 관계가 있다고 할 때

public class Main {
    public static void sayHello(Country country){
        System.out.println(country.hello());
    }

    public static void main(String[] args) {
        sayHello(new Country());
        sayHello(new Korea());
        sayHello(new Japan());
    }
}
출력결과)

shake hands
안녕하세요~
곤니찌와~

sayHelloCountry 파라미터는 Korea, Japan 등의 상속받는 다양한 타입으로 변환될 수 있다.

다형성을 잘 알고있으면 sayHello 메소드처럼 재사용성이 높아지게 코드를 작성할 수 있다.

상속성 (Inheritance)

부모의 특징을 유전받는다고 생각하면 편하다.
extends 키워드로 어떤 클래스를 상속받은 클래스라면,
상속하는(부모) 클래스의 메소드, 필드 등도 상속받는(자식)클래스에서도 사용이 가능하다.

부모와 자식 관계로 생각하면 편한 이유는 부모가 서로 눈 색깔이 다르다고 하면, 오드아이가 아니라면 자식은 둘중 하나의 색깔을 유전받기 때문에 extends 키워드를 사용한다면 두개 이상의 클래스를 상속 받을 수 없다는 개념과 이어지기 때문이다. (implements는 가능)

// 부모클래스
public class Mom {
    String eyes = "blue";
    
    public String hobby() {
        return "gamble";
    }
}
// 자식클래스
public class Son extends Mom {
    public String getEyesColor() {
        return eyes;
    }
}
public class Main {
    public static void main(String[] args) {
        Son son = new Son();
        System.out.println(son.getEyesColor()); // blue출력
        System.out.println(son.hobby()); // gamble출력
    }
}

Son클래스에서 eyeshobby() 메소드를 구현하지 않아도 사용할 수 있어서 중복된 코드를 방지할 수 있고 나중에 수정할 때도 Mom 클래스만 코드만 수정할 수 있어서 유지보수성 또한 높아진다.

0개의 댓글