클래스와 객체

박상윤·2022년 8월 15일

📌 객체지향 프로그래밍(OOP)

문제 혹은 로직을 객체 단위로 나눠서 작성하는

  • 절차지향 프로그래밍과 반대의 개념 X

객체들이 서로 유기적으로 상호작용하는 프로그래밍
ex) 자동차(객체) = 데이터(바퀴,핸들,차체 등) + 기능(주행보조기능, 길찾기 기능)

📌 OOP의 특징

캡슐화

  • 데이터의 구조와 기능을 하나의 캡슐형태로 만들어 외부에서는 형태를 알 수 없도록 하는 방법

추상화

  • 객체의 공통적인 필드와 기능을 하나의 형태로 정의하는 설계 방법

상속

  • 하위 클래스에서는 상속 받은 상위 클래스의 기능 사용을 할 수도 있고, 하위 클래스 자체에 새로운 기능을 추가할 수 있는것

다형성

  • 객체가 상속을 통해 기능을 확장하거나 변경하여 다른형태로 재구성되는 것(오버로딩/오버라이딩)

📌 OOP의 장점

  • 코드 재사용성 증가
  • 생산성 향상
  • 유지보수가 쉬움

📌 OOP의 장점

  • 개발 속도가 느림
  • 실행 속도가 느림
  • 코드의 난이도 상승

📌 클래스

📍 클래스 정의

  • 객체의 설계도
  • 사용자 정의 타입
  • 데이터와 기능의 결합

📍 클래스 용도

  • 객체를 생성하는 용도

📌 객체

📍 객체 정의

  • 클래스의 정의된 내용에 맞춰 메모리에 생성된 형태

📍 객체 용도

  • 정의한 클래스 내용에 따라 속성과 기능이 다르다.

📍 객체와 인스턴스

인스턴스화 하는 과정

📍 인스턴스 생성과 사용

package chapter6;

class Student {
    private int age = 19;

    public String getAddress() {
        return "경기도";
    }

    public int getAge(){
        return age;
    }
}

public class ObjectCreation {
    public static void main(String[] args) {
        Student Lil = new Student();

        System.out.println(Lil.getAddress());
        System.out.println(Lil.getAge());
    }
}

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

package chapter6;

public class VariableType {
    
    // class variable
    static String subject = "Korean";
    
    // instance variable
    int score;
    String studentName;
    
    public boolean isPass(){
        // local variable
        boolean isPass = (score/50)>0?true:false;
        return isPass;
    }
}

📍 변수 초기화

변수를 선언하고 최초로 값을 지정하는 것

  • 멤버번수(클래스 변수, 인스턴스 변수)는 초기화 생략 가능
  • 지역 변수는 반드시 초기화 해주어야 한다.

멤버변수 초기화 방법
1. 명시적 초기화
2. 초기화 블록
3. 생성자

package chapter6;

class Car {
	// 명시적 초기화
    static String brand = "람보르기니";

    int speed;
    String carname;

	// 초기화 블록으로 초기화
    {
        speed = 140;
    }

	// 생성자
    Car(String carname, int speed) {
        this.speed = speed;
        this.carname = carname;
    }

    public String getCar(){
        return "브랜드:"+ brand + " speed:" + speed + " carname:" + carname;
    }
}

public class VariableInitialization {
    public static void main(String[] args) {
        Car car1 = new Car("버전2",250);

        System.out.println(car1.getCar());
    }
}

출력결과

📌 생성자(constructor)란?

new키워드로 인스턴스를 생성할 때, 제일 먼저 실행되는 메소드

  • 클래스의 이름과 동일한 이름이여야 한다.
  • 반환 값은 없지만 void형으로 적어주면 안된다.
  • 기본 생성자 외에 여러 개의 생성자를 가질 수 있다.

📍 기본 생성자

매개변수가 없고, 어떤 실행문도 없는 생성자

  • 모든 클래스에는 반드시 하나 이상의 생성자가 정의
  • Java complier가 어떤 생성자도 없을 때 기본적으로 추가해준다.
  • 어떤 생성자가 있으면, complier가 기본 생성자는 별도로 추가하지 않는다.
package chapter6;

class Lesson {
    int score = 100;
    String studentname = "Java";

    public int getScore(){
        return score;
    }

    public String getStudentName(){
        return studentname;
    }
}

public class DefaultConstructor {
    public static void main(String[] args) {
        Lesson lesson = new Lesson(); // 기본 생성자 호출
        System.out.println(lesson.getScore());
        System.out.println(lesson.getStudentName());
    }
}

📍 매개변수가 있는 생성자

메서드처럼 매개변수를 인자로 받아 인스턴스 초기화에 값을 사용할 수 있는 생성자

  • 인스턴스 생성 후, set 메소드를 호출해주는 것보다 간결한 코드
package chapter6;

class User{
    int userId;
    String userName;

    User(int userId, String userName){
        this.userId = userId;
        this. userName = userName;
    }

    public int getUserId(){
        return userId;
    }

    public String getUserName(){
        return userName;
    }
}

public class ArgumentConstructor {
    public static void main(String[] args) {
        User user = new User(1234,"minou");

        System.out.println(user.getUserId());
        System.out.println(user.getUserName());
    }
}

📍 this()와 this 키워드

this()

  • 같은 클래스 내부의 다른 생성자를 호출할때 사용
  • 생성자 첫 문장에서만 가능

this

  • 인스턴스 자신을 가르키는 참조변수
  • 인스턴스의 주소가 저장, 숨겨진 채로 존재
  • static 메서드에서는 사용 불가
package chapter6;

import java.lang.constant.Constable;

class Phone{
    String phoneVersion;
    String phoneName;

    Phone(String phoneName){
    	//this()
        this("A"+System.currentTimeMillis(),phoneName);
    }

    Phone(String phoneVersion, String phoneName){
        this.phoneVersion = phoneVersion;
        this.phoneName = phoneName;
    }

    public String getPhoneId(){
        return phoneVersion;
    }

    public String getPhoneName(){
        return phoneName;
    }
}

public class thisKeyword {
    public static void main(String[] args) {
        Phone iphone = new Phone("iphone5");

        System.out.println(iphone.getPhoneName());
        System.out.println(iphone.getPhoneId());

    }
}

📌 메소드(Method)란?

어떤 특정한 기능을 수행하기 위한 명령문들의 집합체

구성요소

  • 선언부
  • 구현부

📍 선언부

접근 제어자, static/final keyword, 메소드 이름, 매개변수 선언, 반환타입으로 구성

📍 구현부

  • 지역변수, 수행될 실행문, return문으로 구성
  • void형일 경우 return문이 없음
package chapter6;

public class MethodExample {

    // 선언부
    public static  int add(int a, int b){

        // 구현부
        int sum = 0;
        sum = a+b;
        return sum;
    }

    public static void main(String[] args) {
        System.out.println(add(1,2));
    }
}

📍 매개변수의 종류

메서드에서 넘겨받는 매개변수의 종류는 크게 두가지

  • 기본형 매개변수 : 기본 데이터형으로 넘겨 받는 매개변수, 읽기만 가능
  • 참조형 매개변수 : 인스턴스의 주소를 넘겨 받는 매개변수, 읽고 변경 가능

📍 반환값의 종류

  • 기본형 반환 값 : 기본형을 반환하는 것은 기본형 데이터를 반환
  • 참조형 반환 값 : 참조형을 반환한다는 뜻은 객체의 주소를 반환

📍 JVM의 구조

  • Method Area: 클래스 정보와 클래스 변수 등, 모든 쓰레드가 공유하는 메모리 영역
  • Stack : 메서드의 작업공간
  • Heap : 인스턴스가 생성되는 공간

📍 호출 스택

메소드의 작업에 필요한 메모리 공간 제공

  • 메소드가 작업을 수행하는 동안 지역변수들과 연산의 중간결과 등을 저장하는데 사용
  • 메소드가 작업을 마치면 할당되었던 메모리는 반환
  • 호출 스택 제일 상위에 위치하는 메소드가 현재 실행 중인 메소드, 나머지는 대기
  • 객체를 생성하지 않고 호출하기 위해서는 static keyword

📍 static/인스턴스 메서드

static 메서드

  • 객체 생성 없이 호출할 수 있는 메서드(Class이름.method이름())
  • 메서드 내 인스턴스 변수 사용 불가

인스턴스 메서드

  • 객체 생성 후, 호출할 수 있는 메서드(참조변수.method이름())
  • 메서드 내 인스턴스 변수 사용 가능
package chapter6;

import java.time.LocalDate;

class Example {
    static String today = LocalDate.now().toString();
    private long todayTimeMs;

    Example(){
        this.todayTimeMs = System.currentTimeMillis();
    }

    //static 메서드
    public static String getToday(){
        return today;
    }

    //instance 메서드
    public long getTodayTimeMs(){
        return todayTimeMs;
    }
}

public class StaticMethodAndInstanceMethodExample {
    public static void main(String[] args) {
        System.out.println(Example.getToday());

        Example example = new Example();
        System.out.println(example.getTodayTimeMs());
    }
}

📌 오버로딩(overloading)란?

한 클래스에 같은 메소드 이름으로 여러 메소드를 정의하는 것

  • 메소드의 매개변수의 수 혹은 타입은 달라야 함.
  • 변환 타입은 상관 없음.
package chapter6;

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

    }

    // 이름은 같지만 매개변수는 서로 다르다

    private  static int calculatorSum(int num1, int num2){
        return num1 + num2;
    }

    private static int calculatorSum(double num1, double num2){
        return (int)(num1+num2);
    }

    private static double calculatorSum(float num1, float num2){
        return num1 + num2;
    }
}

📍 오버로딩과 가변인자

메소드의 매개변수를 동적으로 지정할 수 있는 기능(>=JDK1.5)

  • 가변인자의 선언 : 데이터타입... 변수명
  • 가변인자는 메소드 매개변수의 마지막에 선언해야한다.
  • 가변인자를 선언한 메서드는 되도록 오버로딩 하지 않는 것이 좋다.
  • 함수에 들어가는 인수(argument)의 개수가 변하는 것
package chapter6;

public class VariableArgs {
    public static void main(String[] args) {
        String originStr = "abc";
        System.out.println(addString(originStr,new String[]{"d","e"}));
        System.out.println(addString(originStr,"f"));
        System.out.println(addString(originStr));

    }

    private static String addString(String origin,String... add){
        for(String element : add){
            origin += element;
        }

        return origin;
    }
}

출력결과

📍 Task

Human Class 직접 구현해보기

package chapter6;

class Human{
    private String sex;
    private int tall;
    private int weight;
    private int age;
    private String name;

    public Human(String sex, int tall, int weight, int age, String name){
        this.sex = sex;
        this.tall = tall;
        this.weight = weight;
        this.age = age;
        this.name = name;
    }

    public String getSex(){
        return sex;
    }

    public int getTall(){
        return tall;
    }

    public int getWeight(){
        return weight;
    }
    public int getAge(){
        return age;
    }
    public String getName(){
        return name;
    }

    public double getBMIScore(){
        return Math.round(weight/Math.pow(tall,2)*10000);
    }
}

public class task3 {
    public static void main(String[] args) {
        Human human1 = new Human("남",178,68,24,"Alex");
        System.out.println(human1.getSex());
        System.out.println(human1.getAge());
        System.out.println(human1.getName());
        System.out.println(human1.getAge());
        System.out.println(human1.getTall());
        System.out.println(human1.getBMIScore());
    }
}

출력결과

profile
BE 공부 블로그입니다

0개의 댓글