[Section 1] JAVA 객체지향 프로그래밍 기초

2023. 4. 25. 20:36· CodeStates 45th
목차
  1. 1. 클래스(Class)와 객체(Object)
  2. 2. 필드(Field)와 메서드(Method)
  3. 3. 생성자(Constructor)
  4. 4. 내부 클래스 (Inner Class)

1. 클래스(Class)와 객체(Object)
2. 필드(Field)와 메서드(Method)
3. 생성자(Constructor)
4. 내부 클래스(Inner Class)

 

1. 클래스(Class)와 객체(Object)

 

클래스

객체를 설계한 설계도 또는 틀

객체를 생성하는 데 사용

 

 

인스턴스

클래스를 통해 생성된 객체

 

 

인스턴스화

클래스로부터 객체를 만드는 과정

 

 

객체와 인스턴스의 차이

  • 객체: 모든 인스턴스를 포괄하는 넓은 의미
  • 인스턴스: 해당 객체가 어떤 클래스로부터 생성된 것인지를 강조

 

클래스의 네 가지 요소

  1. 필드: 클래스 속성을 나타내는 변수 ex- 차 모델명, 컬러, 바퀴 수 
  2. 메서드: 클래스 기능을 나타내는 함수 ex- 시동하기, 가속하기, 정지하기
  3. 생성자: 클래스 객체를 생성하는 역할
  4. 이너 클래스: 클래스 내부의 클래스 

 

 

 

 

객체

 

객체의 구성요소

  1. 속성- 필드
  2. 기능- 메서드

 

속성 → 변수

(1) 컴퓨터 모델 이름
(2) 메모리 사양
(3) 출시일
(4) 색상
기능 → 메서드

(1) 시스템 ON
(2) 기록 저장
(3) 시스템 OFF

 

class Computer {
    private String modelName; // 컴퓨터 모델 이름
    private int ram; // 메모리 사양
    private int releaseDate; // 출시일
    private String color; // 색상

    void on(){} // 시스템 ON
    void save(){} // 기록 저장
    void off(){} // 시스템 OFF
}

 

 

객체의 생성

- new 키워드로 생성

- new 키워드는 생성된 객체를 힙 메모리에 넣으라는 의미를 가짐

 

클래스명 참조_변수명 = new 생성자();

 

- 참조 변수는 실제 데이터 값을 저장하는 것이 아닌 실제 데이터가 위치해 있는 힙 메모리 주소를 저장하는 변수임

- new 키워드와 생성자를 통해 객체를 생성한다는 것: 해당 객체를 힙 메모리에 넣고 그 주소값을 참조 변수에 저장하는 것

 

 

 

 

클래스 Book과 참조변수 b는 각각 클래스 영역과 스택 영역 다른 위치에 저장된다.

생성자로 만들어진 인스턴스는 힙 메모리에 들어가며 객체 내부에는 클래스의 멤버들이 위치한다.

 

참조변수는 객체의 실제 값이 아닌 힙에 저장되어있는 주소값을 가리키게 된다.

 

 

 

 

 

2. 필드(Field)와 메서드(Method)

 

필드(Field)

"클래스에 포함된 변수"

객체의 속성을 정의할 때 사용

 

 

 

 

자바에서 변수는 크게 3가지로 구분한다.

1. 클래스 변수 

2. 인스턴스 변수

3. 지역 변수

 

 

 

 

필드는 클래스 변수와 인스턴스 변수를 말한다.

그리고 이 둘은 다시 static 키워드의 유무로 구분할 수 있다.

 

 

 

 

클래스 변수 (필드 변수)

- static 키워드와 함께 선언된 것

- 공통된 저장 공간 공유 (고유한 특성 저장 시 사용)

- 인스턴스를 따로 생성하지 않더라도 클래스명, 클래스변수명을 통해 사용 가능

 

 

인스턴스 변수 (필드 변수)

- 그렇지 않은 것 (staic 키워드 선언하지 않음)

- 인스턴스가 가지는 각각의 고유한 속성을 저장하기 위한 변수로 new 생성자()를 통해 인스턴스 생성 시 만들어진다.

 

 

지역 변수

- 위 두 가지 변수 유형에 포함되지 않고 메서드 내에 포함된 모든 변수

- 메서드 내 블록에서만 사용 가능

- 스택 메모리에 저장되어 메소드가 종료되는 것과 함께 소멸되어 더이상 사용할 수 없음

 

 

class Example { // => 클래스 영역
	int instanceVariable; // 인스턴스 변수
	static int classVariable; // 클래스 변수(static 변수, 공유변수)

	void method() { // => 메서드 영역
		int localVariable = 0; // 지역 변수. {}블록 안에서만 유효
	}
}

 

 

 


필드 변수 (클래스 변수, 인스턴스 변수)

 

- 힙 메모리에 저장되어 객체가 사라지지 않는 한 절대로 삭제되지 않음
- 직접 초기화하지 않아도 강제로 초기화가 이루어짐
그 이유는 힙 메모리에는 빈 공간이 저장될 수 없어 강제로 초기화 되는 것

 

 

지역 변수

- 스택 메모리에 저장되어 한동안 사용되지 않는 경우 가상머신에 의해 자동으로 삭제됨
- 직접 초기화하지 않으면 값 출력 시 오류 발생
그 이유는 스택 메모리에는 강제로 초기화되지 않으므로 반드시 초기화를 해줘야 함

 

 

 

public class Main {
    public static void main(String[] args) {
        Car car1 = new Car();
        Car car2 = new Car();

        // Car class 에 있는 클래스 변수의 값은 모두 변함
        // 왜냐하면 static 으로 선언한 클래스 변수는 메모리에 있는 모든 객체들과 메모리를 공유하기 때문이다.
        car1.classNum = "저는 클래스 변수입니다.";

        // 저는 클래스 변수입니다.
        System.out.println(car1.classNum);
        // 저는 클래스 변수입니다.
        System.out.println(car2.classNum);
        // 저는 클래스 변수입니다.
        System.out.println(Car.classNum);



        car1.instanceNum = "저는 인스턴스 변수입니다.";

        // 저는 인스턴스 변수입니다.
        System.out.println(car1.instanceNum);
        // 나는 인스턴스 변수
        System.out.println(car2.instanceNum);

        /*
            static 변수는 모든 객체가 모두 영향을 받음
            instance 변수는 해당 객체만 영향을 받음
        */
        
    }

}

class Car{
    public String instanceNum = "나는 인스턴스 변수";
    public static String classNum = "나는 클래스 변수";

    // static- 정적: 메모리에 있는 모든 객체들과 데이터를 공유하기 위해서 사용
    // 클래스 메서드
    public static void classMethod(){
        System.out.println("인스턴스 변수");
        System.out.println("클래스 변수");
    }

    // 인스턴스 메서드
    public void instanceMethod(){
        // System.out.println("인스턴스 변수");
        System.out.println("클래스 변수");
    }
}

 

위의 코드가 동작하는 것처럼 static 키워드를 사용하면 모든 인스턴스에 공통적으로 적용되는 값을 공유할 수 있다.
즉, 값을 변경할 때 static 변수는 모든 객체가 영향을 받으며, instance 변수는 값을 변경한 객체만 영향을 받는다.

 

 

 

 

 

메서드

특정 작업을 수행하는 일련의 명령물들의 집합

 

 

메서드 시그니처에 필요한 정보

  1. 메서드가 어떤 타입을 반환하는가
  2. 메서드 이름이 무엇인가
  3. 해당 작업을 수행하기 위해 어떤 재료들이 필요한가

 

public static int add(int x, int y) { // 메서드 시그니처
	int result = x + y; // 메서드 바디
	return result;
}

 

 

 

 

 

메서드의 호출

- 메서드도 클래스 멤버이므로 클래스 외부에서 메서드를 사용하기 위해서는 인스턴스를 생성해줘야 함

- 인스턴스를 생성한 후에는 포인트 연산자(.)를 통해 메서드를 호출할 수 있음

 

- 클래스 내부에 있는 메서드끼리는 따로 객체 생성 없이 서로를 호출할 수 있음

 

- 인자(argument): 메서드 호출 시 괄호() 안에 넣어주는 입력값

- 인자의 개수와 순서는 메서드를 정의할 때 선언된 매개변수와 무조건 일치해야 함

 

 

 

 

 

메서드 오버로딩

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

 

public class Overloading {
    public static void main(String[] args) {
        Shape s = new Shape(); // 객체 생성

        s.area(); // 메서드 호출
        s.area(5);
        s.area(10,10);
        s.area(6.0, 12.0);
    }
}

class Shape {
    // 메서드 오버로딩. 같은 이름의 메서드 4개.
    public void area() {
        System.out.println("넓이");
    }
    public void area(int r) {
        System.out.println("원 넓이 = " + 3.14 * r * r);
    }

    public void area(int w, int l) {
        System.out.println("직사각형 넓이 = " + w * l);
    }

    public void area(double b, double h) {
        System.out.println("삼각형 넓이 = " + 0.5 * b * h);
    }
}

 

여기서 무조건 같은 메서드명을 사용한다고 해서 오버로딩이 되는 것은 아니다.

 

 

오버로딩이 성립되기 위해 필요한 두 가지 조건

1. 같은 이름의 메서드명을 써줘야 한다.

2. 매개변수의 개수나 타입이 다르게 정의되어야 한다.

 

+ 반환 타입은 오버로딩이 성립하는 데에 영향을 주지 못한다. (가상 머신이 다른 메서드라 인식하지 못함)

 

 

 

오버로딩의 가장 큰 장점은 하나의 메서드로 여러 경우의 수를 해결할 수 있다는 것

 

 

 

 

3. 생성자(Constructor)

 

생성자

변수들을 초기화하는데 사용되는 특수한 메서드

 

 

생성자의 조건

- 생성자의 이름과 클래스 이름은 동일해야 함

- 생성자는 리턴 타입이 없음 (그렇다고 void 키워드를 사용하는 것은 아니다.)

 

public class ConstructorExample01 {
    public static void main(String[] args) {
        Constructor constructor1 = new Constructor();
        Constructor constructor2 = new Constructor("hello");
        Constructor constructor3 = new Constructor(1, 2);
    }
}

class Constructor {
    Constructor() { // (1) 생성자 오버로딩
        System.out.println("1번 생성자");
    }

    Constructor(String str) { // (2)
        System.out.println("2번 생성자");
    }

    Constructor(int a, int b) { // (3)
        System.out.println("3번 생성자");
    }
}

 

 

 

기본 생성자

 

클래스명(){} //기본 생성자

DefaultConst(){} // 예시) DefaultConst 클래스의 기본 생성자

 

 

 

매개변수가 있는 생성자

 

public class ConstructorExample02 {
    public static void main(String[] args) {
        Car c = new Car("Model X", "빨간색", 250);
        System.out.println("제 차는" + c.getModelName() + "이며, 컬러는 " + c.getColor() + "입니다.");
    }
}

class Car{
    private String modelName;
    private String color;
    private int maxSpeed;

    public Car(String modelName, String color, int maxSpeed){
        this.modelName = modelName;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }

    public String getModelName(){
        return modelName;
    }

    public String getColor(){
        return color;
    }
}

 

Car 인스턴스 생성 시 매개변수가 있는 생성자를 사용하게 되면 인스턴스를 만든 후에 인스턴스의 필드 값을 일일이 설정할 필요 없이 생성과 동시에 원하는 값으로 설정할 수 있다.

 

기본 생성자의 경우 매개변수가 없었기에 원래 객체를 생성하던 방식으로 new 키워드와 생성자를 호출하면 되었지만

매개변수가 있는 경우에는 그 개수와 타입에 맞게 생성자를 호출해주어야 한다.

 

 

 


 

 

 

this()

- 자신이 속한 클래스에서 다른 생성자를 호출하는 경우 에 사용

- 반드시 생성자의 내부에서만 사용

- 반드시 생성자의 첫 줄에 위치해야 함

 

public class ThisMethod {
    public static void main(String[] args) {
        Example example1 = new Example();
        Example example2 = new Example(5);
    }
}

class Example{
    public Example(){
        System.out.println("Example의 기본 생성자 호출");
    };

    public Example(int x){
        this(); // this() 메서드를 통해 기본 생성자를 호출한다.
        System.out.println("Example의 두 번째 생성자 호출");
    }
}

 

 

this 키워드

 

public class ConstructorExample {
    public static void main(String[] args) {
        Car car = new Car("Jeonni", "초록색", 230);
        System.out.println("제 이름은  " + car.getName() + "이고, 좋아하는 색은 " +  car.getColor() + "입니다.");
    }
}

class Car {
    private String name;
    private String color;
    private int size;

    public Car(String name, String color, int size) {
        this.name = name;
        this.color = color;
        this.size = size;
    }

    public String getName() {
        return name;
    }

    public String getColor() {
        return color;
    }
}

 

인스턴스 변수로 name, color, size가 선언됨과 동시에 생성자의 매개변수로 name, color, size가 정의되어 있다.

 

이런 경우에 인스턴스와 매개변수를 이름만으로 구분하기 어려워지는 문제가 발생한다.

이를 구분하기 위한 용도로 자주 사용되는 방법이 this 키워드이다.

 

예를 들어 위의 코드에서 this.name = name 대신 name=name 으로 작성시엔 둘 다 지역변수로 간주한다.

모든 메서드에는 자신이 포함된 클래스의 객체를 가리키는 this 참조변수가 있지만, 일반적으로 컴파일러가 this.를 추가해주기 때문에 생략하는 경우가 많다.

 

결론적으로 this는 인스턴스 자신을 가리키며, 우리가 참조변수를 통해 인스턴스의 멤버에 접근할 수 있는 것처럼

this를 통해 인스턴스 자신의 변수에 접근할 수 있는 것이다. 주로 인스턴스 필드명과 지역변수를 구분하기 위한 용도로 사용된다.

 

 

 

 

 

 

4. 내부 클래스 (Inner Class)

 

 

내부 클래스

클래스 내에 선언된 클래스

외부 클래스와 내부 클래스가 서로 연관되어 있을 때 사용

객체지향의 중요 핵심인 캡슐화 달성에 유용

 

 

class Outer { // 외부 클래스
	
	class Inner {
		// 인스턴스 내부 클래스	
	}
	
	static class StaticInner {
		// 정적 내부 클래스
	}

	void run() {
		class LocalInner {
		// 지역 내부 클래스
		}
	}
}

 

기본적으로 내부 클래스는 외부 클래스 내에 선언된다는 점을 제외하면 일반 클래스와 차이점이 없다.

단순히 외부 클래스와 내부 클래스가 서로 연관되어 있을 때 사용의 편의성을 고려하여 만들어진 문법이다.

 

 

 

인스턴스 내부 클래스

 

class Outer { // 외부 클래스
    private int num = 1; // 외부 클래스 인스턴스 변수
    private static int sNum = 2; // 외부 클래스 정적 변수
    private InClass inClass; // 내부 클래스 자료형 변수 선언

    public Outer() {
        inClass = new InClass(); // 외부 클래스 생성자
    }

    class InClass { // 인스턴스 내부 클래스
        int inNum = 10; // 내부 클래스 인스턴스 변수

        void Test() {
            System.out.println("Outer num = " + num);
            System.out.println("Outer sNum = " + sNum);
        }
    }

    public void testClass() {
        inClass.Test();
    }
}


public class Main {
    public static void main(String[] args) {

        Outer outer = new Outer();
        System.out.println("외부 클래스 사용하여 내부 클래스 기능 호출");
        outer.testClass(); // 내부 클래스 기능호출
    }
}

 

인스턴스 내부 클래스는 반드시 외부 클래스를 만든 후에 사용해야 한다.

따라서 클래스 생성과 상관 없이 사용할 수 있는 정적 변수와 정적 메서드는 인스턴스 내부 클래스에 선언할 수 없다.

 

 

정적 내부 클래스

 

class Outer {
    private int num = 20; // 외부 클래스 인스턴스 변수
    private static int sNum = 10; // 외부 클래스 정적 변수

    void getPrint() {
        System.out.println("인스턴스 메서드");
    }

    static void getPrintStatic() {
        System.out.println("스태틱 매서드");
    }

    static class StaticInClass { // 정적 내부 클래스
        void test() {
            System.out.println("Outer sNum = " + sNum);
            getPrintStatic();
            // num과 getPrint()는 정적 멤버가 아니기 때문에 사용 불가능
        }
    }
}


public class Main {
    public static void main(String[] args) {
        Outer.StaticInClass a = new Outer.StaticInClass();
        a.test();
    }
}

 

 

지역 내부 클래스

 

- 클래스의 멤버가 아닌 메서드 내에 정의되는 클래스

 

class Outer { // 외부 클래스 
    int num1 = 10;

    void test() {
        int num2 = 20;
        class LocalInClass { // 지역 내부 클래스
            void getPrint() {
                System.out.println(num1);
                System.out.println(num2);
            }
        }

        LocalInClass localInClass = new LocalInClass();
        localInClass.getPrint();
    }
}


public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.test();
    }
}

 

지역 내부 클래스인 LocalInClass가 메서드 안에서 선언된 후, 정의된 메서드를 호출하여 외부 클래스의 변수들을 출력한다.

 

 

 

 

'CodeStates 45th' 카테고리의 다른 글

[Section 2] Spring Framework 기본  (0) 2023.05.21
[Section 1] 회고  (2) 2023.05.09
[Section 1] Git 기초 - 회고록  (0) 2023.04.24
[Section 1] Git 기초  (0) 2023.04.18
[Section 1] Development 기초  (0) 2023.04.12
  1. 1. 클래스(Class)와 객체(Object)
  2. 2. 필드(Field)와 메서드(Method)
  3. 3. 생성자(Constructor)
  4. 4. 내부 클래스 (Inner Class)
'CodeStates 45th' 카테고리의 다른 글
  • [Section 2] Spring Framework 기본
  • [Section 1] 회고
  • [Section 1] Git 기초 - 회고록
  • [Section 1] Git 기초
jeonniu
jeonniu
주니어 개발자의 기록하는 습관 기르기.. 👩🏻‍💻
jeonniu
my records
jeonniu
전체
오늘
어제
  • 분류 전체보기 (43)
    • New (3)
    • Study (23)
    • Algorithm (2)
    • Project (2)
    • Solution (2)
    • CodeStates 45th (11)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기
  • 설정

공지사항

인기 글

태그

  • multithreading
  • 가비지 컬렉터
  • mysql
  • aggregate
  • Synchorunous
  • UCP
  • 스프링부트
  • 3 paradigms
  • springboot
  • 아키텍처 패턴
  • Java
  • TCP/IP 4계층
  • Asynchrounous
  • Long Polling
  • data Binding
  • @Repository
  • 컴포넌트 스캔
  • aggregate root
  • @Service
  • EC2
  • spring
  • Spring Data JDBC
  • in-memory db
  • MVC
  • 프로그래밍 패러다임
  • 객체지향프로그래밍
  • JPA
  • chat GPT
  • 백엔드
  • AWS

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
jeonniu
[Section 1] JAVA 객체지향 프로그래밍 기초
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.