Java OOP(2)

ChoRong0824·2023년 4월 8일
2

Java

목록 보기
10/31
post-thumbnail

23.04.08

this

자신의 메모리를 가리킵니다.
this는 생성된 인스턴스 스스로를 가리키는 예약어입니다.

class Birthday{
	int day;
    int month;
    int year;
    
    // 태어난 연도를 지정하는 메서드
    pulbic void setYear(int year){
    	this.year = year; // bDay.year = year; 와 동일
    }
    
    // this 출력 메서드
    public void printThis(){
    	sout(this); // sout(bDay) 와 같음
	}
    
    psvm(){
    	BirthDay bDay = new birthDay();
        bDay.setYear(2000);
        sout(bDay);	// 참조 변수 출력
        bDay.printThis(); // this 출력 메서드 호출
        }
	}

생성자에서 다른 생성자를 호출하는 this

Person(){
	this("이름 없음",1); // this를 사용해 Person(String, int) 생성자 호출
}
Person (String name, int age){
	this.name =name;
    this.age = age;
}

this로 다른 생성자를 호출할 때 주의할점.
this를 사용하여 생성자를 호출하는 코드 이전에 다른 코드를 넣을 수 없습니다.
만약 다른 코드를 넣으면 오류발생.
생성자는 클래스가 생성될 때, 호출되므로 클래스 생성이 완료되지 않은 시점에 다른 코드가 있다면 오류가 발생할 수 있습니다.
즉, 디폴트 생성자에서 생성이 완료되는 것이 아니라 this를 사용해 다른 생성자를 호출하므로, 이때는 this를 활용한 문장이 가장 먼저 와야 합니다.

자신의 주소를 반환하는 this

클래스 자료형과 상관없이 클래스내에서 this를 사용하면, 자신의 주소 값을 반환할 수 있습니다.

객체 간 협력

// Bus
public class Bus {
    int busNumber; // 버스 번호
    int passengerCount; // 승객 수
    int money; // 버스 수입

    // 버스 번호를 매개변수로 받는 생성자
    public Bus(int busNumber) {
        this.busNumber = busNumber;
    }

    // 승객이 버스에 탄 경우를 구현한 메서드
    public void take(int money) {
        this.money += money; // 버스 수입 증가
        passengerCount++; // 승객 수 증가
    }

    // 버스 정보를 출력하는 메서드
    public void showInfo() {
        System.out.println("버스"+ busNumber+" 승객 수 "+passengerCount+" 버스 수입" +money+"원 수입이 생겼습니다.");
    }
}


// Student
public class Student {
    public String studentName; // 학생이름
    public int grade; // 학년
    public int money; // 학생이 가지고 있는 돈

    // 학생이름과 가진 돈을 매개변수로 받는 생성자
    public Student(String studentName, int money) {
        this.studentName = studentName;
        this.money = money;
    }
    // 학생이 버스를 타면, 1000원 지불하는 기능을 구현한 메서드
    public void takeBus(Bus bus) {
        bus.take(1000);
        this.money -= 1000;
    }

    // 학생이 지하철 타면 지불하는 기능을 구현한 메서드
    public void takeSubway(Subway subway) {
        subway.take(1500);
        this.money -= 1500;
    }

    //학생의 현재 정보
    public void showInfo(){
        System.out.println(studentName+ "의 남은돈"+money+"입니다.");
    }
}

// TakeTrans
public class TakeTrans {
    public static void main(String[] args) {
        Student studentJames = new Student("James", 5000);
        Student studentTomas = new Student("Tomas", 10000);

        Bus bus100 = new Bus(100); // 노선 번호가 100번
        studentJames.takeBus(bus100); // james가 100번 버스를 탐
        studentTomas.showInfo(); // james 정보 출력
        bus100.showInfo(); // 버스 정보 출력

        Subway subwayGreek = new Subway("2호선");// 노선번호가 2호선인 지하철 생성
        studentTomas.takeSubway(subwayGreek); // Tomas가 2호선을 탐
        studentTomas.showInfo(); // Tomas 정보 출력
        subwayGreek.showInfo(); // 지하철 정보 출력
    }
}

static 변수

변수를 여러 클래스에서 공통으로 사용하려면 ?

public class Student{
	public int studentID;
    public String studentName;
    public int grade;
    public String address;
}

staic 변수의 정의와 사용 방법

static 변수는 자바뿐만 아니라 다른 언어에서도 비슷한 개념으로 사용하고 있는 변수로서 자바에서는 다른 멤버 변수처럼 클래스 내부에 선언합니다.
변수를 선언할 때, 다음과 같이 사용.

// static예약어   자료형  변수이름
static int serialNum;

static 변수는 클래스 내부에 선언하지만, 다른 멤버 변수처럼 인스턴스가 생성될 때마다 새로 생성되는 변수가 아니며,
static 변수는 프로그램이 실행되어 메모리에 올라갔을 때, 딱 한 번 메모리 공간이 할당됩니다. 그리고 그 값은 모든 인스턴스가 공유하고,
static으로 선언한 변수는 인스턴스 생성과 상관없이 먼저 생성되고 그 값을 모든 인스턴스가 공유하게 되는 것입니다.

변수 유효 범위

  • 함수나 메서드 안에서만 사용할 수 있는 지역 변수, 클래스 안에서 사용하는 멤버변수, 여러 인스턴스에서 공통으로 사용할 수 있는 static 변수(클래스변수)이며,
    변수는 어디에 어떻게 선언되느냐에 따라 유효범위가 달라집니다.

지역 변수의 유효 범위

지역 변수는 함수나 메서드 내부에 선언하기 때문에 함수 밖에서는 사용할 수 없습니다.
즉, 하나의 함수에 선언한 지역 변수는 다른 함수에서 사용할 수 없습니다. 지역 변수가 생성되는 메모리를 stack이라고 합니다. 스택에 생성되는 지역 변수는 함수가 호출될 때 생성되었다가 함수가 반환되면 할당되었던 메모리 공간이 해제되면서 함께 없어집니다.

멤버 변수의 유효 범위

멤버 변수는 인스턴스 변수라고도 합니다.
클래스가 생성될 때 heap(힙) 메모리에 생성되는 변수입니다.
멤버 변수는 클래스의 어느 메서드에서나 사용할 수 있습니다.
힙에 생성된 인스턴스가 가비지 컬렉터에 의해 수거되면 메모리에서 사라집니다.
따라서, 클래스 내부의 여러 메서드에서 사용할 변수는 멤버 변수로 선언하는 것이 좋습니다.

static 변수의 유효 범위

사용자가 프로그램을 실행하면 메모리에 프로그램이 상주하게 됩니다.
이때, 프로그램 영역중에 데이터 영역이 있습니다. 이 영역에는 상수나 문자열, static 변수가 생성됩니다. 인스턴스 변수는 객체가 생성되는 문장.
즉, new가 되어야 생성되지만, static 변수는 클래스 생성과 상관없이 처음부터 데이터 영역 메모리에 생성됩니다. 따라서 인스턴스 변수와 static 변수는 사용하는 메모리가 다릅니다.

정리

변수 유형 선언 위치 사용 범위 메모리 생성과 소멸
지역 변수 함수 내부에 선언 함수 내부에서만 사용 스택 함수가 호출될 때 생성, 함수 끝나면 소멸
멤버 변수 (인스턴스 변수) 클래스 멤버 변수로 선언 클래스 내부에서 사용하고 private이 아니면 참조 변수로 다른 클래스에서 사용 인스턴스가 생성될 때 힙에 생성되고, 가비지 컬렉터가 메모리를 수거할 때 소멸됨
static 변수 (클래스 변수) static 예약어를 사용하여 클래스 내부에 선언 클래스 내부에서 사용하고 private이 아니면 클래스 이름으로 다른 클래스에서 사용 가능 데이터영역 프로그램이 처음 식자할 때 상수와 함께 데이터 영역에 생성, 프로그램이 끝나고 메모리 해제할 때 소멸됨.

문제

  1. 자바에서 객체지향 프로그래밍을 하는 이유는 무엇인가요?
  2. 상속을 이용하여 아래 코드에서 Car 클래스를 확장한 SportsCar 클래스를 만들기
public class Car {
  protected String brand;

  public void honk() {
    System.out.println("Tuut, tuut!");
  }
}
  1. 다형성(Polymorphism)을 이용하여 아래 코드에서 Animal 클래스를 확장한 Dog 클래스와 Cat 클래스를 구현한다면 ?
public class Animal {
  public void animalSound() {
    System.out.println("The animal makes a sound");
  }
}
  • 번외, 추상 클래스(Abstract class)를 이용하여 아래 코드에서 Vehicle 클래스를 추상화 하는 코드를 구혆
public class Vehicle {
  private String color;
  private int speed;

  public void setColor(String color) {
    this.color = color;
  }

  public void setSpeed(int speed) {
    this.speed = speed;
  }

  public String getColor() {
    return this.color;
  }

  public int getSpeed() {
    return this.speed;
  }
  1. 캡슐화를 이용하여 아래 코드에서 Person 클래스의 name 필드를 보호하는 방법은 ?
public class Person {
  public String name;
  public int age;
}
  1. 다음 코드에서 Animal 클래스를 상속받은 Dog 클래스를 만들고, Dog 클래스의 bark() 메서드를 오버라이딩하여 "멍멍"이 출력되도록 구현하는 방법은?
public class Animal {
  public void makeSound() {
    System.out.println("동물이 소리를 냅니다.");
  }
}

// 여기에 코드를 작성해주세요.

public class Main {
  public static void main(String[] args) {
    Animal animal = new Animal();
    animal.makeSound();
    
    Dog dog = new Dog();
    dog.makeSound();
  }
}
  1. 올바른 함수 사용인가 ? 맞다면 O를, 만약 틀리다면 이유를 말해주세요.
public class Example {
    public static void sum(int a, int b) {
         int result = a + b;
        return result;
    }
}
profile
컴퓨터공학과에 재학중이며, 백엔드를 지향하고 있습니다. 많이 부족하지만 열심히 노력해서 실력을 갈고 닦겠습니다. 부족하고 틀린 부분이 있을 수도 있지만 이쁘게 봐주시면 감사하겠습니다. 틀린 부분은 댓글 남겨주시면 제가 따로 학습 및 자료를 찾아봐서 제 것으로 만들도록 하겠습니다. 귀중한 시간 방문해주셔서 감사합니다.

1개의 댓글

comment-user-thumbnail
2023년 4월 10일

자바 문제의 정답
1번
// 예시 답안
// 자바에서 객체지향 프로그래밍을 하는 이유는 코드의 재사용성을 높이고 유지보수를 용이하게 하기 위함입니다.
// 또한, 객체지향 프로그래밍을 통해 모듈화가 가능해져서 여러 사람이 협업을 할 때 효율성이 높아집니다.

2번
// 예시 답안
public class SportsCar extends Car {
private boolean hasSpoiler;

public SportsCar(String brand, boolean hasSpoiler) {
this.brand = brand;
this.hasSpoiler = hasSpoiler;
}

public boolean hasSpoiler() {
return this.hasSpoiler;
}
}

3번
// 예시 답안
public class Dog extends Animal {
public void animalSound() {
System.out.println("The dog says: bow wow");
}
}

public class Cat extends Animal {
public void animalSound() {
System.out.println("The cat says: meow");
}
}

번외,
// 예시 답안
public abstract class Vehicle {
private String color;
private int speed;

public void setColor(String color) {
this.color = color;
}

public void setSpeed(int speed) {
this.speed = speed;
}

public String getColor() {
return this.color;
}

public int getSpeed() {
return this.speed;
}

public abstract void start();
}

4번
// 예시 답안
public class Person {
private String name;
public int age;

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

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

5번
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("멍멍");
}
}

6번

void 는 return이 올 수 없습니다.
따라서 해당 코드는 올바른 코드가 아닙니다.
코드를 수정하려면 void 말고 int 로 하거나 return 을 빼야 됩니다.

답글 달기