OOP(Object-Oriented Programming)의 4대 원칙
- 캡슐화 (Encapsulation): 객체의 데이터와 그 데이터를 처리하는 메서드를 하나로 묶어 외부에서 직접 접근할 수 없도록 하는 것입니다. 이를 통해 데이터의 무분별한 변경을 방지하고 객체의 안정성을 높입니다.
- 상속 (Inheritance): 기존의 클래스를 기반으로 새로운 클래스를 생성하는 기능으로, 코드의 재사용성을 높이고 중복된 코드 작성을 줄입니다. 예를 들어, '동물' 클래스에서 '포유류' 또는 '조류' 클래스를 파생시킬 수 있습니다.
- 다형성 (Polymorphism): 같은 이름의 메서드가 서로 다른 형태로 동작할 수 있는 능력입니다. 이는 메서드 오버로딩과 오버라이딩을 통해 구현되며, 유연한 코드 작성을 가능하게 합니다.
- 추상화 (Abstraction): 복잡한 시스템을 단순화하여 필요한 특성만을 강조하는 것입니다. 예를 들어, 자동차 객체를 표현할 때 엔진, 바퀴 등의 주요 특성만을 강조하고 나머지 세부 사항은 생략할 수 있습니다.
상속 시리즈
1) Extend, Overriding <<
2) Abstract
3) Interface
학교관리시스템을 만든다고 생각해보자.
학생 클래스
교수 클래스
교직원 클래스가 필요할것이다.
지금까지는 학생클래스의 학번, 이름, 학과, 주소, 수강과목 변수들을
그 클래스에서 하나하나 지정해줬었다.
잘 생각해보면... 학생, 교수, 교직원 객체는 서로 다른 객체이긴 하지만
번호, 이름, 학과, 주소같은 성격이 같은 변수들이 있다.
공통으로 관리할 수 있는 데이터는 따로 하나의 클래스로 묶어서, 필요한 변수는 받아서 쓰고(상속) !
별도 변수는 그 클래스에서 따로관리!
상속 사용의 장점!
- 코드 재사용
상속을 통해 자식 클래스는 부모 클래스에서 정의된 필드와 메소드를 재사용할 수 있습니다.
이를 통해 중복 코드를 줄이고, 코드의 유지보수성을 높일 수 있습니다. 예를 들어, 공통적인 기능을 부모 클래스에 정의하고, 자식 클래스에서 이를 상속받아 사용할 수 있습니다. - 유지보수 용이
부모 클래스에서 수정이 필요한 경우, 자식 클래스는 자동으로 그 변경 사항을 반영합니다.
이는 코드의 일관성을 유지하면서도 효율적인 유지보수를 가능하게 합니다. 따라서 부모 클래스의 기능이 변경될 때마다 자식 클래스를 수정할 필요가 없어집니다. - 다형성 지원
상속은 다형성을 구현하는 데 중요한 역할을 합니다. 하나의 참조 변수를 사용하여 다양한 형태의 객체를 다룰 수 있게 해줍니다.
예를 들어, Person이라는 부모 클래스를 상속받은 Student와 Employee라는 자식 클래스가 있을 때, 이들을 동일한 타입으로 처리할 수 있습니다. - 클래스 계층 구조
상속을 통해 클래스 간의 계층적 관계를 구성할 수 있습니다. 이는 클래스 관리와 구조화에 용이하게 하며, 새로운 클래스를 작성할 때 기존 클래스를 기반으로 빠르게 확장할 수 있게 합니다. - 생산성 향상
기존 클래스를 재사용하고 확장함으로써 새로운 클래스를 작성하는 속도가 빨라지고, 소프트웨어 개발의 생산성이 향상됩니다. 이는 개발자가 반복적으로 코드를 작성할 필요가 없기 때문에 발생하는 이점입니다.
상속받은 클래스에서는 변수, 메소드 모두 상속받아 사용 가능하다.
package entity;
public class Parent {
String name;
int age;
int money;
Child child;
public void print(){
System.out.println("이름: "+name);
System.out.println("나이: "+age);
System.out.println("보유자산: "+money);
}
public class Child extends Parent {
// 상속 받을때 사용하는 키워드 extends
// extends 오른쪽에 상속받을 클래스명을 쓴다 (딱 1개)
// 여러 클래스에서 상속받을순 없다? 가능은 하다.
// 눈에 안보이지만 멤버 변수들, 메소드 모두 상속 받았음!
// 상속 받았다는 것은, 이 클래스에서 바로 이용이 가능하단 뜻!
String hobby;
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
Chlid 클래스에서만 쓰인 hobby 변수... Parent에서 상속받아 쓰려했던 print()는 hobby 변수 출력이 되지 않는다
어떻게하면 출력되지?
Override
// print()가 Parent에도, Child에도 있다 > Child print()가 우선작동
// 메소드 오버라이드 : 상속받은 클래스의 함수이름을 그대로 사용하되
// 이 클래스에 맞게 재작성 했다는 뜻
// @ 어노텐션 Override : 다른사람이 봐도 아 재작성한거구나 알수있음
@Override
public void print() {
System.out.println("이름: "+name);
System.out.println("나이: "+age);
System.out.println("보유자산: "+money);
System.out.println("취미: "+hobby);
}
Parent.print();에도 이름, 나이, 보유자산이 있으니 물려받아 쓰고,
새로운변수만 추가해야지 = super 키워드
@Override
public void print() {
super.print();
// super = 상속해준 클래스 (Parent)
System.out.println("취미: "+hobby);
}
부모클래스에서 만든 메소드 print(); 도 사용가능!
super(); 를 이용하면 자식 클래스의 생성자에서 부모 클래스의 생성자도 호출가능!
public Customer(String username, String email) {
super(username, email);
// super(User)의 생성자
// loyaltyPoints를 0으로 초기화
this.loyaltyPoints=0;
}
오버라이딩과 오버로딩의 차이점
오버라이딩(Overriding):
상속 관계에 있는 클래스 간에 같은 이름의 메소드를 재정의하는 기술입니다.
부모 클래스의 메소드를 자식 클래스에서 같은 시그니처로 다시 정의합니다.
메소드 이름, 파라미터 개수, 파라미터의 자료형, 반환형이 모두 같아야 합니다.
오버로딩(Overloading):
같은 이름의 메소드를 여러 개 가지면서 매개변수의 유형과 개수가 다르도록 하는 기술입니다.
한 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것입니다.
메소드 이름은 같지만, 매개변수의 개수, 타입, 또는 순서가 달라야 합니다.
주요 차이점:
오버라이딩은 상속 관계에서 발생하고, 오버로딩은 같은 클래스 내에서 발생합니다.
오버라이딩은 메소드를 재정의하는 것이고, 오버로딩은 새로운 메소드를 정의하는 것입니다.
오버라이딩은 메소드 시그니처가 완전히 같아야 하지만, 오버로딩은 매개변수가 달라야 합니다.
자동 작성 기능도 지원한다! 편하다!