천천히 빛나는

Java 기초 : 객체 본문

JAVA/JAVA

Java 기초 : 객체

까만콩 •ᴥ• 2023. 7. 28. 17:43

객체 지향 언어의 4대 특징

1) 추상화 : 필요한 부분만 고려하여 복잡한 시스템을 역할에 따라 나누어 단순화할 수 있다

2) 캡슐화 : 객체 내부 작동 방식을 노출하지 않고 작업을 수행한다

3) 상속 : 유사한 기능을 가진 코드를 재사용할 수 있다

4) 다형성 : 정해진 규약에 따라 구현된 객체들을 활용하여 유연하고 확장 가능한 코드를 작성할 수 있다

 

이 부분이 지금 당장 이해되지 않아도 괜찮습니다!

 

 

클래스 (Class)

객체의 속성과 기능을 추상화한 것으로 인스턴스 (객체)를 생성할 목적으로 작성해놓은 소스코드 작성단위이다

class Student {
    // Student의 속성(관리 해야 될 다양한 자료형의 상태값)
    int studentId;
    String name;
    char gender;
    String major;
    int grade;
    String phone;
    String email;
    
    // Stduent의 기능
    public void signUpFor(String subject) {
        System.out.println(subject + " 과목을 신청합니다");
        ...
    }
    public String test(String subject, int semester, int ordinal, String result) {
        System.out.println(subject + " 과목의: " + semester + "학기의 " + ordinal + "번째 시험을 치릅니다.";
        ...
        return result; 
    }
    ...
}

예시) 대학생 (Student라는 참조 자료형을 선언)

속성: 학번, 이름, 성별, 대학생의 학과, 학년, 전화번호, 이메일

기능: 수강 신청을 한다, 시험을 치른다 등

 

 

Student s = new Student();

클래스와 new 연산자를 통해 메모리 공간에 객체를 할당할 수 있다. 메모리 공간에 할당하는 것인스턴스화(Instantiation)이라고 하고 할당 된 객체인스턴스(Instance)라고 부른다.

여기서 인스턴스는 대학생 한명 한명을 뜻한다

 

class Calculator {
    static double PI = 3.14; // 클래스 변수
    static int base = 0; // 클래스 변수
    int left, right; // 인스턴스 변수
    public void setOprands(int left, int right){
    // 더하기에 base의 값을 포함시킨다.
        this.left = left;
        this.right = right;
    }

    public void sum(){
        System.out.println(this.left + this.right + base);
    }

    public void avg(){
        System.out.println((this.left + this.right)/2);
    }
}

public class Number {
    public static void main(String[] args) {
        Calculator c1 = new Calculator(); // 객체
        c1.setOprands(10, 20);
        c1.sum();
        c1.avg();
        // 인스턴스를 통해서 PI에 접근
        System.out.println(c1.PI);
        // 클래스를 통해서 PI에 접근
        System.out.println(Calculator.PI);
        Calculator.base = 10; // 변경 가능
    }
}

 

static 변수는 클래스 변수가 된다는 뜻이다. PI라는 클래스 변수는 모든 인스턴스에서 동일한 값을 가지게 된다.

값의 변경사항을 모든 인스턴스가 공유해야 하는 경우에도 사용할 수 있다.

 

public class Member {
    String id;
    String pwd;

    public void print() {
        System.out.println("Member 클래스");
    }
}
public class Main {
    public static void main(String[] args) {
        Member m = new Member();
        m.id = "blackbean";
        m.pwd = "1234a";
        System.out.println(m.id);
        System.out.println(m.pwd);
        m.print();
    }
    
    public static Member returnMember (Member m){
        return m;
    }
}

또다른 예시이다. 이와 같이 객체를 생성하고 선언해주었다.

 

 

캡슐화

public class Monster {
    String name;
    private int hp;

    public void setHp(int hp) {
        if(hp>=0) {
            System.out.println("양수값이 입력^^");
            this.hp = hp;
        }
        else {
            // this.hp = 0; // 기본자료형 int의 기본값은 0이므로 굳이 설정할 필요가 없다
            System.out.println("음수입력해서 0으로 설정^^;");
        }
    }
}

직접 변수 hp에 접근하지 않고 setHp 함수를 통해서만 접근할 수 있도록 하였다

 

메소드 호출 시 내부의 this : 메소드를 호출하는 인스턴스(인스턴스의 주소)를 가리킨다.

생성자나 메소드의 매개변수명과 인스턴스의 필드명이 같을 경우 매개변수명이 우선이므로 this을 자동으로 생성해 주지 않아 필드를 구분하는 용도로 사용될 때는 반드시 명시해 주어야 한다.

 

private : 해당 클래스 안에서만 직접 접근할 수 있도록 설정 (캡슐화)

 

구분 같은 클래스 같은 패키지 자식 클래스 전체
public O O O O
protected O O O  
(default) O O    
private O      

어디까지 접근이 가능한지 나타내주는 표이다. 예를 들어 private은 같은 클래스 안에서만 접근 가능하다

 

 

생성자

new 연산자를 활용하여 클래스의 인스턴스를 생성 시 1회성으로 호출되는 리턴 타입이 없는 메소드

로 필드 초기화 목적으로 주로 사용

[접근제어자] [예약어] class 클래스명 {

    // 클래스의 필드(클래스의 속성)
		
    [접근제어자] 클래스명() {}
    [접근제어자] 클래스명(매개변수) {(this.)필드명 = 매개변수;}

    // 클래스의 메소드(클래스의 기능)
}

접근제어자: public, default만 가능

 

public class Monster {
    private String name;
    private int hp;

    public Monster(){
        System.out.println("생성자");
        this.name = "임시이름";
        this.hp = 100;
    }
}

생성자는 반드시 클래스 이름과 동일해야 한다. 또한 생성자는 반환형을 명시하지 않는다.

Monster m = new Monster("드라큘라", 100);

인스턴스 생성과 동시에 값 초기화도 가능하다

 

public User(String id, String pwd, String name){
	this(id, pwd); // 다른 생성자 사용해서 초기화
	this.name = name;
}

생성자는 다른 생성자를 이용할 수도 있다. 두개 이상은 안되며 첫줄에 작성해야지만 가능하다.

 

오버로딩

동일한 메소드명으로 다른 기능을 하는 메소드들을 활용하기 위해 사용하는 기술

매개변수를 다르게 해서 같은 이름의 메소드를 여러개 만들 수 있다

 

가변인자

타입 뒤에 ...을 붙여 표시하는 매개변수

해당 타입의 값을 0개 이상 받거나 아니면 해당 타입의 배열의 주소값을 받을 수 있는 매개변수

public void testVariable(String... hobby){
	for(int i = 0; i<hobby.length; i++){
		System.out.print(hobby[i] + " ");
	}
}
pt.testVaiable();
pt.testVaiable("농구");
pt.testVaiable("뜨개질", "음악듣기");
pt.testVaiable(new String[] {"축구", "테니스", "서예"});

가변인자는 반드시 매개변수 선언 마지막에 작성해야 한다

 

 

Final

변경 불가의 의미를 담고 있는 키워드

따라서 초기 인스턴스(객체)가 생성되고 나면 기본값 0이 필드에 들어가게 되는데, 그 초기화 이후 값을 변경할 수 없기 때문에 선언하면서 바로 초기화를 해주어야 한다

private final int TEST; // 에러, 생성자 있으면 생성자에서 초기화 해주면 됨
private final int TEST = 1;

클래스 필드의 final 변수는 선언과 동시에 초기화 하거나 생성자를 통한 초기화를 해야 한다.

 

 

Static

클래스 인스턴스를 생성하지 않더라도 static 변수는 메모리가 할당이 되어버리기 때문에 생성자에서 초기화해주는 것이 불가능하다

private static final int TEST; // 에러, 생성자 초기화도 의미 없음
private static final int TEST = 1;
private final static int TEST = 1;
public class KindOfVariable{
    private static int staticNum; // 정적필드, static field
    private int globalNum; // 전역변수, 인스턴스 변수(non-static)
    
    public void testMethod(int num){
        int localNum = 1; // 초기화 필수
        
        System.out.println(kindsOfVariable.staticNum); // 인스턴스 없이 쓸수 있는 전역 변수
        System.out.println(staticNum); // 같은 클래스라서 클래스 이름 생략 가능
    }
    
    public void testMethod2(){
        System.out.println(globalNum);
        System.out.println(staticNum);
        // System.out.println(localNum); // 오류 발생
    }

    public static void main(){
        KindsOfVariable kov = new KindsOfVaraible();
        kov.testMothod(1);
    }
}

 

클래스 로딩 과정

클래스 로더가 .class 클래스 파일의 위치를 찾아 클래스영역(=정적영역)에 올려놓는 과정

JVM을 실행할 때 (프로그램을 실행할 때) 이미 static이 붙은 필드나 메소드는 따로 호출하지 않아도 클래스 영역에 로딩된다

 

 

초기화 블럭

어떤 생성자든 상관없이 공통적인 로직이 필요할 때 사용

인스턴스 변수
클래스 변수

private static String brand;
private String name;

{
    name = "Amy";
    Product.brand = "삼성";
}

static {
    Product.brand = "삼성";
}

 

'JAVA > JAVA' 카테고리의 다른 글

Java 기초 : 상속  (0) 2023.07.31
Java 기초 : Enum과 객체 배열  (0) 2023.07.30
Java 기초 : 정리본 (1)  (0) 2023.07.27
Java 기초 : 배열  (0) 2023.07.27
Java 기초 : 제어문  (0) 2023.07.25