하위 클래스를 생성하면 상위 클래스가 먼저 생성됨

 

package ch03;

public class Customer {
	protected int customerID; //하위 클래스에선 접근 가능하지만 외부 클래스는 접근 불가
	protected String customerName;
	protected String customerGrade;
	int bonusPoint; //package default ->다른 package에서 접근 불가
	double bonusRatio;
	
	/*public Customer() {
		
		customerGrade="SILVER";
		bonusRatio=0.01;
		
		System.out.println("Customer() call");
	}*/
	public Customer(int customerID, String customerName) {
		this.customerID=customerID;
		this.customerName=customerName;
		
		customerGrade="SILVER";
		bonusRatio=0.01;
		System.out.println("Customer(int,String) call");
	}
	public int clacPrice(int price) {
		bonusPoint+=price*bonusRatio;
		return price;
	}
	public String showCustomerInfo() {
		return customerName+"님의 등급은 "+customerGrade+"이며 보너스포인트는 " + bonusPoint+"입니다.";
	}
	public int getCustomerID() {
		return customerID;
	}
	public void setCustomerID(int customerID) {
		this.customerID = customerID;
	}
	public String getCustomerName() {
		return customerName;
	}
	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}
	public String getCustomerGrade() {
		return customerGrade;
	}
	public void setCustomerGrade(String customerGrade) {
		this.customerGrade = customerGrade;
	}
	

}
package ch03;

public class VIPCustomer extends Customer {
	
	double salesRatio;
	String agentID;
	
	/*public VIPCustomer() {
		// super(); 오류 발생
		super(0,null); //상위 클래스의 생성자를 명시적으로 호출해줘야 O
		bonusRatio=0.05;
		salesRatio=0.1;
		customerGrade="VIP";
		System.out.println("VIP Customer() call");
	}*/
	
	public VIPCustomer(int customerID, String customerName) {
		super(customerID,customerName);
		
		//여기서 값 덮어씌우기!
		customerGrade="VIP";
		bonusRatio=0.1;
		System.out.println("VIP Customer(int,String) call");
		
	}
}
package ch03;

public class CustomerTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Customer customerLee= new Customer(10010,"이순신");
		customerLee.bonusPoint=1000;
		System.out.println(customerLee.showCustomerInfo());
		
		VIPCustomer customerKim = new VIPCustomer(10020,"김유신");
		customerKim.bonusPoint=10000;
		System.out.println(customerKim.showCustomerInfo());
	}

}

멤버십 시나리오

회사에서 고객 정보를 활용한 맞춤 서비스를 하기 위해 일반고객(Customer)과
이보다 충성도가 높은 우수고객(VIPCustomer)에 따른 서비스를 제공하고자 함

물품을 구매할 떄 적용되는 할인율과 적립되는 보너스 포인트의 비율이 다름
여러 멤버십에 대한 각각 다양한 서비스를 제공할 수 있음
멤버십에 대한 구현을 클래스 상속을 활용하여 구현해보기

일반 고객 (Customer) 클래스 구현

고객의 속성: 고객 아이디, 고객 이름, 보너스 포인트, 보너스 포인트 적립 비용

일반 고객의 경우 물품 구매 시 1%의 보너스 포인트 적립

package ch03;

public class Customer {
	protected int customerID; //하위 클래스에선 접근 가능하지만 외부 클래스는 접근 불가
	protected String customerName;
	protected String customerGrade;
	int bonusPoint; //package default ->다른 package에서 접근 불가
	double bonusRatio;
	
	public Customer() {
		
		customerGrade="SILVER";
		bonusRatio=0.01;
	}
	public int clacPrice(int price) {
		bonusPoint+=price*bonusRatio;
		return price;
	}
	public String showCustomerInfo() {
		return customerName+"님의 등급은 "+customerGrade+"이며 보너스포인트는 " + bonusPoint+"입니다.";
	}
	public int getCustomerID() {
		return customerID;
	}
	public void setCustomerID(int customerID) {
		this.customerID = customerID;
	}
	public String getCustomerName() {
		return customerName;
	}
	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}
	public String getCustomerGrade() {
		return customerGrade;
	}
	public void setCustomerGrade(String customerGrade) {
		this.customerGrade = customerGrade;
	}
	

}

우수 고객 구현(VIP Customer)

매출에 더 많은 기여를 하는 단골 고객

제품을 살 때 10% 할인해 줌

보너스 포인트는 제품 가격의 5%를 적립해줌

담당 전문 상담원이 배정됨

이미 Customer에 구현된 내용이 중복되므로 Customer을 확장하여 구현함(상속)

 

package ch03;

public class VIPCustomer extends Customer {
	
	double salesRatio;
	String agentID;
	
	public VIPCustomer() {
		bonusRatio=0.05;
		salesRatio=0.1;
		customerGrade="VIP";
	}
}
package ch03;

public class CustomerTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Customer customerLee= new Customer();
		customerLee.setCustomerName("이순신");
		customerLee.setCustomerID(10010);
		customerLee.bonusPoint=1000;
		System.out.println(customerLee.showCustomerInfo());
		
		VIPCustomer customerKim = new VIPCustomer();
		customerKim.setCustomerName("김유신");
		customerKim.setCustomerID(10020);
		customerKim.bonusPoint=10000;
		System.out.println(customerKim.showCustomerInfo());
	}

}

 

package ch23;
import java.util.ArrayList;
import ch21.Book;
public class ArrayListTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		ArrayList<Book> library = new ArrayList<>();
		
		library.add(new Book("태백산맥","조정래"));
		library.add(new Book("태백산맥","조정래"));
		library.add(new Book("태백산맥","조정래"));
		library.add(new Book("태백산맥","조정래"));
		library.add(new Book("태백산맥","조정래"));
		
		for(int i=0;i<library.size();i++) {
			System.out.println(library.get(i));
			library.get(i).showInfo();
		}
		

	}

}

ArrayList 활용한 성적산출 프로그램

package ch24;
import java.util.ArrayList;

public class Student {
	public String studentName;
	public int studentNum;
	private int total; //과목 총점
	ArrayList<Subject> subjectList;
	
	public Student(int studentNum,String studentName) {
		this.studentNum=studentNum;
		this.studentName=studentName;
		subjectList= new ArrayList<>();
		
	}
	public void addSubject(String subjectName, int grade) {
			subjectList.add(new Subject(subjectName,grade));
			total+=grade;
	}
	public void showStudentInfo() {
		for(int i=0;i<subjectList.size();i++) {
			System.out.println("학생 "+studentName+"의 "+subjectList.get(i).subjectgrade+"입니다.");
		}
		System.out.println("학생 "+studentName+"의 총점은 "+total+"입니다.");
	}
	

}
package ch24;

public class Subject {
	public String subjectName;
	public int subjectgrade;
	
	public Subject() {
		
	}
	public Subject(String subject, int grade) {
		this.subjectName=subject;
		this.subjectgrade=grade;
		
	}
	
	
}
package ch24;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		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.showStudentInfo();
		System.out.println("==================================================");
		studentKim.showStudentInfo();
		
	}

}

++

학생 Lee의 100입니다.

학생 Lee의 50입니다.

학생 Lee의 총점은 150입니다.

==================================================

학생 Kim의 70입니다.

학생 Kim의 85입니다.

학생 Kim의 100입니다.

학생 Kim의 총점은 255입니다.

 

++

package ch24;
import java.util.ArrayList;

public class Student {
	public String studentName;
	public int studentNum;
	private int total; //과목 총점
	ArrayList<Subject> subjectList;
	
	public Student(int studentNum,String studentName) {
		this.studentNum=studentNum;
		this.studentName=studentName;
		subjectList= new ArrayList<>();
		
	}
	public void addSubject(String subjectName, int grade) {
			Subject subject = new Subject();
			subject.setSubjectName(subjectName);
			subject.setSubjectgrade(grade);
			
			subjectList.add(subject);
	}
	public void showStudentInfo() {
		for(Subject subject : subjectList) {
			total+=subject.getSubjectgrade();
			System.out.println(studentName+subject.getSubjectgrade());
		}
		System.out.println("학생 "+studentName+"의 총점은 "+total+"입니다.");
	}
	

}

 

 

package ch20;

public class Calculate {

	public static void main (String[] args) {
		int[] arr= new int[10];
		int total=0;
		
		for(int i=0,num=1;i<arr.length;i++) {
			arr[i]=num++;
			total+=arr[i];
		}
		System.out.println("Total: "+total);
	}
}

향상된 for문 사용하기

package ch20;

public class Calculate {

	public static void main (String[] args) {
		char[] alpahbets = new char[26];
		char ch='A';
		
		for(int i=0;i<alpahbets.length;i++) {
			alpahbets[i]=ch++;
		}
		for(char alpha:alpahbets) {
			System.out.println(alpha+", "+(int)alpha);
		}
		}
}

객체배열

package ch21;

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:"+title);
		System.out.println("Author: "+author);
	}

}

package ch21;

public class BookTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Book[] library = new Book[5]; // 객체의 주소만 할당됨
		
		for(int i=0;i<library.length;i++) {
			System.out.println(library[i]);
		}
		
		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();
		}
	}

}

배열 복사하기

package ch21;

public class ObjectCopyTest {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Book[] library = new Book[5]; // 객체의 주소만 할당됨
		Book[] copy = 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","조정래");
		
		
		System.arraycopy(library, 0, copy, 0, 5);
		System.out.println("======원래 배열========");
		for (Book book:library) {
			System.out.println(book);
			book.showInfo();
		}
		System.out.println("======복붙 배열========");
		for (Book book:copy) {
			System.out.println(book);
			book.showInfo();
		}
		//주소까지 전부 다름
		
		library[0].setAuthor("박완서");
		library[0].setTitle("나목");
		//아래 두 배열 모두 0번째 배열 내용이 바뀜
		System.out.println("======원래 배열========");
		for (Book book:library) {
			System.out.println(book);
			book.showInfo();
		}
		System.out.println("======복붙 배열========");
		for (Book book:copy) {
			System.out.println(book);
			book.showInfo();
		}
	}
}

주소 다르게 깊은 복사

package ch21;

public class ObjectCopyTest {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Book[] library = new Book[5]; // 객체의 주소만 할당됨
		Book[] copy = 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","조정래");
		
		Book[] copyReal = new Book[5];
		copyReal[0]=new Book();
		copyReal[1]=new Book();
		copyReal[2]=new Book();
		copyReal[3]=new Book();
		copyReal[4]= new Book();
		
		for(int i=0;i<library.length;i++) {
			copyReal[i].setAuthor(library[i].getAuthor());
			copyReal[i].setTitle(library[i].getTitle());
		}
		
		System.arraycopy(library, 0, copy, 0, 5);
		System.out.println("======원래 배열========");
		for (Book book:library) {
			System.out.println(book);
			book.showInfo();
		}
		System.out.println("======복붙 배열========");
		for (Book book:copy) {
			System.out.println(book);
			book.showInfo();
		}
		//주소까지 전부 다름
		
		library[0].setAuthor("박완서");
		library[0].setTitle("나목");
		//아래 두 배열 모두 0번째 배열 내용이 바뀜
		System.out.println("======원래 배열========");
		for (Book book:library) {
			System.out.println(book);
			book.showInfo();
		}
		System.out.println("======복붙 배열========");
		for (Book book:copy) {
			System.out.println(book);
			book.showInfo();
		}
		
		System.out.println("======주소까지 전부 다른 복붙 배열========");
		for (Book book:copyReal) {
			System.out.println(book);
			book.showInfo();
		}
	}
}

다차원 배열

package ch20;

public class Calculate {

	public static void main (String[] args) {
	int[][]arr= {{1,2,3},{1,2,3,4}};
	
	int i,j;
	for(i=0;i<arr.length;i++) {
		//arr.length는 행의 길이
		for(j=0;j<arr[i].length;j++) {
			System.out.print(arr[i][j]+",");
		}
		System.out.println("\t"+arr[i].length);
	}
	}
}

 

static 변수

- 여러 인스턴스를 공통으로 사용하는 변수

- 인스턴스가 생성될 때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될 때 메모리를 할당 <- 데이터 영역

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

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

ex) Employee.serialNum 으로 바로 참조해서 사용O

 

 

Employee

package ch16;

public class Employee {
	
	public static int serialNum=1000;
	
	private int employeeId;
	private String employeeName;
	private String department;
	
	public Employee() {
		serialNum++;//한명이 증가할 때마다 하나씩 증가
		employeeId=serialNum;//기준값에 대입
	}
	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;
	}
	
	
}

EmployeeTest

package ch16;

public class EmployeeTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Employee employeeLee = new Employee();
		employeeLee.setEmployeeName("이순신");
		
		System.out.println(employeeLee.serialNum);
		
		Employee employeeKim= new Employee();
		employeeKim.setEmployeeName("김유신");
		employeeKim.serialNum++;
		
		System.out.println(employeeLee.getEmployeeName()+employeeLee.getEmployeeId());
		System.out.println(employeeKim.getEmployeeName()+employeeKim.getEmployeeId());
		//두 개의 인스턴스가 하나의 메모리, 하나의 변수를 접근
		
	}

}

static 메서드

package ch16;

public class Employee {
	
	private static int serialNum=1000; //외부에서 변경 불가능하도록 private로
	
	
	private int employeeId;
	private String employeeName;
	private String department;
	
	public Employee() {
		serialNum++;//한명이 증가할 때마다 하나씩 증가
		employeeId=serialNum;//기준값에 대입
	}
	
	public static int getSerialNum() {
		return serialNum;
	}

	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) {
		// TODO Auto-generated method stub
		Employee employeeLee = new Employee();
		employeeLee.setEmployeeName("이순신");
		
		System.out.println(employeeLee.getSerialNum());
		
		Employee employeeKim= new Employee();
		employeeKim.setEmployeeName("김유신");
		
		System.out.println(employeeLee.getEmployeeName()+employeeLee.getEmployeeId());
		System.out.println(employeeKim.getEmployeeName()+employeeKim.getEmployeeId());
		//두 개의 인스턴스가 하나의 메모리, 하나의 변수를 접근
		
	}

}

 

변수의 유효 범위와 메모리

- 변수의 유효범위(scope)와 생성과 소멸(life cycle)은 각 변수의 종류마다 다름

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

- 클래스 내부의 여러 메서드에서 사용하는 변수는 멤버 변수로 선언하는 것이 좋음

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

- 상황에 적절하게 변수 사용해야함

 

static 응용- 싱글톤패턴

Company

package ch17;

public class Company {
	
	//생성자를 company를 생성
	//컴파일러는 생성자를 마음대로 생성할 수 O
	private static Company instance = new Company();
	private Company() {
		
	}
	public static Company getInstance() {
		if(instance==null) {
			instance= new Company();
		}
		return instance;
		//외부에서 접근 가능하도록
	}
	
}

CompanyTest

package ch17;

import java.util.Calendar;
public class CompanyTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Company company = Company.getInstance();
		//이미 인스턴스 만들어놨으니 바로 가져다 써서 사용
		//여러개 생성해도 같은 인스턴스만 생성
		System.out.println(company);
		
		Calendar calendar = Calendar.getInstance();
	}

}

 

 

 

과제(static과 싱글톤 패턴)

자동차 공장이 있습니다. 자동차 공장은 유일한 객체이고, 이 공장에서 생산되는 자동차는 제작될 때마다 고유한 번호가 부여됩니다. 자동차 번호가 1001부터 시작되어 자동차가 생산될 때마다 1002,1003 이렇게 번호가 붙도록 자동차 공장 클래스, 자동차 클래스를 구현하세요

 

package ch19;

public class Car {
	
	private int carNum;
	private String carName;
	public static int serialNum=1001;
	
	
	public Car() {
		this.carNum=serialNum;
		serialNum++;
	}

	public int getCarNum() {
		return carNum;
	}

}
package ch19;

public class CarFactory {
	
	private String factoryName;
	private String factoryAddress;
	private static CarFactory instance = new CarFactory("순양","평택");
	private CarFactory(String name, String address) {
		this.factoryName=name;
		this.factoryAddress=address;
	}
	public static CarFactory getInstance() {
		return instance;
	}
	public Car createCar() {
		Car car=new Car();
		return car;
	}

}
package ch19;

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());
		System.out.println(yourSonata.getCarNum());
	}
}

this : 객체 자신을 가리킴

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

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

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

생성자에서 다른 생성자를 호출하는 경우, 인스턴스의 생성이 완전하지 않은 상태이므로 this() statement 이전에 다른 statement를 사용할 수 없음 

package ch11;

public class Person {
	String name;
	int age;
	
	public Person() {
    //생성자에서 다른 생성자를 호출하는 경우, 
    //인스턴스의 생성이 완전하지 않은 상태이므로 this() statement 이전에 다른 statement를 사용할 수 없음 
		this("이름없음",1);
		
	}
	public Person(String name, int age) {
		this.name=name;
		this.age=age;
		
	}
}

3) 자기 자신의 주소를 반환하는 this

package ch11;

public class Person {
	String name;
	int age;
	
	public Person() {
		
		this("이름없음",1);
		
	}
	public Person(String name, int age) {
		this.name=name;
		this.age=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);
		//ch11.Person@515f550a
		
		Person person2= person.getPerson();
		System.out.println(person2);
		//ch11.Person@515f550a
	}
}

MakeReport

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-8888\n");
	}
	
	private void makeFooter() {
		buffer.append(line);
		
	}
	public String getReport() {
		//client code에 getRoport()만 제공함!<- 캡슐화
		makeHeader();
		generateBody();
		makeFooter();
		//위 세개 함수는 private로 
		return buffer.toString();
	}
}

MakeReportTest

package ch11;

public class MakeReportTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MakeReport builder = new MakeReport();
		String report= builder.getReport();
		
		System.out.println(report);
	}

}

학생은 국어 과목, 수학 과목을 수강중이며 각 과목의 총점을 계산하는 프로그램을 작성하라

 

Subject

package ch09;

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

}

Student

package ch09;

public class Student {

	int studentID;
	String studentName;
	Subject korea; //참조 자료형
	Subject math; //참조 자료형
	
	public Student(int id,String name) {
		studentID=id;
		studentName=name;
		korea= new Subject(); //생성을 해줘야 O , 대부분 생성자에서 생성
		math= new Subject(); // 생성을 해줘야 O
		
		
	}
	
	public void setKoreaScore(String name, int score) {
		//main에서 korea. 으로 설정해도 O
		korea.subjectName=name;
		korea.score=score;
	}
	public void setMathScore(String name, int score) {
		math.subjectName=name;
		math.score=score;	
	}
	
	public void showScoreInfo() {
		
		int total=korea.score+math.score;
		System.out.println("Total: "+total);
		
	}
}

TotalScore

package ch09;

public class TotalScore {
	//각 학생의 총점을 구함

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student studentKwak = new Student(10,"kwakseoyeon");
		Student studentLee = new Student (11, "Leeyeonwoo");
		Student studentKim = new Student (12, "Kimseowoo");
		
		studentKwak.setKoreaScore("korea", 90);
		studentKwak.setMathScore("math",80);
		
		studentLee.setKoreaScore("korea", 70);
		studentLee.setMathScore("math",30);
		
		studentKim.setKoreaScore("korea", 20);
		studentKim.setMathScore("math", 100);
		
		int KwakTotal= studentKwak.korea.score+studentKwak.math.score;
		int LeeTotal= studentLee.korea.score+studentLee.math.score;
		int KimTotal= studentKim.korea.score+studentKim.math.score;
		
		System.out.println(studentKwak.studentName+" Total: "+KwakTotal);
		System.out.println(studentLee.studentName+" Total: "+LeeTotal);
		System.out.println(studentKim.studentName+" Total: "+KimTotal);
		
	}

}

+ Recent posts