교육과정 기록/☕ Java

객체지향 요약1

춘식이왔엉 2022. 4. 17. 15:59

🚗클래스 정의

1. 설계도

2. 데이터 + 함수

- 변수 (하나의 데이터) --> 배열 (같은 종류의 데이터) --> 구조체 (서로 관련된 데이터) --> 클래스 (데이터+함수)

-즉, 데이터(변수)와 함수(메서드)로 이루어진 '명령문 묶음' 

3. 사용자 정의 타입

int hour = 12;
int minute = 34;
int second = 56;
// 비객체지향적

class Time {
    int hour;
    int minute;
    int second;
 }
 Time t = new Time();
    t.hour = 12;
    t.minute = 34;
    t.second = 56;
// 객체지향적

 

🚗선언 위치에 따른 변수의 종류

1. 클래스 영역 -- iv (인스턴스변수) / cv (static+iv)

2. 메서드 영역(클래스영역 이외의 영역) -- lv (지역변수)

 

*변수의 생성시기 / 범위

  생성시기 범위
iv 인스턴스가 생성되었을 때 클래스 내에서 유효
cv 클래스가 메모리에 올라갈 때
--> 필요할때 자동으로
--> 객체생성 필요XX
클래스 내에서 유효
lv 변수선언문이 수행되었을 때 메서드 내에서만 유효
--> 메서드 종료시 자동제거

 

🚗클래스 변수와 인스턴스 변수

ex) 카드 객체

카드마다 무늬나 숫자가 다름. 하지만 폭과 높이는 다르면 안됨

- 무늬 / 숫자 --> 개별 --> iv

- 폭 / 높이 --> 공통 --> cv --> static 붙이자 ! 

class Card {
    String kind;
    int number;
    static int width;
    static int height;
 }
 //사용
 Card c = new Card();
    c.kind = "HEART"
    c.number = 7
    Card.width = 100;
    Card.height = 200;
 // static 멤버도 c.width = 100; 와 같이 쓸 수도 있지만, 
 // 인스턴스멤버와 혼동을 줄 수 있기 때문에 권장하지 않는다.

   


🚗메서드

1. 문장들을 작업단위로 묶어서 이름 붙인 것

2. 값(입력)을 받아서 처리하고, 결과를 반환(출력)

int add(int x, int y) { // 선언부
 int result = x + y;   
                       // 구현부
 return result;
 }

 

* 장점

- 코드 중복 줄일 수 있음

- 관리가 쉽다

- 재사용 가능

- 간결하다 -> 이해 쉬움

 

* 메서드의 작성

- 반복적으로 수행되는 여러 문장을 메서드로 작성

- 하나의 메서드는 한 가지 기능만 수행하도록 작성

 

* 메서드의 호출

   Call -> 실행

- 메서드 이름(값1, 값2, ...);   // 호출

   --> 메서드에 값이 전달되며, 작업 ㄱㄱ --> 작업을 마치면 호출한 곳으로 돌아온다.

public static void main(String[] args) {
 Mymath mm = new Mymath();
  int result1 = add(5,3);       // add 메서드 호출
  int result2 = subtract(5,3);  // subtract 메서드 호출
  int result3 = multiply(5,3);  // multiply 메서드 호출
  double result4 = divide(5,3); // divide 메서드 호출
  
Class Mymath {
 int add(int x, int y){
  int result = x + y;
  return result;
 } // --> return x + y; 로 간단히 쓸 수 있다.
 int subtract(int x, int y){return x - y};
 int multiply(int x, int y){return x * y};
 double divide(double x, double y){return x / y};

 

* return문

- 실행중인 메서드를 종료하고 호출한 곳으로 되돌아감

- 반환타입이 void일 때는 return문 생략 가능.

  그 외에는, 반환값을 함께 써줘야 한다. -> 타입이 일치해야함(or자동형변환이 가능해야함)

 

* 호출 스택

- 메서드 수행에 필요한 메모리가 저장되는 공간

- 메서드가 호출되면 호출 스택에 메모리 할당 / 종료되면 해제

- 아래 있는 메서드가 위에 있는 메서드 호출한 것.

- 맨 위의 메서드 하나만 실행중 / 나머지는 대기중

 

* 기본형 매개변수

-> 변수의 값을 읽기만 할 수 있다. ( read only ) --> 변경 불가

* 참조형 매개변수 

-> 변수의 값을 읽고 변경할 수 있다. ( read & write )

 

🚗 static 메서드와 인스턴스 메서드

   ( --> iv 사용여부에 따라 구분된다. )

 

* 인스턴스 메서드

- 인스턴스 생성 후, '참조변수.메서드이름()'으로 호출

- 인스턴스 멤버(iv,im)와 관련된 작업을 하는 메서드

- 메서드 내에서 인스턴스 변수(iv) 사용가능

 

* static 메서드 (클래스메서드) 

  --> 언제 메서드에 static 붙여?  iv를 사용하지 않을 때

- 객체생성없이 '클래스이름.메서드이름()'으로 호출

- 인스턴스 멤버(iv,im)와 관련 없는 작업을 하는 메서드

- 메서드 내에서 인스턴스 변수(iv) 사용불가

class MyMath {
 long a, b;  // iv
 
 long add() {  // 인스턴스 메서드
  return a + b;
 }
 
 static long add(long a, long) { // a와 b는 lv
  return a + b; // lv (가까운쪽 따라)
  }
 }
 
 class MyMathTest {
  public static void main(String[] args) {
   System.out.println(MyMath.add(100L,200L));  // 클래스메서드 호출
   
   MyMath mm = new MyMath();
    mm.a = 100;
    mm.b = 200;
    System.out.println(mm.add());  // 인스턴스메서드 호출
   }
 }

 

Q. static 메서드는 인스턴스 변수 사용가능? - No

Q. static 메서드는 인스턴스 메서드 호출 가능? - No

Q 왜 static 메서드는 인스턴스 멤버를 못 쓰나요? - static 메서드 호출 시 객체(iv묶음)가 없을 수도 있기 때문

 

🚗 (메서드) 오버로딩 (overloading)

- 한 클래스 안에 같은 이름의 메서드를 여러 개 정의하는 것

ex) void println() / void println(char x) / void println(int x) / void println(int x, int y)

 

* 오버로딩이 성립하기 위한 조건

1. 메서드 이름이 같아야 한다.

2. 매개변수의 개수 또는 타입이 달라야 한다.

3. 반환 타입은 영향 없다.

 

ex) int add(int a, int b) { return a+b; } 

     int add(int x, int y) { return x+y; }     --> 오버로딩 X . 메서드 중복정의  오류 ( add(int,int) is already defined. )

ex) long add(int a, long b) { System.out.print("long add(int a, long b) - "); return a+b; }

     long add(long a, int b) { System.out.print("long add(long a, int b) - "); return a+b; } 

   --> 오버로딩 O . 근데 여기서, add(3,3) 을 하면 어떤 메소드가 호출 될까? 

   --> 에러 발생. The method add(int, long) is ambiguous for ~. 

   --> ambiguous 모호하다 / 확실하지않다.

 


🚗생성자 (constructor)

- 인스턴스가 생성될 때마다 호출되는 ' iv 초기화 메서드 (대입문) '

- 인스턴스 생성시 수행할 작업(iv 초기화)에 사용

    ex) Time t = new Time(12, 34, 56);

* 규칙 *

- 이름이 클래스 이름과 같아야 한다.

- 리턴값이 없다. ( void 안붙임 )

- 모든 클래스는 반드시 생성자를 가져야 한다.

 

* 기본 생성자 (default constructor)

- 매개변수가 없는 생성자

- 생성자가 하나도 없을 때만, 컴파일러가 자동 추가 --> 클래스이름( ) { }

생성자가 없는 Data_1을 호출할 때는 에러가 나지 않음 --> 컴파일러가 기본생성자를 자동으로 추가해주기 때문에. / 하지만 Data_2를 호출할 때는 에러 발생
Data_2 기본생성자 추가 --> 에러 해결

 

* 매개변수가 있는 생성자

Car(String c, String g, int d) {
 color = c;
 gearType = g;
 door = d;
 }

--> Car c = new Car("white", "auto", 4);

  순서) 참조변수 만들어짐 Car c -> 객체 생성 new -> 생성자 호출, iv 초기화 Car(..) -> 객체의 주소 대입 (연결) =

 

* 생성자 this()

- 생성자에서 다른 생성자 호출할 때 사용

- 다른 생성자 호출시 첫 줄에서만 사용가능

Class Car {
 String color;
 String gearType;
 int door;
 
// Car() {
//  color = "white";
//  gearType = "auto";
//  door = 4;
// --> 코드의 중복을 제거해보자
 Car() {
  this("white","auto",4);
  }
  
 Car(String c, String g, int d) {
  color = c;
  gearType = g;
  door = d;
 }
}

 

* 참조변수 this

- 인스턴스 자신을 가리키는 참조변수

- 인스턴스 메서드(생성자 포함)에서 사용가능

- 지역변수(lv)와 인스턴스 변수(iv)를 구별할 때 사용

Car(String color, String gearType, int door) {
	// this.color는 iv, color는 lv
    this.color = color;
    this.gearType = gearType;
    this.door = door;
   }

 

 


🚗변수의 초기화

 

- 지역변수(lv)는 사용전, 수동 초기화 해야함

 

* 멤버변수(iv, cv)의 초기화

1. 자동 초기화

2. 간단 초기화

   --> 명시적 초기화(=)

class Car {
 int door = 4;            // 기본형 변수의 초기화
 Engine e = new Engine(); // 참조형 변수의 초기화

 

3. 복잡 초기화

--> 초기화 블럭 / 생성자

- iv) 인스턴스 초기화 블럭 : { 여러문장 넣기 }  --> 잘 안써.

- cv) 클래스 초기화 블럭 : static { 여러문장 넣기 }

- iv) 생성자 

 

* 초기화 시점

- cv : 클래스가 처음 로딩될 때 ( 메모리에 올라갈 때) 단 한번!

- iv : 인스턴스가 생성될 때 마다!

- 순서) 1. cv -> iv

         2. 자동 -> 간단 -> 복잡

 


🚗 클래스간의 관계

 

1. 상속 ( Inheritance )

- 관계 결정 : ~은 ~이다. ( is - a )

- 기존의 클래스로 새로운 클래스를 작성하는 것. (코드의 재사용)

- 두 클래스를 부모와 자식으로 관계를 맺어주는 것.

- class 자식클래스 extends 부모클래스

- 자손은 조상의 모든 멤버를 상속받는다. (생성자, 초기화블럭 제외)

- 자손의 멤버 개수는 조상보다 적을 수 없다. (같거나 많다.) --> 확장(extends)의 개념!!

- 자손의 변경은 조상에 영향을 미치지 않는다.

 

2. 포함 관계

- 관계 결정 : ~은 ~을 가지고 있다. ( has - a )   --> 이 경우가 더 많다.

- 클래스의 멤버로 참조변수를 선언하는 것

- 작은 단위의 클래스를 만들고, 이들을 조합해서 클래스를 만든다.

 

* 단일 상속

- 자바는 단일상속만을 허용한다. (c++은 다중상속 허용 -> 충돌문제 존재)

- 비중이 높은 클래스 하나만 상속관계로, 나머지는 포함관계로 하면 다중상속의 효과를 낼 수 있다.

- 부모가 없는 클래스는 자동적으로 Object 클래스를 상속받게 된다.

    --> 모든 클래스는 Object클래스에 정의된 11개의 메서드를 상속받는다.