배운것들을 정리합니다.
三昧境

Java/Java Language

[Java 기초] 클래스 class

ujo_orr 2024. 11. 28. 00:02

클래스(class)

데이터와 기능을 포함하는 코드 묶음

/*
class 클래스명 {}
클래스는 대문자로 시작
*/

class Person {
// 내용
}

public static void main(String[] args) {
  Person person = new Person(); // 객체 만들기
}

클래스 == 틀

객체 == 틀로인해서 나온 빵


인스턴스 변수(instance variable)

클래스 내에 선언된 변수

/*
class 클래스명 {
  인스턴스 변수1
  인스턴스 변수2
  ...
}
*/

class Person {
  String name;
  int age;
}

public static void main(String[] args) {
  Person person = new Person();
  person.name = "John";
  person.age = 20; // 점(.)으로 인스턴스 변수에 접근
}

클래스 변수(class variable)

클래스 내에 static으로 선언된 변수 == 모든 객체가 공유하는 변수

class Person {
  String name;
  int age;
  static int personCount = 0; // 클래스 변수
}

public static void main(String[] args) {
  Person.personCount = 10;
  System.out.println(Person.personCount); // 10 출력
}

객체를 만들 필요 없이 클래스 명으로 접근


인스턴스 메소드(instance method)

클래스 내에 정의된 메소드

class Person {
  String name;
  int age;
  static int personCount = 0;
  public void introduce() { // 인스턴스 메소드
    System.out.println("name =" + name);
    System.out.println("age =" + age);
  }
}

public static void main(String[] args) {
  Person person = new Person();
  person.name = "John"
  person.age = 20;
  person.introduce();
}

클래스 메소드(class method)

클래스 내에 static으로 선언된 메소드 == 모든 객체가 공유하는 메소드

class Person {
  String name;
  int age;
  static int personCount = 0;
  public static void printPersonCount() { // 클래스 메소드
    System.out.println(personCount);
  }
}

public static void main(String[] args) {
  Person.personCount = 10;
  Person.printPersonCount(); // 클래스 메소드
}

this

자기자신 (인스턴스 / 지역변수 구분)

/*
this.인스턴스변수;
*/

class Person {
  String name;
  public void setName(String name) {
    this.name = name; // this.name은 인스턴스 변수, name은 파라미터 변수
  }
}

public static void main(String[] args) {
  Person person = new Person();
  person.setName("John");
  System.out.println(person.name);
}

생성자(constructor)

객체가 생성될 때 호출되는 메소드

/*
클래스명(전달값) {
  초기화 명령문
}
*/

class Person {
  String name;
  int age;
  Person(String name, int age) {
    this.nname = name; // 초기화 작업
    this.age = age; //  초기화 작업
  }
}

public static void main(String[] args) {
  Person.person = new Person("John", 20); // 인수
}

getter&setter

getter

인스턴스 변수의 값 반환

/*
반환형 get이름() {
  return 반환값;
}
*/

class Person {
  String name;
  int age;
  
  public String getName() {
    return name;
  }
  public int getAge() {
    return age;
  }
}

setter

인스턴스 변수의 값 설정

/*
void set이름(전달값) {
  값을 설정하는 작업
}
*/

class Person {
  String name;
  int age;
  
  public void setName(String name) {
    this.name = name;
  }
  
  public void setAge(int age) {
    this.age = age;
  }
}

getter&setter

class Person {
  int age;
  
  public int getAge() {
    return age;
  }
  
  public void setAger() {
    this.age = age;
  }
}

public static void main(String[] args) {
  Pesron person = new Person(); // 객체(object)생성 및 생성자(constructor)호출
  person.setAge(20); // 값 설정(setter)
  System.out.println(person.getAge()); // 값 읽기(getter)
}

getter와 setter는 언뜻 보면 생성자와 비슷하게 인수를 받아 값을 설정하는것 같지만

특징 getter&setter 생성자
초기화 시점 객체 생성 후에도 값을 설정하거나 변경 가능 객체 생성 시점에서만 초기화 가능
캡슐화 멤버 변수 보호 및 데이터 무결성 보장 초기화만 수행함, 이후 보호 로직 구현 필요
유효성 검사 setter에서 값을 설정하기 전에 조건 검증 가능 생성자 내부에서만 초기 조건 검증 가능
유연성 값 읽기(getter) 쓰기(setter)를 분리 가능 초기화 이외의 추가 동작 구현 어려움
코드 가독성 멤버 변수와 동작을 명확히 구분 간결한 초기화 작업에 적합
예시 나이, 이름, 주소 등 변경 가능한 값 값이 불변하거나, 객체 생성 후 값의 변경이 필요 없는 경우

이러한 차이가 있다.


접근 제어자(access modifier)

접근 권한 지정

/*
접근제어자 class 클래스명 {
  접근제어자 인스턴스 변수
  접근제어자 인스턴스 메소드
}
*/

class Person {
  String name;
  private int age; // private == 접근제어자
  
  public void setAge(int age) { // public == 접근제어자
    this.age = age;
  }
}
접근 제어자 접근 가능 범위
private 해당 클래스 내에서만
public 모든 클래스에서
default 같은 패키지 내에서만(아무것도 안 적었을 때)
protected 같은 패키지 내에서
다른 패키지인 경우 자식 클래스에서

패키지(package)

관련 클래스들을 그룹화 (폴더)

/*
package 패키지명;
*/
  • JavaWorkspace
    • .idea
    • out
    • src
      • sample
        • MyClass.java

이러한식으로 디렉토리가 구성돼 있을 때

package sample; // 폴더 명

public class Myclass{} // java파일 명

이렇게 표기 된다

또는 다른곳에 있는 패키지를 사용할 때에는

/*
import 패키지명.클래스명;
*/

import java.util.Random; // java라는 패키지 내, util이라는 패키지 내, Random이라는 class를 쓰겠다
import java.util.*; // util 패키지 내 모든 class 사용

public class MyClass {
  public static viod main(Sring[] args) {
    Random random = new Random();
    int num = random.nextInt();
  }
}

상속(extends)

특정 클래스(부모 클래스)의 기능을 재사용(자식 클래스) 및 확장

부모 클래스 기능 1, 2  
부모 클래스의 기능1, 2를 재사용
자식 클래스 기능 1, 2, 3 새로운 기능3 구현
/*
class 자식클래스명 extends 부모클래스명 {}
*/

class Person {
  int age;
}

class Student extends Person { // Person이라는 부모클래스 상속
  String school; // int age; 를 구현할 필요 없음
}

public class Main {
  public static void main(String[] args) {
    Student student = new Student();
    student.age = 20; // 변수초기화를 하지 않아도 Person클래스의 필드를 사용, 메소드도 동일
  }
}

메소드 오버라이딩(method overriding)

부모 클래스의 메소드를 재정의(덮어쓰기)

class Person {
  public void introduce() {
  System.out.println("I'm Person");
  }
}

class Student extends Person {
  @Override
  public void introduce() {
    System.out.println("I'm Student");
  }
}

public class Main {
  public static void main(String[] args) {
    Person person = new Person();
    Student student = new Student();

    person.introduce(); // I'm Person
    student.introduce(); // I'm Student
  }
}

다형성(polymorphism)

여러 형태로 동작할 수 있는 성질

class Person {
    public void introduce() {
        System.out.println("I'm Person");
    }
}

class Student extends Person {
    @Override
    public void introduce() {
        System.out.println("I'm Student");
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        Person student = new Student(); // Student => Person (Upcasting)

        person.introduce(); // I'm Person
        student.introduce(); // I'm Student
    }
}

객체를 초기화할때 Student student 가 아닌 Person Student형식으로 정의 가능 이를 "업캐스팅"이라고 함


super

부모 클래스에 접근

/*
super.부모클래스 변수;
super.부모클래스 메소드();
super(부모클래스 변수);
*/

class Person {
  int age;
  
  Person(int age) {
    this.age = age;
  }
}

class Student extends Person {
  String school;
  
  Student(int age, String school) {
    super(age); // super
    this.school = school;
  }
}

참조(reference)

객체의 메모리 주소를 가리킴

자료형 비고 종류
기본 자료형 실제 값 저장 int, long, float, double, boolean,
참조 자료형 값이 저장된 메모리 주소를 저장 String, 클래스, ...
 

[Java] 기초 자료형, 문자열, 정수, 실수, 비교

자료형 (자료의 형태 Data Type) 문자열 (String)큰 따옴표 내에 들어오는 문자형 자료숫자 자료형 (int, long, double, float)실수 정수 등의 자료불리언 자료형 (boolean)true, false를 반환하는 자료 기본 자

ujo-orr.tistory.com

 

기초 자료형에서

int a = 10;
int b = 20;

이렇듯 변수가 선언됐다 가정 하였을 때

a b
10 20

이러한 형식으로 값이 들어가게 됨. 여기서

a = b;

이러한 식으로 b의 값을 a에 복사를 하게되면

a b
20 20

이러한 형식으로 값이 들어가게 됨

참조 자료형에서는

String a = "가";
String b = "나";
a b

가 라는 문자열이 있는 위치를 a 에서 참조하게 되고
나 라는 문자열이 있는 위치를 b 에서 참조하게 됨

위와 같이

a = b;

를 선언하게 되면 b의 값을 a에 복사하게 되는건데 값을 복사하는게 아닌
b에서 가리키고 있는 참조를 a에서 복사하게 된다.

고로 값을 복사하는게 아니게 됨으로

public class Main {
  public static void main(String[] args) {
  String a = "가";
  String b = "가";

    System.out.println(a == b);         // true (참조값 비교)
    System.out.println(a.equals(b));   // true (값 비교)
  }
}

public class Main {
  public static void main(String[] args) {
  String a = new String("가");
  String b = new String("가");

    System.out.println(a == b);         // false (참조값 비교)
    System.out.println(a.equals(b));   // true (값 비교)
  }
}

이러한 형식으로 비교할 수 있음

  • 문자열 리터럴 "가"는 String Pool에 저장됨
  • 동일한 문자열 리터럴이 있을 경우 같은 객체를 참조하게 됨.
  • new 키워드를 사용하면 항상 새로운 객체Heap Memory에 생성

final

변경할 수 없게

class Person {
  final String name = "John"; // final 키워드로 불변의 변수값으로 설정
  
  public final void introduce() { // final 키워드로 불변의 메소드로 설정
    System.out.println("I'm Person");
  }
}

class Student extends Person {
  @Override

  public void introduce() { // 부모클래스에 선언된 final 때문에 오버라이드 불가
    System.out.println("I'm Person");
  }
}

열거형(enum)

상수들의 묶음

/*
enum 열거형명 {상수명1, 상수명2, ...}
*/

enum Animal {DOG, CAT, BIRD, RABBIT} // 열거형 선언(열거형 상수는 대문자로 선언)

class Person {
  Animal animal; // 열거형 필드 선언
  
  public void setAnimal(Animal animal) { // setter 선언
    this.animal = animal;
  }
  
  public void introduce() { // 메소드 선언
    System.out.println("My animal is " + animal);
  }
}

public class Main{
  public static void main(String[] args) {
    Person person = new Person(); // Person 객체 초기화 
    
    person.setAnimal(Animal.CAT); // 열거형 상수 CAT 설정
    person.introduce(); // My animal is RABBIT 출력
    
    switch(person.animal) {
      case DOG : 
        System.out.println("강아지");
        break;
      
      case CAT : 
        System.out.println("고양이");
        break;
      
      case BIRD : 
        System.out.println("새");
        break;
      
      case RABBIT : 
        System.out.println("토끼");
        break;
      
      default : 
        System.out.println("unknown");
        break;
    }
  }
}

추상 클래스(abstract class)

아직 완성되지 않은(추상적인) 클래스

/*
abstract class 클래스명 {}
*/

abstract class Shape { // 추상클래스
  abstract double calculateArea(); // 추상메소드
}

class Square extends Shape {
  private double s;
  
  public Square(double s) { // 차후에 s 값을 파라미터로 받아 private double s; 로 전달
    this.s = s;
  }
  
  @Override
  double calculateArea() { // 추상클래스 오버라이드
    return s * s;
  }
}

class Circle extends Shape {
  private double r;
  
  public Circle(double r) {
    this.r = r;
  }
  
  @Override
  double calculateArea() {
    return Math.PI * r * r;
  }
}

인터페이스(interface)

클래스를 작성할 때 기본이되는 뼈대

/*
interface 인터페이스명 {}
*/

interface Shape {
  double calculateArea();
}

class Square implements Shape { // interface용 implements
  private double s;
  
  public Square(double s) { // 생성자
    this.s = s;
  }
  
  @Override
  public double calculateArea() { // interface에서는 @Override 메서드도 반드시 public
    return s * s;
  }
}

class Circle implements Shape {
  private double r;
  
  public Circle(double r) {
    this.r = r;
  }
  
  @Override
  public double calculateArea() { // interface에서는 @Override 메서드도 반드시 public
    return Math.PI * r * r;
  }
}

추상 클래스와 인터페이스의 차이

특징 추상 클래스 인터페이스
목적 "is-a" 관계
클래스의 확장(상속)을 위한 기반
"can-do" 관계
클래스의 행동(기능)계약 제공
다중 상속 단일 상속만 지원 다중 구현 가능
메소드 추상 메소드와 구현된 메소드 모두 포함 모든 베소드는 기본적으로 public abstract
변수 인스턴스 변수, 정적 변수, 상수를 가질 수 있음 public, static, final 상수만 가질 수 있음
생성자 생성자 정의 가능 생성자 정의 불가능
접근 제어자 public, protected, private 모두 사용 가능 모든 메소드는 public이어야 함
추상 메소드 구현 여부 구현하지 않아도 됨 모든 메소드는 구현해야 함

제네릭스(generics)

다양한 형태의 데이터를 일반화하여 다룰 수 있게

/*
T 변수명
*/

// 단순 메소드 오버로딩 방식
public class Main {
  public static void printValue(int value) { // 타입별 메소드 정의
    System.out.println(value);
  }
  
  public static void printValue(double value) { // 타입별 메소드 정의
    System.out.println(value);
  }
  
  public static void printValue(String value) { // 타입별 메소드 정의
    System.out.println(value);
  }
  
  public static void main(String[] args) {
  int intValue = 3;
  double doubleValue = 3.14;
  String stringValue = "Hi";
  
  printValue(intValue);
  printValue(doubleValue);
  printValue(stringValue);
  }
}

// 제너릭 방식 (컴파일러가 타입 매개변수 T를 추론함)
public class Main {
  public static <T> void printValue(T value) { // 제너릭을 통해서 타입을 일반화
    System.out.println(value);
  }
  
  public static void main(String[] args) {
  int intValue = 3;
  double doubleValue = 3.14;
  String stringValue = "Hi";
  
  printValue(intValue);
  printValue(doubleValue);
  printValue(stringValue);
  }
}

제네릭 클래스(generic class)

다양한 데이터 유형을 처리할 수 있도록 설계된 제네릭 기반 클래스

/*
class 클래스명 <T> {}
*/

// 일반적인 클래스
class BoxInteger {
  int data; // 인스턴스 변수
  
  public void setData(int data) { // 생성자
    this.data = data;
  }
}

class BoxString {
  String data;
  
  public void setData(String data) {
    this.data = data;
  }
}

public class Main {
  public static void main(String[] args) {
  BoxInteger iBox = new BoxInteger(); // 일반적인 객체 생성
  BoxString sBox = new BoxString(); // 일반적인 객체 생성
  
  iBox.setData(3); // 정수 담기
  sBox.setData("Hi"); // 문자열 담기  
  }
}

// 제너릭 클래스
class Box<T> { // 클래스 일반화
  T data; // 일반화 된 인스턴스 변수
  
  public void setData(T data) { // 생성자
    this.data = data;
  }
}

public class Main {
  public static void main(String[] args) {
  Box<Integer> iBox = new Box<>(); // 정수 제너릭 객체 생성
  Box<String> sBox = new Box<>(); // 문자열 제너릭 객체 생성
  
  iBox.setData(3); // 정수 담기
  sBox.setData("Hi"); // 문자열 담기
  }
}

제너릭 클래스를 만들때 타입지정은 불필요하지만

객체를 생성할 때에는 타입을 지정해주어야 함


래퍼 클래스(wrapper class)

기본 자료형을 객체로 감싸 추가 기능 제공하는 클래스

// 기본 변수 선언
public class Main {
  public static void main(String[] args) {
  int i =1;
  double d = 1.0;
  char c = 'a';
  }
}

// 래퍼 클래스 변수 선언
public class Main {
  public static void main(String[] args) {
  Integer i =1;
  Double d = 1.7;
  Character c = 'a';
  
  System.out.println(i.intValue());
  System.out.println(d.intValue()); // 1출력. 소숫점 이하는 버림
  System.out.println(c.cahrValue());
  }
}
기본 타입(primitive) 래퍼 클래스(wrapper class)
int Integer
double Double
char Character
boolean Boolean
long Logn
float Float
byte Byte
short Short