JAVA/이론

[Java] 8. 클래스와 객체 Part.2

katia 2023. 3. 15. 16:45

1. 제어자

(1) 접근 제어자

  • 클래스나 멤버의 사용을 제어하기 위해서 사용
  • 접근 제어자는 외부에서 접근할 수 있는 정도와 범위를 정해줌
  • 종류
    • public : 접근 제한이 없음
    • protected : 같은 패키지나 자식 클래스에서 접근 가능
    • default : 같은 패키지 내에서만 접근 가능
    • private : 같은 클래스 내에서만 접근 가능
구분 클래스 패키지 자식 클래스 전체 세계
public O O O O
protected O O O X
default O O X X
private O X X X

(2) 접근자와 설정자

  • 캡슐화(정보 은닉) : 구현의 세부 사항을 클래스 안에 감추는 것
  • 클래스 안의 데이터를 외부에서 마음대로 변경하지 못하게 하는 것
  • 외부에서 변수는 감추고, 메소드는 사용할 수 있도록 클래스를 생성
  • 종류
    • getter : 변수 값(필드 값)을 반환하는 접근자
    • swtter : 변수 값(필드 값)을 설정하는 접근자
  • 예시
class Account{
    private String name;
    public int balance;

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }

    public int getBalance(){
        return balance;
    }
       public void setBalance(int balance){
        this.balance = balance;
    }
}

public class Test2{
    public static void main(String[] args){
        Account obj = new Account();

        obj.setName("Tom");
        obj.setBalance(10000);
        System.out.println("이름은 " + obj.getName() + ", 통잔잔고는 " + obj.getBalance + " 입니다.");
    }
}

2. 생성자

(1) 생성자

  • 인스턴스를 생성할 때 자동으로 호출되는 메소드
  • 모든 클래스는 기본 생성자를 가지고 있음
  • 클래스에 생성자가 없을 경우 컴파일시 컴파일러가 자동으로 생성자를 추가함
// 기본 생성자
class Cellphon{
    String model;
    String color;
    int capacity;
    // 컴파일시 컴파일러가 자동으로 추가
    public Cellphon(){}
}
  • 예시
// 매개변수를 갖는 생성자
class Cellphon{
    String model;
    String color;
    int capacity;

    public Cellphon(String color, int capacity){
        this.capacity = capacity;
        this.color = color;
    }
}

public class Test{
    public static void main(String[] args){
        Cellphone myphone = new Cellphone("silver, 64");
        System.out.println(myphone.model);
        System.out.println(myphone.color);
        System.out.println(myphone.capacity);
    }
}

3. 오버로딩

(1) 오버로딩(Overloading)

  • 매개변수의 개수와 타입은 다르지만 이름이 같은 메소드를 여러개를 정의하는 것
  • 메소드의 기능은 같지만 매개변수의 개수와 타입이 다를 때 효율적으로 사용이 가능
  • 예시
public class Test{
    static int sum(int a, int b){
        return a+b;
    }

    static int sum(int a, int b, int c){
        return a+b+c;
    }

    static double sum(double a, double b, double c){
        return a+b+c;
    }

    public static void main(String[] args){
        System.out.println(sum(3, 2));
        System.out.println(sum(2, 3, 4));
        System.out.println(sum(2.5, 3.5, 4.5));
    }
}

(2) 생성자 오버로딩

  • 생성자 오버로딩을 통하여 다양한 방법으로 객체를 생성
  • this : 현재 객체를 나타냄
  • this() : 객체의 기본 생성자 호출
  • this()를 통한 다른 생성자 호출은 항상 첫번째 문장이여야 함
class Rectangle{
    private int x, y;
    private width, height;

    Rectangle(){
        this(0, 0, 1, 1)
    }
    Rectangle(int width, int height){
        this(0, 0, width, height);
    }
    Rectangle(int x, int y, int width, int height){
        this.x = x
        this.y = y
        this.width = width;
        thid.height = height;
    }
}

4. 내장 클래스

(1) 중첩 클래스 : 내장 클래스와 외부 클래스

  • 클래스 안에 클래스를 정의 가능
  • 외부 클래스(outer class) : 내부에 클래스를 가지고 있는 클래스
  • 내부 클래스(nested class) : 클래스 내부에 포함되는 클래스
    • 정적 내장 클래스 : static이 붙어서 내장되는 클래스(다른 클래스로 바로 접근 가능)
    • 비정적 내장 클래스 : static이 붙지 않는 내장 클래스 (객체 생성 후 접근 가능)
      • 내부 클래스(inner class) : 클래스의 멤버처럼 선언되는 내장 클래스
      • 지역 클래스(local class) : 메소드의 몸체 안에서 선언되는 내장 클래스
      • 무명 클래스(anonymous class) : 수식의 중간에서 선언되고 바로 객체화 되는 클래스

(2) 내장 클래스

  • 클래스 안에 선언된 클래스
  • 외부 클래스의 인스턴스 변수와 메소드 전부 사용가능
  • private로 선언되어 있어도 접근이 가능
  • 예시
class OuterClass{
    private int value = 10;
    class InnerClass{
        public void myMethod(){
            system.out.println("외부 클래스의 private 변수 값: " + value);
        }
    }

    OuterClass(){
        InnerClass obj = new InnerClass();
        obj.myMethod();
    }
}

public class Test{
    public static void main(String[] args){
        OuterClass outer = new OuterClass();
    }
}

(3) 지역 클래스

  • 메소드 안에 정의되는 클래스
  • 접근 제어 지정자를 가질수 없음
  • 지역클래스는 abstract 또는 final로만 지정가능
  • 예시
class localInner{
    private int data = 30;
    void display(){
        final String msg = "현재의 데이터 값은 ";
        class Local{
            void printMsg(){
                System.out.println(msg + data);
            }
        }
        Local obj = new Local();
        obj.printMsg();
    }
}

public class Test{
    public static void main(String[] args){
        localInner inner = new localInner();
        inner.display();
    }
}

(4) 익명 클래스

  • 이름이 없는 클래스
  • 인스턴스를 생성할 때 블록이 있음
  • 블록안에서 클래스 내용을 재정의
  • 예시
class Some{
    private int a = 3;
    int getter(){return this.a;}
    void setter(int a){this.a = a;}
}

public class Test{
    public static void main(String[] args){
        Some s = new Some() {
            private int a = 10;
            int getter(){return this.a;}
            void setter(int a){this.a = a;} 
        };
    }
}

5. 상속

(1) 상속(inheritance)

  • 다른 클래스가 가지고 있는 기능을 그대로 사용
  • 부모 클래스와 자식 클래스로 구성
  • IS-A 관계가 성립
구분 부모 클래스 자식클래스
의미 상속해 주는 클래스 상속받는 클래스
용어 슈퍼 클래스(super class)
기반 클래스(base class)
서브 클래스(sub class)
파생 클래스(derived class)

(2) 상속 관계 구현

  • 부모 객체는 자기가 가지고 있는 필드와 메소드를 자식 객체에게 물려주어 자식 객체가 사용할 수 있도록 함
  • 다중 상속은 지원 하지않음
  • final이 붙은 클래스는 상속불가
class 부모 클래스{
    본문
}

class 자식 클래스 extends 부모 클래스{
    // 부모 클래스의 멤버들을 상속 받음
    본문
}
  • 예시
// 부모 클래스 선언
class Person{
    void breath(){
        System.out,println("숨쉬기");
    }
    void eat(){
        System.out,println("먹기");
    }
}
// 부모 클래스 Person을 상속 받은 자식 클래스 Man 정의 
class Man extends Person {
    void run(){
        System.out,println("달리기");
    }
}

public class Test{
    public static void main(String[] args){
        Man man1 = new Man();
        // 부모 클래스의 메소드 breath()을 사용가능
        man1.breath();
        man1.run();
    }
}

(3) 상속과 생성자 - super()

  • 자식 클래스의 생성자 작업 시 부모 클래스의 생성자도 반드시 호출해야 함
  • 부모 클래스의 생성자 호출은 상위 클래스를 의마하는 super()를 통해 이루어짐
  • 자식 생성자 내부에 부모 클래스의 생성자를 따로 작성하지 않았다면 자동적으로 컴파일러가 자식 클래스 생성자에 super();을 추가하여 부모 클래스의 생성자를 호출함
  • 예시
class Car{
    String color;

    Car(String color){
        this color = color;
    }
}

class SportsCar extends Car{
    int supeedLimit;

    SportsCar(String color, int speedLimit){
        this.color = color;
        this.speedLimit = speedLimit;
    }
}

(4) Object 클래스

  • 모든 클래스의 조상격인 클래스로, 모든 클래스의 부모 클래스
  • 상속을 받지 않는 독자적인 클래스는 자동으로 Object클래스를 상속함(Ctrl + T로 상속관계 확인 가능)
class Tree extends Object{
    // 본문
}
메소드 리턴 타입 설명
java.lang.Object
clone() Object 객체 자신의 복사본을 생성하여 반환
equals(Object obj) boolean obj가 현재 객체와 같은지를 반환
finalize() void 사용되지 않는 객체가 제거되기 직전에 호출
getClass() Class 실행 시간에 객체의 클래스 정보를 반환
int hashCode() int 객체에 대한 해쉬
String toString() String 객체를 기술하는 문자열을 반환
java.util.Objects
compare(T a, T b, Comparator) int 두 객체 a와 b를 Comparator를 사용해서 비교
deepEquals(Object a, Object b) boolean 두 객체의 깊은 비교(배열 항목까지 비교)
isNull(Object obj) boolean 객체가 null인지 조사

6. 오버라이딩

(1) 오버라이딩(Overriding)

  • 자식 클래스에서 부모 클래스로 부터 물려받은 메소드를 다시 작성하는 것
  • 부모 클래스에서 물려받은 메소드의 기능을 변경할 때
  • 메소드 이름을 같게 하여 새로운 내용을 작성(재정의)
  • final이 붙은 메소드는 오버라이딩 불가능
class Animal{
    void jump(){
        System.out.println("Jump!");
    }
    void bark(){
        System.out.println("컹컹");
    }
}

class Dog extends Animal{
    @Override
    void bark(){
        System.out.println("왕왕");
    }
}

class Cat extends Animal{
    @Override
    void bark(){
        System.out.println("냐옹");
    }
}

public class Test{
    public static void main(String[] args){
        Dog dog1 = new Dog();
        Cat cat1 = new Cat();

        /* 
            부모 클래스 Animal을 상속받아 Animal 클래스의 bark()메소드를
            자식 클래스에서 재정의하여 사용.
        */
        dog1.bark();
        cat1.bark();
    }
}

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

[Java] 10. 예외 처리  (0) 2023.03.27
[Java] 9. 클래스와 객체 Part.3  (0) 2023.03.20
[Java] 7. 클래스와 객체 Part.1  (0) 2023.03.15
[Java] 6. 배열  (0) 2023.03.14
[Java] 5. 반복문  (0) 2023.03.14