ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [패스트캠퍼스] Java & Spring 웹 개발 종합반 2주차 학습일지
    패스트캠퍼스/Java & Spring 웹 개발 종합반 2023. 2. 19. 14:04

     

    내일배움카드, 국비지원교육


    Chapter 2. 객체 지향 입문

    01. 객체와 객체지향 프로그래밍

    - 객체 (object) : 구체적, 추상적 데이터의 단위

    - 절차지향 프로그래밍 : 시간이나 사건의 흐름에 따른 프로그래밍

    - 객체지향 프로그래밍

    객체를 정의하고, 각 객체가 제공하는 기능들을 구현하고,

    각 객체가 제공하는 기능들간의 소통을 통해 객체간의 협력을 구현

     

     

     

     

     

    03. 함수와 메서드

    - 함수 (function) : 하나의 기능을 수행하는 일련의 코드

     

    - 함수 호출과 스택 메모리

    스택 : 함수가 호출될 때 지역 변수들이 사용하는 메모리

    함수의 수행이 끝나면 자동으로 반환되는 메모리

     

    - 메서드 (method)

    객체의 기능을 구현하기 위해 클래스 내부에 구현되는 함수

    멤버 함수라고도 함

    메서드를 구현함으로써 객체의 기능이 구현됨

     

     

     

     

     

     

     

     

     

    05. 인스턴스 생성과 힙 메모리

    - 인스턴스 (instance)

    클래스는 객체의 속성을 정의하고, 기능을 구현하여 만들어 놓은 코드 상태

    실제 클래스 기반으로 생성된 객체(인스턴스)는 각각 다른 멤버 변수 값을 가지게 됨

     

    - 힙 메모리

    생성된 인스턴스는 동적 메모리에 할당됨

    자바에서 Garbage collector가 주기적으로 사용하지 않는 메모리를 수거

    하나의 클래스로부터 여러 개의 인스턴스가 생성되고 각각 다른 메모리 주소를 가지게 됨

     

    참조 변수 : 메모리에 생성된 인스턴스를 가리키는 변수

    참조 값 : 생성된 인스턴스의 메모리 주소 값

     

     

     

     

     

    06. 생성자에 대해 알아봅시다

    - 생성자

    객체를 생성할 때 new 키워드와 함께 사용

    객체가 생성될 때 변수나 상수를 초기화하거나 다른 초기화 기능을 수행하는 메서드를 호출함

    생성자는 반환 값이 없고, 클래스의 이름과 동일

     

    - 기본 생성자

    클래스에는 반드시 하나 이상의 생성자가 존재

    생성자를 구현하지 않아도 new 키워드와 함께 생성자를 호출할 수 있음

    매개변수와 구현부가 없음

     

     

     

     

     

    07. 여러가지 생성자를 정의하는 생성자 오버로딩

    클래스에 생성자를 따로 구현하면 기본 생성자는 제공되지 않음

    생성자를 호출하는 코드에서 여러 생성자 중 필요에 따라 호출해서 사용할 수 있음

     

     

     

     

     

     

    09. 참조 자료형 변수

    클래스형으로 변수를 선언

    기본 자료형은 사용하는 메모리의 크기가 정해져있지만, 참조 자료형은 클래스에 따라 다름

    참조 자료형을 사용할 때는 해당 변수에 대해 생성하여야 함 (String 예외)

    public class Subject {
    	String subjectName;
    	int score;
    	int subjectId;
    }
    public class Student {
    	int studentId;
    	String studentName;
    	
    	Subject korea;
    	Subject math;
    	
    	public Student(int studentId, String studentName) {
    		this.studentId = studentId;
    		this.studentName = studentName;
    		
    		korea = new Subject();
    		math = new Subject();
    	}
    	
    	public void setKoreaSubject(String name, int score) {
    		korea.subjectName = name;
    		korea.score = score;
    	}
    	
    	public void setMathSubject(String name, int score) {
    		math.subjectName = name;
    		math.score = score;
    	}
    	
    	public void showScoreInfo() {
    		int total = korea.score + math.score;
    		System.out.println(studentName + "학생의 총점은 " + total + "점 입니다.");
    	}
    }
    public class SubjectTest {
    	public static void main(String[] args) {
    		Student studentLee = new Student(100, "Lee");
    		studentLee.setKoreaSubject("국어", 100);
    		studentLee.setMathSubject("수학", 99);
    		
    		Student studentKim = new Student(100, "Kim");
    		studentKim.setKoreaSubject("국어", 50);
    		studentKim.setMathSubject("수학", 65);
    		
    		studentLee.showScoreInfo();
    		studentKim.showScoreInfo();
    	}
    }

     

     

     

     

    10. 접근 제어 지시자와 정보은닉

    - 접근 제어 지시자 (access modifier)

    클래스 외부에서 클래스의 멤버 변수, 메서드, 생성자를 사용할 수 있는지 여부를 지정하는 키워드

    private : 같은 클래스 내부에서만 접근 가능

    default : 같은 패키지 내부에서만 접근 가능

    protected : 같은 패키지나 상속관계의 클래스에서 접근 가능

    public : 클래스의 외부 어디서나 접근 가능

     

    - 정보은닉

    외부에서 접근 가능한 최소한의 정보를 오픈함으로써 객체의 오류를 방지하여 클라이언트 객체가 더 효율적으로 객체를 활용할 수 있도록 해준다

     

     

     

     

     

    11. 캡슐화

    - 정보 은닉을 활용한 캡슐화

    꼭 필요한 정보와 기능만 외부에 오픈함

    대부분의 멤버 변수와 메서드를 감추고 외부에 통합된 인터페이스만 제공하여 일관된 기능을 구현하게 함

     

     

     

     

     

     

    12. 객체 자신을 가리키는 this

    - this가 하는 일

    인스턴스 자신의 메모리를 가리킴

    생성자에서 또 다른 생성자를 호출할 때 사용 (클래스에 생성자가 여러 개인 경우 this를 이용하여 생성자에서 다른 생성자를 호출할 수 있음)

    자신의 주소를 반환함

     

     

     

     

     

     

     

    15. 복습해봅시다

     

     

     

     

     

    16. 여러 인스턴스에서 공통으로 사용하는 변수를 선언하자

    공통으로 사용하는 변수가 필요한 경우 : 여러 인스턴스가 공유하는 기준 값이 필요한 경우

     

    - static

    처음 프로그램이 메모리에 로딩될 때 메모리를 할당

    클래스 변수, 정적변수라고도 함

    인스턴스 생성과 상관없이 사용가능하므로 클래스 이름으로 직접 참조

     

     

     

     

     

    17. static 메서드의 구현과 활용, 변수의 유효 범위

    static 메서드에서는 인스턴스 변수를 사용할 수 없음

    static 메서드는 클래스 이름으로 호출할 수 있음

    인스턴스 생성 전에 호출할 수 있으므로 static 메서드 내부에서는 인스턴스 변수를 사용할 수 없음

     

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

    static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지하므로 너무 큰 메모리를 할당하는 것은 좋지 않음

    멤버 변수가 너무 많으면 인스턴스 생성 시 쓸데없는 메모리가 할당됨

     

     

     

     

     

     

     

    18. 싱글톤 패턴

    싱글톤 패턴 : 프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴

    static 변수, 메서드를 활용하여 구현할 수 있음

     

    public class Company {
    	private static Company instance = new Company();
    	private Company() {}
    
    	public static Company getInstance() {
    		if(instance == null) {
    			instance = new Company();
    		}
    		return instance;
    	}
    }
    import java.util.Calendar;
    
    public class CompanyTest {
    	public static void main(String[] args) {
    		Company company1 = Company.getInstance();
    		Company company2 = Company.getInstance();
    		
    		System.out.println(company1);
    		System.out.println(company2);
    		
    		Calendar calendar = Calendar.getInstance();
    	}
    }

     

     

     

     

     

    19. 복습해봅시다

    자동차 공장이 있습니다. 자동차 공장은 유일한 객체이고, 이 공장에서 생산되는 자동차는 제작될 때마다 고유의 번호가 부여됩니다. 자동차 번호가 1001부터 시작되어 자동차가 생산될 때마다 1002, 1003 이렇게 번호가 붙도록 자동차 공장 클래스, 자동차 클래스를 구현하세요. 다음 CarFactoryTest.java 테스트 코드가 수행되도록 합니다.
    public class CarFactoryTest {
    	public static void main(String[] args) {
    		CarFactory factory = CarFactory.getInstance();
    		Car mySonata = factory.createCar();
    		Car yourSonata = factory.createCar();
    		
    		System.out.println(mySonata.getCarNum());	//1001 출력
    		System.out.println(yourSonata.getCarNum());	//1002 출력
    	}
    }
    public class CarFactory {
    	private static CarFactory instance = new CarFactory();
    	private CarFactory() {}
    	
    	public static CarFactory getInstance() {
    		if(instance == null) {
    			instance = new CarFactory();
    		}
    		return instance;
    	}
    	
    	public Car createCar() {
    		Car car = new Car();
    		return car;
    	}
    }
    public class Car {
    	private static int carNumber = 1000;
    	
    	private int carNum;
    	
    	public Car() {
    		carNumber++;
    		carNum = carNumber;
    		
    	}
    
    	public int getCarNum() {
    		return carNum;
    	}
    
    	public void setCarNum(int carNum) {
    		this.carNum = carNum;
    	}
    	
    }

     

     

     

     

     

     

     

    21. 객체 배열 사용하기

    객체 배열의 경우, 요소가 되는 객체의 주소가 들어갈 메모리만 할당되고 각 요소 객체는 생성하여 저장해야 함

    System.arraycopy 얕은 복사 : 주소값이 복사됨 (같은 객체)

    깊은 복사 : 값이 복사됨 (다른 객체)

    public class Book {
    	private String title;
    	private String author;
    	
    	public Book() {}
    	
    	public Book(String title, String author) {
    		this.title = title;
    		this.author = author;
    	}
    
    	public String getTitle() {
    		return title;
    	}
    	public void setTitle(String title) {
    		this.title = title;
    	}
    	public String getAuthor() {
    		return author;
    	}
    	public void setAuthor(String author) {
    		this.author = author;
    	}
    	
    	public void showInfo() {
    		System.out.println(title + ", " + author);
    	}
    }
    public class BookTest {
    	public static void main(String[] args) {
    		Book[] library = new Book[5];
    		
    		library[0] = new Book("태백산맥1", "조정래");
    		library[1] = new Book("태백산맥2", "조정래");
    		library[2] = new Book("태백산맥3", "조정래");
    		library[3] = new Book("태백산맥4", "조정래");
    		library[4] = new Book("태백산맥5", "조정래");
    		
    		for(Book book : library) {
    			System.out.println(book);
    			book.showInfo();
    		}
    	}
    }
    public class ObjectCopyTest {
    	public static void main(String[] args) {
    		Book[] library = new Book[5];
    		Book[] copyLibrary = new Book[5];
    		
    		library[0] = new Book("태백산맥1", "조정래");
    		library[1] = new Book("태백산맥2", "조정래");
    		library[2] = new Book("태백산맥3", "조정래");
    		library[3] = new Book("태백산맥4", "조정래");
    		library[4] = new Book("태백산맥5", "조정래");
    		
    		copyLibrary[0] = new Book();
    		copyLibrary[1] = new Book();
    		copyLibrary[2] = new Book();
    		copyLibrary[3] = new Book();
    		copyLibrary[4] = new Book();
    		
    		for(int i=0; i<library.length; i++) {
    			copyLibrary[i].setAuthor(library[i].getAuthor());
    			copyLibrary[i].setTitle(library[i].getTitle());
    		}
    		
    		// System.arraycopy(library, 0, copyLibrary, 0, 5);
    		
    		System.out.println("== library ==");
    		for(Book book : library) {
    			System.out.println(book);
    			book.showInfo();
    		}
    		
    		System.out.println("== copyLibrary ==");
    		for(Book book : copyLibrary) {
    			System.out.println(book);
    			book.showInfo();
    		}
    		
    		library[0].setAuthor("박완서");
    		library[0].setTitle("나목");
    		
    		System.out.println("== library ==");
    		
    		for(Book book : library) {
    			System.out.println(book);
    			book.showInfo();
    		}
    		
    		System.out.println("== copyLibrary ==");
    		for(Book book : copyLibrary) {
    			System.out.println(book);
    			book.showInfo();
    		}
    	}
    }

     

     

     

     

     

    24. ArrayList를 활용한 간단한 성적 산출 프로그램

    1001학번 Lee와 1002학번 Kim, 두 학생이 있습니다.
    Lee 학생은 국어와 수학 2과목을 수강했고, Kim 학생은 국어, 수학, 영어 3과목을 수강했습니다.
    Lee 학생은 국어 100점, 수학 50점입니다.
    Kim 학생은 국어 70점, 수학 85점, 영어 100점입니다.
    Student 클래스와 Subject 클래스를 만들고 ArrayList를 활용하여 두 학생의 과목 성적과 총점을 출력하세요
    public class StudentTest {
    	public static void main(String[] args) {
    		Student studentLee = new Student(1001, "Lee");
    		
    		studentLee.addSubject("국어", 100);
    		studentLee.addSubject("수학", 50);
    		
    		Student studentKim = new Student(1002, "Kim");
    		
    		studentKim.addSubject("국어", 70);
    		studentKim.addSubject("수학", 85);
    		studentKim.addSubject("영어", 100);
    		
    		studentLee.showScoreInfo();
    		System.out.println("=================================");
    		studentKim.showScoreInfo();
    	}
    }
    import java.util.ArrayList;
    
    public class Student {
    	int studentNum;
    	String studentName;
    	ArrayList<Subject> subjectList;
    	
    	public Student() {}
    
    	public Student(int studentNum, String studentName) {
    		this.studentNum = studentNum;
    		this.studentName = studentName;
    		subjectList = new ArrayList<>();
    	}
    	
    	public void addSubject(String name, int score) {
    		Subject subject = new Subject();
    		subject.setName(name);
    		subject.setScore(score);
    		subjectList.add(subject);
    	}
    	
    	public void showScoreInfo() {
    		int total = 0;
    		for(Subject subject : subjectList) {
    			total += subject.getScore();
    			System.out.println(studentName + "학생의 " + subject.getName() + " 과목의 성적은 " + subject.getScore() + "점입니다.");
    		}
    		System.out.println(studentName + "학생의 총점은 " + total + "점입니다.");
    	}
    }
    public class Subject {
    	private String name;
    	private int score;
    	
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getScore() {
    		return score;
    	}
    	public void setScore(int score) {
    		this.score = score;
    	}
    }

     

     


    댓글