관리 메뉴

LC Studio

JAVA & Spring 강의 (자바 인강 3주차) 객체 지향 입문 본문

Java/Java&Spring 기초 강의

JAVA & Spring 강의 (자바 인강 3주차) 객체 지향 입문

Leopard Cat 2022. 4. 1. 09:49

객체

구체적, 추상적 데이터의 단위

-객체를 정의하고, 객체의 기능을 구현하여, 객체의 기능간의 소통이 객체지향이다.

 

유저정보 객체

package ch01;

public class UserInfo {

	String userId;
	String userPassword;
	String userName;
	String address;
	int phoneNumber;
	
}

주문정보 객체

package ch01;

public class Order {

	int orderId;
	String buyerId;
	String sellerId;
	int productId;
	String orderDate;
	
}

학생정보 객체

package ch01;

public class Student {

	int studentNumber;
	String studentName;
	int major;
	String majorName;
	int grade;
	
}

책 정보 객체(연습)

package ch01;

public class Book {

	int bookNumber;
	String bookName;
	int bookPrice;
	String bookAuthor;
	
}

함수

기능을 수행하는 일련의 코드

함수는 이름, 매개 변수, 반환 값, 함수 몸체(body)로 구성된다.

아래 다양한 방식의 함수 예시를 구현해 보았다.

package ch03;

public class FuntionTest {

	//반환타입 + 매서드 이름 + 매개변수
	public static int addNum(int num1, int num2) {
		int result;
		result = num1 + num2;
		return result;
	}

	//반환타임 없음(void) + 메서드 이름 + 매개변수
	public static void sayHello(String greeting) {
		System.out.println(greeting);
	}
	
	//반환타입 + 메서드 이름
	public static int calcSum()
	{
		int sum = 0;
		int i;
		
		for(i=0;i<=100;i++) {
			sum += i;
		}
		
		return sum;
	}
	
	public static void main(String[] args) {
		int n1 = 10;
		int n2 = 20;
		
		int total = addNum(n1, n2);
		System.out.println(total);
		
		sayHello("HI");
		
		total = calcSum();
		System.out.println(total);
		
	}
	
}

멤버변수 & 메서드

멤버변수 - 클래스 영역에 선언된 변수

메서드 - 특정 작업을 수행하는 일렬의 문장들을 묶은 것

 

package ch04;

public class Student {
	
	public int studentId;
	public String studentName;
	public String address;
	
	public void showStudentInfo() {
		System.out.println(studentId + "학번 학생의 이름은 "+ studentName + "이고, 주소는" +address+"입니다.");
	}
	
	public String getStudentName() {
		return studentName;
	}
	
	public void setStudentName(String name) {
		studentName = name;
	}
	

}

위의 코드에서...

 

멤버변수 선언

  • public int studentId;
  • public String studentName;
  • public String address;

메소드 선언

  • public void showStudentInfo() {
    System.out.println(studentId + "학번 학생의 이름은 "+ studentName + "이고, 주소는" +address+"입니다.");
    }

  • public String getStudentName() {
    return studentName;
    }

  • public void setStudentName(String name) {
    studentName = name;
    }
package ch04;

public class SudentTest {
	public static void main(String[] args) {
		
		Student studentLee = new Student(); //학생 한면 생성 (클래스를 기반으로 인스턴스 생성) //인스턴스 생성
		
		studentLee.studentId = 12345;
		studentLee.setStudentName("Lee");
		studentLee.address = "서울 강남구";
		
		studentLee.showStudentInfo();
		
		Student studentKim = new Student(); //학생 한면 생성 (클래스를 기반으로 인스턴스 생성)
		
		studentKim.studentId = 54321;
		studentKim.studentName = "Kim";
		studentKim.address = "서울 영등포구";
		
		studentLee.showStudentInfo();
	}
}

위의 코드는 Student 클래스를 기반으로 인스턴스를 생성하여, 

Student 클래스의 멤버변수와 메소드를 호출한 코드이다.


인스턴스 생성과 힙 메모리

인스턴스

- 클래스로부터 만들어진 객체 (기능을 구현하여 만들어 놓은 코드 상태)

힙 메모리

- 생성된 인스턴스가 할당되는 동적 메모리 공간

위의 예시를 보면, studentLee와 studentKim 인스턴스를 출력하면, 우측과 같이 힙 메모리 값이 나오는걸 볼 수 있다.

 

+인스턴스 생성연습

package ch02;

public class Order {

	int orderId;
	String buyerId;
	String sellerId;
	int productId;
	String productName;
	String orderDate;
	
	public void info() {
		System.out.println("주문 ID는 "+orderId+" 이시고, 선택하신 음식은 "+productName+ "입니다.");
	}
	
}
package ch02;

public class OrderTest {
	public static void main(String[] args) {
		
		Order orderKim = new Order();
		
		orderKim.orderId = 1234;
		orderKim.productName = "맘스터치 치킨+버거 세트";
		
		orderKim.info();
	}
}

=> 주문 ID는 1234 이시고, 선택하신 음식은 맘스터치 치킨+버거 세트입니다. 출력!


생성자

(Student st = new Student(); <- new 이때 생성되는 것이 생성자, 인스턴스 생성시 생성)

클래스라는 부분은 생성자를 정의하는 클래스의 이름과 동일하게 적어줘야 한다

class Student라면,

public Student(int studentNumber, String studentName, int grade){

}

위와같은 식으로 선언해주면 된다.

생성자가 없을 시, JVM에서 자동으로 생성해준다.

package ch06;

public class StudentTest {

	public static void main(String[] args) {

		
		//case 1
		Student studentLee = new Student();
		System.out.println(studentLee.showStudentInfo());
		
		
		//case 2
		Student studentKim = new Student(123456, "Kim", 3);
		System.out.println(studentKim.showStudentInfo());
	}

}
package ch06;

public class Student {

	//멤버변수는 만들어지는 동시에 자동 초기화
	public int studentNumber;
	public String studentName;
	public int grade;
	
	//생성자 case1 생성
	public Student() {}
	
	//생성자 case2 생성
	public Student(int studentNumber, String studentName, int grade) {
		
		//this는 멤버변수를 가르킴
		this.studentNumber = studentNumber;
		this.studentName = studentName;
		this.grade = grade;
		
	}
	
	public String showStudentInfo() {	
		return studentName + "학생의 학번은 "+ studentNumber +"이고, "+grade+ "학년 입니다.";
	}
	
}

 

 

위에서는 생성자 2개를 생성했다. 

 

이것을 오버로딩이라 한다.

오버로딩

여러가지 생성자를 정의하는 생성자

package ch06;

public class Student {

	//멤버변수는 만들어지는 동시에 자동 초기화
	public int studentNumber;
	public String studentName;
	public int grade;
	
	//생성자 case1 생성
	public Student() {}
	
	//생성자 case2 생성
	public Student(int studentNumber, String studentName, int grade) {
		
		//this는 멤버변수를 가르킴
		this.studentNumber = studentNumber;
		this.studentName = studentName;
		this.grade = grade;
		
	}
	
	public String showStudentInfo() {	
		return studentName + "학생의 학번은 "+ studentNumber +"이고, "+grade+ "학년 입니다.";
	}
}

위의 경우처럼 생성자를 여러개 생성하는 것을 오버로딩이라고 함.

생성자의 경우 this를 통해 멤버변수를 가르키게하여 구분하는 것이 중요!


참조 자료형

변수의 자료형에는 2가지 종류가 있다.

-기본 자료형 (int, long, float, double 등)

-참조 자료형 (String, Date, Student 등)

 

직접 클래스를 만들어서, 멤버변수로 사용하는 것.

클래스형으로 변수를 선언하는 것이다.

 

Subject class 생성

package ch09;

public class Subject {
	String subjectName;
	int score;
	int subjectID;
}

Student class 생성 및 참조 자료형 생성

package ch09;

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 showStudentSocre() {
		int total = korea.score + math.score;
		System.out.println(studentName +  " 학생의 총점은 " + total + "점 입니다." );
		
	}
}

SubjectTest class로 출력

package ch09;

public class SubjectTest {

	public static void main(String[] args) {
		
		Student studentLee = new Student(100, "Lee");
		studentLee.setKoreaSubject("국어", 100);
		studentLee.setMathSubject("수학", 16);
		
		Student studentKim = new Student(200, "Kim");
		studentKim.setKoreaSubject("국어", 10);
		studentKim.setMathSubject("수학", 60);
		
		studentLee.showStudentSocre();
		studentKim.showStudentSocre();

	}

}

접근 제어 지시자

accesss modifier / 클래스 외부에서 클래스의 (멤버 변수, 메서드, 생성자)들에대한 접근여부를 지정하는 키워드

 

1. private : 같은 클래스 내부에서만 접근 가능 ( 외부 클래스, 상속 관계의 클래스에서도 접근 불가)

2. protected : 같은 패키지나 상속관계의 클래스에서 접근 가능하고 그 외 외부에서는 접근 할 수 없음

3. public : 클래스의 외부 어디서나 접근 할 수 있음

4. default(아무 선언 없음) : 같은 패키지 내부에서만 접근 가능 ( 상속 관계라도 패키지가 다르면 접근 불가)

 

get()/ set() 메서드

get() // 가져오다

set() // 지정하다

private 으로 선언된 멤버 변수 (필드)에 대해 접근, 수정하는 메서드, public으로 제공

 

get, set 예제

Day, Month, Year에 대한 각각의 get, set

package ch10;

public class BirthDay {
	
	private int day;
	private int month;
	private int year;
	
	private boolean isValid; 
	//isValid의 경우 BirthDay class 안에서만 사용하기 떄문에, private가 좋다
	
	public int getDay() {
		return day;
	}
	
	public void setDay(int day) {
		this.day = day;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		if( month < 1 || month > 12) { //유효한 월인지 검증하는 조건문
			isValid = false; //객체 사용시 오류 확률 낮춘다
		}
		else {
			isValid = true;
			this.month = month;
		}
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}
	
	public void showDate()
	{
		if(isValid) {
			System.out.println(year + "년 " + month + "월 " + day+ "일 입니다.");
		}
		else {
			System.out.println("유효하지 않은 날짜입니다.");
		}
	}
}
package ch10;

public class BirthDayTest {

	public static void main(String[] args) {

		BirthDay date = new BirthDay();
		
		date.setYear(1965);
		date.setMonth(11);
		date.setDay(30);
		
		date.showDate();
	}

}

 

 


캡슐화

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

ex)

package ch11;

public class MakeReport {

	StringBuffer buffer = new StringBuffer();
	
	private String line = "===========================================\n";
	private String title = "  이름\t   주소 \t\t  전화번호  \n";
	private void makeHeader()
	{
		buffer.append(line);
		buffer.append(title);
		buffer.append(line);
	}
	
	private void generateBody()
	{
		buffer.append("James \t");
		buffer.append("Seoul Korea \t");
		buffer.append("010-2222-3333\n");
		
		buffer.append("Tomas \t");
		buffer.append("NewYork US \t");
		buffer.append("010-7777-0987\n");
	}
	
	private void makeFooter()
	{
		
		buffer.append(line);
	}
	
	public String getReport()
	{
		makeHeader();
		generateBody();
		makeFooter();
		return buffer.toString();
	}
}

위 코드의 getReport() 메서드에서 위의 private메서드를 캡슐화한 형태를 띄고있다.


this

1. 객체 자신을 가르킴 (인스턴스 내에서 자기 자신의 메모리를 가리킴)

   생성된 인스턴스 메모리의 주소를 가짐

public class Person {
	
	String name;
	int age;
	
	public Person(String name, int age) 
	{
		this.name = name;
		this.age = age;
		//Person class 의 String name, int age;
	}

2. 생성자에서 다른 생성자를 호출

   클래스에 생성자가 여러 개 인경우, this를 이용하여 생성자에서 다른 생성자를 호출

package ch12;

public class Person {
	
	String name;
	int age;
	
	public Person()
	{
		this("no name", 1);
		//Person(String name, int age) 생성자를 호출 
	}
	
	public Person(String name, int age) 
	{
		this.name = name;
		this.age = age;
		//Person class 의 String name, int age;
	}

3. 자신의 주소를 반환

package ch12;

public class Person {
	
	String name;
	int age;
	
	public Person()
	{
		this("no name", 1);
		//Person(String name, int age) 생성자를 호출 
	}
	
	public Person(String name, int age) 
	{
		this.name = name;
		this.age = age;
		//Person class 의 String name, int age;
	}
	
	public Person getPerson() {
		return this;
        //자신의 주소 반환
	}	
}
package ch12;

public class Person {
	
	String name;
	int age;
	
	public Person()
	{
		this("no name", 1);
		//Person(String name, int age) 생성자를 호출 
	}
	
	public Person(String name, int age) 
	{
		this.name = name;
		this.age = age;
		//Person class 의 String name, int age;
	}
	
	public void showPerson()
	{
		System.out.println(name + ","+age);
	}
	
	public Person getPerson() {
		return this;
	}
	
	public static void main(String[] args) {
		
		Person person = new Person();
		person.showPerson();
		
		System.out.println(person);
		
		Person person2 = person.getPerson();
		System.out.println(person2);
	}
	
}

객체 간의 협력

하나의 객체가 혼자 돌아가는 것이 아닌, 다른 객체들과 유기적으로 연결

(메세지 전송 및 처리)

객체간의 협력

package ch14;

public class Student {
	
	String studentName;
	int money;
	
	public Student(String studentName, int money) {
		this.studentName = studentName;
		this.money = money;
	}
	
	//버스타는 경우
	//Bus class와 연결
	public void takeBus(Bus bus) {
		bus.take(1000);
		this.money -= 1000;
	}
	
	//지하철타는 경우
    //Subway class와 연결
	public void takeSubway(Subway subway) {
		subway.take(1200);
		this.money -= 1200;
	}
	
	public void showInfo() {
		System.out.println(studentName + "님의 남은 돈은" + money + "원 입니다.");
	}

}

Subway.java

	package ch14;

public class Subway {

	int lineNumber;
	int passengerCount;
	int money;
	
	public Subway(int lineNumber) {
		this.lineNumber = lineNumber;
	}
	
	public void take(int money) {
		this.money += money;
		passengerCount++;
	}
	
	public void showSubwayInfo() {
		System.out.println(lineNumber+"호의 승객 수는"+passengerCount+ "명 이고, 수입은"+money+"원입니다.");
	}
}

Bus.java

package ch14;

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 showBusInfo() {
		System.out.println(busNumber+"번의 승객 수는"+passengerCount+ "명 이고, 수입은"+money+"원입니다.");		
	}
	
}
package ch14;

public class TakeTransTest {
	public static void main(String[] args) {
		
		Student studentJ = new Student("James", 5000);
		Student studentT = new Student("Tomas", 10000);
		
		Bus bus100 = new Bus(100);
		studentJ.takeBus(bus100);
		
		Subway greenSubay = new Subway(2);
		studentT.takeSubway(greenSubay);
		
		studentJ.showInfo();
		studentT.showInfo();
		
		bus100.showBusInfo();
		greenSubay.showSubwayInfo();
	}
}

Taxi 추가해보기 과제,

Taxi.java

package ch14;

public class Taxi {
	
	int taxiNumber;
	int passengerCount;
	int money;
	
	public Taxi(int taxiNumber) {
		this.taxiNumber = taxiNumber;
	}
	
	public void takeTaxi(int money) {
		this.money += money;
		this.passengerCount++;
	}
	
	public void showTaxiInfo() {
		System.out.println(taxiNumber+"번의 승객 수는"+passengerCount+ "명 이고, 수입은"+money+"원입니다.");
	}
	
}

Student.java에서 택시타는 경우 추가

//택시를 타는 경우
	public void takeTaxi(Taxi taxi) {
		taxi.takeTaxi(10000);
		this.money -= 10000;
	}

main 함수에서 아래 내용 추가하여 출력!

Taxi taxi10 = new Taxi(10);
		Edward.takeTaxi(taxi10);
		
		Edward.showInfo();
		taxi10.showTaxiInfo();

static 변수

여러 인스턴스에서 공통으로 사용하는 변수

주로 여러 인스턴스가 공유하는 기준 값이 필요한 경우에 사용

 

ex) serialNum 이라는 static변수 공유

package ch16;

public class Employee {

	public static int serialNum = 1000;
	//static 변수
	
	private int employeeId;
	private String employeeName;
	private String department;
	
	public int getEmployeeId() {
		return employeeId;
	}
	public void setEmployeeId(int employeeId) {
		this.employeeId = employeeId;
	}
	public String getEmployeeName() {
		return employeeName;
	}
	public void setEmployeeName(String employeeName) {
		this.employeeName = employeeName;
	}
	public String getDepartment() {
		return department;
	}
	public void setDepartment(String department) {
		this.department = department;
	}
	
	
}
package ch16;

public class EmployeeTest {

	public static void main(String[] args) {
		
		Employee employeeLee = new Employee();
		employeeLee.setEmployeeName("이순신");
		
		System.out.println(employeeLee.serialNum);
		
		Employee employeeKim = new Employee();
		employeeKim.setEmployeeName("김유신");
		employeeKim.serialNum++;
		
		System.out.println(employeeLee.serialNum);
		System.out.println(employeeKim.serialNum);
		
	}
}

static 변수를 공유하기 때문에, serialNum의 수가 같은 것을 알 수 있다

static 변수와 메서드는 인스턴스 변수, 메서드가 아니므로 클래스 이름으로 직접 참조

//static 변수는 인스턴스 없이도 사용가능
///왜냐하면 이미 메모리에 올라와있기 때문에

인스턴스.static변수 X

클래스.static변수 O


싱글톤 패턴

객체지향적인 코드작성을 위한 여러 디자인 패턴 중 하나.

싱글톤 패턴 (인스턴스가 여러개면 안되는 상황에 사용하는 패턴)

package ch18;

public class Company {

	private static Company instance = new Company();
	//클래스 내부에 유일한 private 인스턴스 생성
	
	private Company() {
		
	}
	
	//외부에서 유일한 인스턴스를 참조할 수 있는 public 메서드 제공
	public static Company getInstance() {
		if( instance == null) {
			instance = new Company();
		}
		return instance;
	}
}

구조 ( + => public, - => private)

Singleton
-instance
-Singleton
+getInstance

배열

동일한 자료형의 순차적 구조

 

배열 선언 방법

int[] arr1 = new int[10];  //타입, 변수명, [] 를 좌변에 선언하고, new, 타입, 배열 크기 선언 
int arr2[] = new int[10]; //동일

배열 초기화 방법

기본적으로 선언과 동시에 초기화

int[] numbers = new int[] {10, 20, 30};  //개수 생략해야 함

int[] numbers = {10, 20, 30};            // new int[]  생략 가능 

int[] ids; 
ids = new int[] {10, 20, 30};            // 선언후 배열을 생성하는 경우는 new int[] 생략할 수 없음
반응형