1. 추상화(모델링)
2. 상속: 재사용+확장
3. 다형성: 사용편의성
4. 캡슐화: 정보 은닉
추상화(모델링)
-'추상': 여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용
-'모델': 실제 사물을 정확히 복제하는 게 아니라 목적에 맞게 관심 있는 특성만을 추출해서 표현하는 것. 즉, 추상화를 통해 실제 사물을 단순하게 묘사하는 것
-객체 지향의 추상화는 곧 모델링입니다. 즉, 추상화란 구체적인 것을 분해해서 관찰자가 관심 있는 특성만 가지고 재조합하는 것입니다.
객체(Object)와 클래스(Class) 간의 관계
클래스:객체=펭귄:뽀로로=사람:김연아=쥐:미키마우스
-객체는 유일무이한 사물이며, 클래스는 같은 특성을 지닌 여러 객체를 총칭하는 집합의 개념입니다.
-객체 지향에서 추상화의 결과는 클래스입니다.
애플리케이션 경계(Context)
만들고자 하는 애플리케이션에 따라 클래스의 설계가 달라질 수 있습니다.
애플리케이션 경계 | 병원 애플리케이션 | 은행 애플리케이션 |
사람 | 환자 | 고객 |
클래스 모델링 | 시력 몸무게 혈액형 키 나이 먹다() 자다() 운전하다() 운동하다() |
나이 직업 연봉 일하다() 입금하다() 출금하다() 이체하다() 대출하다() |
*자바가 객체 지향의 추상화를 지원하는 방법
추상화=모델링=자바의 class 키워드
*자바에서 클래스와 객체 관계를 표현하는 방법
클래스 객체_참조_변수=new 클래스();
클래스 | 객체_참조_변수 | = | new | 클래스 | () |
객체_참조_변수의 자료형(Type) | 생성된 객체를 참조할 수 있는 변수 | 할당문 | 새로운 | 만들고자 하는 객체의 분류 | 메소드 |
클래스의 인스턴스, 즉 객체를 생성하기 위해 객체 생성자를 호출 | |||||
새로운 객체를 하나 생성해 그 객체의 주소값(포인터)을 객체 참조 변수에 할당 |
UML 클래스 다이어그램
-추상화의 결과물은 모델이고, 모델은 자바 언어에서 클래스로 표현됩니다. 그리고 클래스 모델을 표현하는 국제 표준 표기법이 UML 다이어그램입니다.
-클래스의 논리적/물리적 설계
- 논리적 설계: 개발 환경(언어 등)에 영향을 받지 않는 설계
- 물리적 설계: 개발 환경에 맞춰진 설계
T 메모리
아래와 같은 메모리 구조를 임의로 T 메모리로 부르고자 합니다.
스태틱(static) | |
스택(stack) | 힙(heap) |
스태틱 영역: 정적 변수
스택 영역: 지역 변수
힙 영역: 객체 변수
//Mouse .java
public class Mouse {
public String name;
public int age;
public static int countOfTail=1;
public void Sing() {
System.out.println(name + "찍찍!!!");
}
}
//MouseDriver.java
public class MouseDriver {
public static void main(String[] args) {
//클래스명.countOfTail
Mouse.countOfTail=1;
Mouse mickey=new Mouse();
Mouse jerry=new Mouse();
Mouse mightyMouse=new Mouse();
//객체명.countOfTail
System.out.println(mickey.countOfTail);
System.out.println(jerry.countOfTail);
System.out.println(mightyMouse.countOfTail);
//클래스명.countOfTail
System.out.println(Mouse.countOfTail);
}
}
Mouse name age countOfTail: 1 sing() |
|||
- | Mouse name: "미키" age: 85 sing() |
Mouse name: "제리" age: 73 sing() |
Mouse name: "마이티마우스" age: 71 sing() |
스택 | 힙 |
main()이 실행되기 전 T 메모리
countOfTail은 모든 객체가 동일한 값을 가지기 때문에, Mouse class에서 static으로 선언해주어 static 영역에 상주하게 됩니다.
클래스 멤버 = static 멤버 = 정적 멤버
객체 멤버 = 인스턴스 멤버
상속: 재사용+확장(extends)
-'상속': 상위 클래스의 특성을 하위 클래스에서 상속하고 거기에 더해 필요한 특성을 추가, 즉 확장해서 사용할 수 있다는 의미
상위클래스(슈퍼 클래스)-하위 클래스(서브 클래스)
하위->상위: 추상화, 일반화
상위->하위: 구체화, 특수화
하나의 상위 클래스: 하나의 객체
하나의 하위 클래스: 분류/집단
하위 클래스 is a kind of 상위 클래스->하위 클래스는 상위 클래스의 한 분류다.
펭귄 is a kind of 조류->펭귄은 조류의 한 분류다.
상속의 중요한 정의
-객체 지향의 상속은 상위 클래스의 특성을 재사용하는 것이다.
-객체 지향의 상속을 상위 클래스의 특성을 확장하는 것이다.
-객체 지향의 상속은 is a kind of 관계를 만족해야 한다.
상속과 인터페이스
구현 클래스 is able to 인터페이스->구현 클래스는 인터페이스할 수 있다.
-자바 API의 몇 가지 인터페이스
- Serializable 인터페이스: 직렬화할 수 있는
- Cloneable 인터페이스: 복제할 수 있는
- Comparable 인터페이스: 비교할 수 있는
- Runnable 인터페이스: 실행할 수 있는
-하위 클래스의 인스턴스가 생성될 때 상위 클래스의 인스턴스도 함께 생성됩니다.
다형성: 사용편의성
오버라이딩(overriding)과 오버로딩(overloading)
-오버라이딩(재정의): 상위클래스의 메소드와 같은 메소드 이름, 같은 인자 리스트
하위클래스가 재정의한 메소드를 알아서 호출해 줌으로써 형변환이나 instanceof 연산자를 써서 하위 클래스가 무엇인지 신경쓰지 않아도 됩니다.
-오버로딩(중복정의): 같은 메소드 이름, 다른 인자 리스트
오버로딩은 함수명 하나를 가지고 인자 목록만 달리하면 되기 때문에, 하나의 함수만 구현해도 다수의 함수를 구현한 효과를 낼 수 있습니다.
//Animal.java
public class Animal {
public String name;
public void showName() {
System.out.println("안녕 나는 %s야. 반가워\n", name);
}
}
//Penguin.java
public class Penguin extends Animal {
public String habitat;
public void showHabitat() {
System.out.println("%s는 %s에 살아\n", name, habitat);
}
//오버라이딩(재정의)
public void showName() {
System.out.println("어머 내 이름은 알아서 뭐하게요?");
}
//오버로딩(중복정의)
public void showName(String yourName) {
System.out.println("%s 안녕, 나는 %s라고 해\n", yourName, name);
}
}
캡슐화: 정보 은닉
-객체 멤버의 접근 제어자
- public: 모두가 접근 가능
- protected: 상속/같은 패키지 내의 클래스에서 접근 가능
- [default]: 같은 패키지 내의 클래스에서 접근 가능
- private: 같은 클래스 내에서만 접근 가능
-정적 멤버의 접근 제어자
ClassA | ClassA.pubSt | pubSt | this.pubSt | |
사용 가능 | 사용 가능 | 사용 가능 | ||
같은 패키지 | 상속한 경우 | 사용 가능 | 사용 가능 | 사용 가능 |
상속하지 않은 경우 | 사용 가능 | 사용 불가 | 사용 불가 | |
다른 패키지 | 상속한 경우 | 사용 가능 | 사용 가능 | 사용 가능 |
상속하지 않은 경우 | 사용 가능 | 사용 불가 | 사용 불가 |
정적 멤버의 접근 방법
객체참조변수명.정적멤버 형식으로 접근하기보다는 클래스명.정적멤버 형식으로 접근하는 것이 좋습니다.
참조 변수의 복사
Call By Value(값에 의한 호출)
기본 자료형 변수를 복사하는 경우 Call By Value(값에 의한 호출)에 의해 그 값이 복사되며 두 개의 변수는 서로에게 영향을 주지 않습니다.
//CallByValue.java
public class CallByValue {
public static void main(String[] args) {
int a=10;
int b=a;
b=20;
System.out.println(a); //10
System.out.println(b); //20
}
}
변수 b에 변수 a가 가진 값을 복사하고, 다시 변수 b에 20을 할당했습니다.
이때, a가 가진 값이 단순히 b에 복사된 것이고 a와 b 변수는 아무런 관계도 없습니다.
Call By Reference(참조에 의한 호출)/Call By Address(주소에 의한 호출)
//CallByReference.java
public class CallByReference {
public static void main(String[] args) {
Animal ref_a=new Animal();
Animal ref_b=re_a;
ref_a.age=10;
ref_b.age=20;
System.out.println(ref_a.age); //20
System.out.println(ref_b.age); //20
}
}
class Animal {
public int age;
}
참조변수 b에 참조변수 a의 주소를 참조하도록 하고, 참조변수 a에 10, b에 20을 할당했습니다.
이때, a와 b가 가진 값이 모두 10이 되었다가 값이 모두 20으로 바뀝니다.
- 기본 자료형 변수는 값을 값 자체로 판단합니다.
- 참조 자료형 변수는 값을 주소, 즉 포인터로 판단합니다.
- 기본 자료형 변수를 복사할 때, 참조 자료형 변수를 복사할 때 일어나는 일은 같습니다. 즉, 가지고 있는 값을 그대로 복사해서 넘겨줍니다.
'Java' 카테고리의 다른 글
[Java] 데이터 직렬화(Serialization)와 역직렬화(Deserialization) (0) | 2022.02.20 |
---|---|
[Java] 싱글턴(Singleton) 디자인 패턴 (0) | 2022.02.20 |
[Java] 생성자와 초기화 (0) | 2022.02.18 |
[Java] 객체 지향 설계 5원칙_SOLID (0) | 2021.02.17 |
[Java] 자바가 확장한 객체 지향 (0) | 2021.02.17 |