자바 & 객체지향
객체 지향 프로그래밍 OOP
- OOP: Object Oriented Programing
객체를 파악하고 객체들 간의 상호작용을 통해 프로그램을 만드는 것 - 직관적인 방식
- 컴퓨터에 맞춰 사고하던 방식의 프로그래밍(절차적/구조적)
-> 현실세계를 인지하는 방식의 프로그래밍(객체 지향)
객체 지향의 4대 특성
- 객체 지향의 4대 특성: 캡슐화, 상속, 추상화, 다형성 (캡! 상추다)
- 캡슐화(Encapsulation): 정보 은닉
- 정보 은닉 - 접근 제어자: private, default, protected, public
- private: 같은 클래스에서 접근 가능
- protected: 같은 패키지 & 상속 관계에 있는 클래스에서 접근 가능
- default: 같은 패키지에서 접근 가능
- public: 접근 제한 없음
- 접근 제어자 UML 표기법
- -표시: private 접근 제어자
- ~표시: default 접근 제어자
- #표시: protected 접근 제어자
- +표시: public 접근 제어자
- 상속(Inheritance): 재사용
- 객체지향에서의 상속 = 확장 + 재사용
- 상위 클래스의 특성을 하위 클래스에서 상속하고 필요한 특성을 추가(확장)
- 상위 클래스쪽으로 갈수록 추상화/일반화
- 하위 클래스쪽으로 갈수록 구체화/특수화
- 상속에서는 "하위 클래스는 상위 클래스다"관계가 성립되어야함 => is a / is a kind of 관계를 만족
- 동물은 포유류다 (x)
- 포유류는 동물이다 (o)
- extends 키워드 사용
- 자바에서는 다중상속을 지원하지 않음
- 다중 상속의 다이아몬드 문제 발생
- 컴파일러가 정확한 상속관계를 파악할 수 없음
=> 호출이 모호해서 컴파일러의 정상적인 수행이 어려움 - 다중 상속의 장점을 가져오기 위해 인터페이스 도입
- "구현 클래스 is able to 인터페이스" 관계 성립
- 상위 클래스는 물려줄 특성이 많을수록 좋음
=> 객체지향 설계 5원칙 중 LSP(리스코프 치환 원칙) - 인터페이스는 메서드가 적을수록 좋음
=> 객체지향 설계 5원칙 중 ISP(인터페이스 분리 원칙)
public class Inheritance {
public static void main(String [] args) {
// 상위 클래스 - Animal, 하위 클래스 - Mammalia, Bird라 가정
Animal animal = new Animal;
// "하위 클래스 is a kind of 상위클래스" 관계 성립
Animal mammalia = new Mammalia();
Animal bird = new Bird();
}
}
- 상속관계 UML 표기법
- 두 클래스 간 상속은 하위 클래스에서 상위 클래스 쪽으로 실선 삼각형 화살표로 표시
- 클래스가 인터페이스를 구현할 경우 클래스에서 인터페이스 쪽으로
점선 삼각형 화살표로 표시, 약식으로 막대 사탕처럼 표시하기도 함
- 추상화(Abstraction): 모델링
- 추상: 여러가지 사물, 개념에서 공통되는 특성/속성을 추출해 파악
- 모델: 실제 사물을 정확히 복제하는 것이 아닌 목적에 맞게 관심있는 특성만 추출하고 표현 => 추상화를 통한 실제 사물을 단순하게 묘사
- 상속, 인터페이스, 다형성을 통한 추상화
- 객체지향에서 추상화의 결과는 클래스
- 다형성(Polymorphism): 사용편의성
- 객체 지향에서의 다형성: overriding, overloading
- overriding: 같은 메서드 이름, 같은 인자로 상위 클래스의 메서드 재정의
- overloading: 같은 메서드 이름, 다른 인자로 다수의 메서드를
중복 정의 - 상위 클래스 타입의 객체 참조 변수를 사용해도 하위 클래스에서 overriding한 메서드가 호출
// method overriding & overloading ex)
public class Person {
public String name;
public void hi() {
System.out.println("hi");
}
}
public class Korean extends Person {
public void hi() { // method overriding
System.out.println("안녕");
}
public void hi(String name) { // method overloading
System.out.println("안녕하세요 저는 " + name + "입니다.");
}
}
클래스(추상화)와 객체
- 클래스(class): 분류, 집합, 같은 특성(속성/기능)을 가진 객체를 총칭
- 키, 몸무게 => 명사로 표현되는 특성을 속성
- 속성은 값을 가질 수 있다.
- 먹다, 자다 => 동사로 표현되는 특성을 기능/행위(메서드)
- 기능/행위는 수행 절차, 로직을 갖는다.
- 애플리케이션 경계(context)에 따라 클래스 설계가 달라진다.
<클래스와 객체의 관계>
클래스 객체참조변수 = new 클래스();
=> 새로운 객체를 하나 생성해 그 객체의 주소값을 객체참조변수에 할당
- 객체(object = class instance):실체, 유일무이한 사물
- 클래스 멤버와 객체 멤버의 차이는 static 키워드의 유무
=> static 키워드가 있으면 클래스 멤버 - 클래스 멤버 = static 멤버 = 정적 멤버
- 정적 속성은 해당 클래스의 모든 객체가 같은 값을 가질 때 사용함
- 정적 메서드는 객체 존재 여부와 관계없이 쓸 수 있는 메서드
- 메모리가 초기화된 순간 객체가 하나도 존재하지 않기에 main()
메서드는 정적 메서드여야 한다. - 정적 멤버는 UML 표기법에서 밑줄을 사용해 표시
- 정적 멤버는 클래스 내부에 메모리 공간이 확보
- 정적 멤버는 클래스명.정적멤버 형태로 접근하는 것을 권장
- 객체 멤버 = 인스턴스 멤버
- 객체 멤버는 클래스 내부에 실제 메모리 공간을 확보하지 않는다
- 클래스, 객체 멤버는 별도로 초기화 해주지 않아도 default 값으로 초기화됨
- int(0), double(0.0), boolean(false), 객체(null)
이름 | 호칭 | 메모리 공간 |
---|---|---|
static 변수 | 클래스 멤버, 정적 멤버 | static 영역 |
instance 변수 | 객체 멤버 | heap 영역 |
local 변수 | 지역 변수 | stack 영역 |
public class Person {
// 객체(인스턴스) 멤버
public String name;
public int age;
// 클래스 멤버 => static 키워드
public static int countOfEyes;
}
public class Main {
// main() 메서드도 클래스의 멤버 메서드
public static void main(String [] args){
// 클래스 멤버는 클래스명, 객체명으로 모두 접근 가능
// 클래스명.멤버
Person.countOfEyes = 2;
Person person = new Person();
// 객체명.멤버
System.out.println(person.countOfEyes);
}
}
출처: 김종민, ⌜스프링 입문을 위한 자바 객체 지향의 원리와 이해⌟ 위키북스
Leave a comment