It's going to be one day 🍀

안녕하세요! 매일 매일 공부하려고 노력하는 백엔드 개발자 지망생의 공부 흔적입니다.

Back-End/Java # 교육

[Java 교육] final/상수/Getter,Setter/상속

2jin2 2024. 2. 1. 17:33

[공부 내용 정리]

final 필드

final 필드가 초기값 지정이 되면 이것이 최종적인 값이 되며, 프로그램 실행 도중에 수정할 수 없음.

final은 프로그램을 수행하면서 그 값이 바뀌면 안 될 때 사용함.

final int time = 3;
  • 필드의 초기값을 줄 수 있는 방법은 필드 선언시 사용!

상수 (static final)

불변의 값을 저장하는 필드. 상수 이름은 모두 대문자로 작성해야함. 언더바(_)로 연결.

static final double PI = 3.141592;
public class Earth {
	static final double EARTH_RADIUS = 6400;
	static final double EARTH_SURFACE_AREA;

	static {
		EARTH_SURFACE_AREA = 4 * Math.PI * EARTH_RADIUS * EARTH_RADIUS;
	}
}

캡슐화를 사용하기 위한 방법으로는 접근 제어자가 있음

접근 제어자

접근 제어자 (access modifier)를 사용하여 변수나 메소드의 사용 권한을 설정할 수 있음.

private

접근 제어자가 private으로 설정되었다면 해당 클래스 안에서만 접근이 가능함.

public class Secret {
	private String name;

	private String getName() {
		return this.name;
	}
}

 

defalut

접근 제어자를 별도로 설정하지 않는다면 변수나 메소드는 defalut 접근 제어자로 자동 설정. 동일한 패키지 안에서만 접근 가능.

package house;  // 패키지가 동일하다.

public class HouseKim {
    String lastname = "kim";  // lastname은 default 접근제어자로 설정된다.
}
package house;  // 패키지가 동일하다.

public class HousePark {
    String lastname = "park";

    public static void main(String[] args) {
        HouseKim kim = new HouseKim();
        System.out.println(kim.lastname);  // HouseKim 클래스의 lastname 변수를 사용할 수 있다.
    }
}

 

protected

protected가 붙은 변수나 메소드는 동일한 패키지의 클래스 or 해당 클래스를 상속받은 클래스에서만 접근이 가능.

package car;

public class Car {
	protected String company = "kia";
}
package car.example;   // Car.java와 패키지가 서로 다름

import car.Car;

public class Sonata extends Car {    // Car를 상속
	public static void main(String[] args) {
		Sonata sonata = new Sonata();
		System.out.println(sonata.company);   // 상속한 클래스의 protected변수는 접근 가능
	}
}

 

public

public 접근 제어자가 붙은 변수나 메소드는 어떤 클래스에서도 접근이 가능.

package car;

public class Car {
	protected String company = "kia";
	public String info = "this is public message.";
}

 

public 접근 제어자가 붙었기 때문에 패키지가 다른 Sonata클래스에서도 sonata.info 접근이 가능합니다.

package car.example;

import car.Car;

public class Sonata extends Car {
	public static void main(String[] args) {
		Sonata sonata = new Sonata();
		System.out.println(sonata.company);
		System.out.println(sonata.info);
	}
}

 

 

 

접근제어자 사용 이유 : 객체의 로직을 보호하기 위해 멤버에 따라서 외부의 접근을 허용하거나 차단해야 할 때 사용함. 의도치 않은 실수를 줄이기 위함.


Getter, Setter 메소드

객체의 무결성이 깨지는 것을 방지하기 위해 객체 지향 프로그래밍에서는 메소드를 통해 데이터를 변경하는 방법을 선호함.

Setter 메소드 : 데이터는 외부에서 접근할 수 없도록 막고, 메소드는 공개해서 외부에서 메소드를 통해 데이터에 접근하도록 유도하는 역할을 함.

public class Car {
		private int speed;
		
		public void setSpeed(int speed) {
				if (speed < 0) {
						this.speed = 0;
						return;
				} else {
						this.speed = speed;
				}
		}
}

 

Getter 메소드 : 메소드로 객체의 필드값을 가공한 후 외부로 전달함.

public class Car {
		private int speed;
		
		public double getSpeed() {
				double km = speed * 1.6;
				return km;
		}
}

만약 필드 타입이 boolean일 경우엔 관례상 get대신 is로 시작함

private boolean stop;

// Getter
public boolean **is**Stop() {
	return stop;
}

// Setter
public void setStop(boolean stop) {
	this.stop = stop;
}

 

-> 최종 Sonata 클래스의 Geter, Setter 메소드

public class Sonata {
	private int speed;
	private boolean stop;

	void setSpeed(int speed) {
		if (speed < 0) {
			this.speed = 0;
			return;
		} else {
			this.speed = speed;
		}
	}

	public int getSpeed() {
		return speed;
	}

	public boolean isStop() {
		return stop;
	}

	public void setStop(boolean stop) {
		this.stop = stop;
	}

	public static void main(String[] args) {
		Sonata sonata = new Sonata();

		// 잘못된 속도 변경
		sonata.setSpeed(-50);
		System.out.println("현재 속도: " + sonata.getSpeed());

		// 올바른 속도 변경
		sonata.setSpeed(60);
		System.out.println("변경 후 속도: " + sonata.getSpeed());

		// 멈춤
		if (!sonata.isStop()) { // isStop()이 false인 경우에 실행
			sonata.setStop(true); // setStop을 사용하여 상태를 멈춤(stop)을 변경
		}
// 따라서 위 코드는 sonata 객체의 상태가 아직 멈춰있지 않을때만 실행됨.

		System.out.println("멈춤 후 속도: " + sonata.getSpeed());
	}
}

상속

7.1 상속 : 상속이란 부모 클래스의 멤버를 자식 클래스에게 물려주는 것임

→ 상속은 이미 잘 개발된 클래스를 재사용해서 새로운 클래스를 만들기 때문에 코드의 중복을 줄여줌.

package chapter07;

public class Vehicle {
    String model;
    int speed;
    boolean stop;
    String color;
    int wheels;
    boolean onOff;

    public Vehicle() {
        model = "Tesla modelX";
        speed = 300;
        stop = true;
    }

    public void print() {
        System.out.println("Parent: "+model+", "+speed+", "+stop);
    }
}

-> Vehicle.java (부모 클래스)

package chapter07;

public class Car extends Vehicle {
    public void print() {
        System.out.println("Child(Car): "+model+", "+speed+", "+stop);
    }
}

-> Car.java

package chapter07;

public class Motorcycle extends Vehicle{ // 자식 클래스에서 부모 클래스를 선언(상속 받기로 직접 선택함)

    void setSpeed(int speed) {
        this.speed = speed;
    }
    public void print() {
        System.out.println("Child(Motorcycle): "+model+", "+speed+", "+stop);
    }
}

-> Motorcycle.java

package chapter07;

public class InheritPrinter {
    public static void main(String[] args) {
        Motorcycle motorcycle = new Motorcycle();
        motorcycle.speed = 0; // 자식 클래스는 부모의 값을 물려받긴 했지만 또 변경가능함!
        motorcycle.print();
    }
}

-> InheritPrinter.java (실행)

  • 상속을 해도 부모 클래스의 모든 필드와 메소드들을 물려받는 것은 아님. 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외.

→ 이렇게 상속을 이용하면 클래스의 수정과 중복을 최소화시킬 수 있음!


7.2 클래스 상속

class 자식클래스 extends 부모클래스 {
	// 필드
	// 생성자
	// 메소드
}

→ 다중 상속은 지원하지 않음. 부모클래스 하나만 상속 가능.

 

7.3 부모 생성자 호출

자바에서 자식 객체를 생성하면 부모 객체가 먼저 생성되고 자식 객체가 생성됨.

Car(String model, int speed, boolean stop) {
        super(model, speed); // 부모 생성자 호출
    }

-> Car.java (자식 클래스)

public Vehicle(String model, int speed) {
        this.model = model;
        this.speed = speed;
    }

Vehicle.java (부모 클래스)

→ super()을 사용해 부모의 기본 생성자를 호출함.

만약 부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자만 있다면 자식 생성자에서 반드시 부모 생성자 호출을 위해 super을 명시적으로 호출해야함.


Daily Quiz

Item 이라는 부모 클래스를 상속 받아서 Album, Movie, Book클래스를 생성해보세요. 추가로 ItemManager 라는 클래스를 생성하여 album, movie, book 각 객체의 필드를 출력해봅시다.

package chapter07;

public class Item {
    String id;
    String name;
    int price;
}

-> Item.java

package chapter07;

public class Album extends Item {
    String artist;
    public Album() {
        artist = "작곡가";
        id = "Album";
        name = "앨범";
        price = 10000;
    }

}

-> Album.java

package chapter07;

public class Movie extends Item {
    String director;
    String actor;

    public Movie() {
        director = "감독";
        actor = "배우";
        id = "Movie";
        name = "영화";
        price = 20000;

    }
}

-> Movie.java

package chapter07;

public class Book extends Item{
    String author;
    int isbn;

    Book() {
        author = "작가";
        isbn = 123456;
        id = "book";
        name = "책";
        price = 5000;
    }
}

-> Book.java

package chapter07;

public class ItemManager extends Item{
    public static void main(String[] args) {
        Album album = new Album();
        String [] arr = {};
        System.out.println("상품 아이디: "+album.id+", 상품 이름: "+album.name+", 상품 가격: "+ album.price
                +", 작곡가: "+album.artist);

        Movie movie = new Movie();
        System.out.println("상품 아이디: "+movie.id+", 상품 이름: "+movie.name+", 상품 가격: "+ movie.price
                +", 감독: "+movie.director+", 배우: "+movie.actor);

        Book book = new Book();
        System.out.println("상품 아이디: "+book.id+", 상품 이름: "+book.name+", 상품 가격: "+ book.price
                +", 작가: "+book.author+", ISBN: "+book.isbn);

    }
}

-> ItemManager.java