<Java 사전학습_3>
- 클래스와 객체(9~16강)
1. 클래스와 객체(9~16강)
객체(Object)
의사나 행위가 미치는 대상(사전적 의미)
구체적, 추상적 데이터 단위
객체 지향 프로그래밍(Object Oriented Programming, OOP)
객체를 기반으로 하는 프로그래밍
객체 정의 > 객체의 기능 구현 > 객체 사이의 협력 구현
(cf. 절차 프로그래밍(Procedural Programming)-C언어, 시간의 흐름에 따른 프로그래밍)
클래스(class)
객체에 대한 속성과 기능을 코드로 구현한 것
“클래스를 정의한다”라고 함
객체에 대한 청사진(blueprint)
객체의 속성
객체의 특성, 속성, 멤버 변수(인스턴스 변수)
property, attribute, member variable
객체의 기능
객체가 하는 기능들을 메서드로 구현
method, member function
클래스 정의하기
class는 대부분 대문자로 시작
하나의 java파일에 하나의 클래스를 두는 것이 원칙
여러 개의 클래스가 같이 있는 경우 public클래스는 단 하나이며, public클래스와 자바 파일의 이름은 동일해야 함
자바의 모든 코드는 class내부에 위치
(접근 제어자) class 클래스 이름{
멤버 변수; //속성-학번, 이름, 학년, 사는곳 등등
메서드; //기능-수강신청, 수업듣기, 시험보기 등등
}
클래스의 속성
클래스의 특징을 나타냄
property, attribute라고도 함
자료형을 이용하여 멤버 변수로 선언
클래스의 기능
메서드(method)로 구현
멤버 함수(member function)라고도 함
객체가 수행하는 기능을 구현
package classpart;
public class Student {
int studentID; //멤버변수-학번
String studentName; //멤버변수-학생 이름
int grade; //멤버변수-학년
String address; //멤버변수-사는 곳
public void showStudentInfo() {
System.out.println(studentName + "," + address); //메서드 추가-이름, 추소 출력
}
public static void main(String[] args) { //구동코드, 따로 구동 클래스를 만들수도 있음
Student studentLee = new Student();
studentLee.studentName = "루팽구";
studentLee.address = "서울 땡땡구 땡땡동";
studentLee.showStudentInfo();
}
}
package classpart;
public class StudentTest {
public static void main(String[] args) { //구동 클래스를 따로 만든 경우
Student studentLee = new Student();
studentLee.studentName = "루팽구";
studentLee.address = "서울 땡땡구 땡땡동";
studentLee.showStudentInfo();
}
}
메서드(method)
함수의 일종
객체의 기능을 제공하기 위해 클래스 내부에 구현되는 함수
함수
하나의 기능을 수행하는 일련의 코드
중복되는 기능은 함수로 구현하여 함수를 호출하여 사용
함수 정의하기
함수를 코드로 구현
함수의 이름, 매개변수, 반환 값을 선언하고 코드를 구현함
package classpart;
public class FunctionTest {
public static void main(String[] args) {
int num1 = 10;
int num2 = 30;
int sum = addNum(num1, num2); //addNum()함수 호출
System.out.println(sum); //40
}
public static int addNum(int n1, int n2) { //함수선언, n1 n2는 이 함수에서 새로 선언된것
//함수반환형int(자료형/없는경우 void) 함수이름(addNum) 매개변수(int n1, int n2)
int result = n1 + n2;
return result; //return 예약어-함수 수행 결과를 반환하기 위한 예약어
}
}
함수와 스택 메모리
함수가 호출될 때 사용하는 메모리-스택(stack)
함수의 기능 수행이 끝나면 자동으로 반환되는 메모리
클래스에 메서드 구현하기
클래스의 메서드는 멤버 변수를 사용하여 기능 구현
package classpart;
public class Student2 {
int studentID;
String studentName;
int grade; String address;
public void showStudentInfo() {
System.out.println(studentName + "," + address);
}
public String getStudentName() { //매개변수X, 반환O-학생 이름을 반환하는 메서드
return studentName;
}
public void setStudentName(String name) { //매개변수O, 반환X
studentName = name;
}
}
class & instance
클래스(static 코드) > 생성(인스턴스화) > 인스턴스(dynamic memory)
클래스 생성하기
클래스를 사용하기 위해서는 클래스를 생성해야 함
new 예약어를 이용하여 클래스 생성
클래스형 변수이름 = new 생성자;
Student studentA = new Student();
package classpart;
public class Student3 {
int studentID;
String studentName;
int grade;
String address;
public void showStudentInfo() {
System.out.println(studentName + "," + address);
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String name) {
studentName = name;
}
public static void main(String[] args) { //main은 다른 클래스로 만들떄가 더 많음
Student studentLee = new Student();
studentLee.studentName = "루팽구";
studentLee.studentID = 100;
studentLee.address = "서울 땡땡구";
Student studentKim = new Student();
studentKim.studentName = "루쿠카";
studentKim.studentID = 101;
studentKim.address = "서울 땡땡땡구";
studentLee.showStudentInfo();
studentKim.showStudentInfo();
}
}
package classpart;
public class StudentTest2 {
public static void main(String[] args) { //main클래스를 따로 만든 경우
Student studentLee = new Student();
studentLee.studentName = "루팽구";
studentLee.studentID = 100;
studentLee.address = "서울 땡땡구";
Student studentKim = new Student();
studentKim.studentName = "루쿠카";
studentKim.studentID = 101;
studentKim.address = "서울 땡땡땡구";
studentLee.showStudentInfo();
studentKim.showStudentInfo();
}
}
인스턴스와 힙(heap) 메모리
하나의 클래스 코드로부터 여러 개의 인스턴스를 생성
인스턴스는 힙(heap) 메모리에 생성됨
각각의 인스턴스는 다른 메모리에 다른 값을 가짐
클래스, 인스턴스, 참조 변수, 참조값
| 용어 | 설명 |
| 객체 | 객체 지향 프로그램의 대상, 생성된 인스턴스 |
| 클래스 | 객체를 프로그래밍 하기 위해 코드로 만든 상태 |
| 인스턴스 | 클래스가 메모리에 생성된 상태 |
| 멤버 변수 | 클래스의 속성, 특성 |
| 메서드 | 멤버 변수를 이용하여 클래스의 기능을 구현 |
| 참조 변수 | 메모리에 생성된 인스턴스를 가리키는 변수 |
| 참조 값 | 생성된 인스턴스의 메모리 주소 값 |
참조 변수와 참조 값
참조 변수
인스턴스 생성 시 선언하는 변수
참조 값
인스턴스가 생성되는 힙 메모리 주소
package classpart;
public class StudentTest3 {
public static void main(String[] args) {
Student studentLee = new Student();
studentLee.studentName = "루팽구";
studentLee.studentID = 100;
studentLee.address = "서울 땡땡구";
Student studentKim = new Student();
studentKim.studentName = "루쿠카";
studentKim.studentID = 101;
studentKim.address = "서울 땡땡땡구";
studentLee.showStudentInfo();
studentKim.showStudentInfo();
System.out.println(studentLee); //참조값-classpart.Student@5ca881b5
System.out.println(studentKim); //참조값-classpart.Student@24d46ca6
}
}
생성자(constructor)
생성자는 인스턴스를 초기화할 때의 명령어 집합
생성자 이름은 클래스 이름과 동일
생성자는 메서드가 아님. 상속되지 않으며 리턴 값은 없음
<modifiers><class_name>([<argument_list>]) {
[<statements>]
}
public Class_name() {} //디폴트 생성자-생성자가 하나도 없을 때 생김
디폴트 생성자(default constructor)
하나의 클래스에는 반드시 적어도 하나 이상의 생성자가 존재
프로그래머가 생성자를 기술하지 않으면 Default Constructor가 자동으로 생김(컴파일러가 코드에 넣어줌)
디폴트 생성자에는 매개변수, 구현부가 없음
만약 클래스에 매개변수가 있는 생성자를 추가하면 디폴트 생성자는 제공되지 않음
생성자 오버로드(constructor overload)
필요에 의해 생성자를 추가하는 경우 여러 개의 생성자가 하나의 클래스에 있음
package classpart;
public class Person {
String name;
float height;
float weight;
// public Person() {} //디폴트 생성자
public Person(String pname) { //이름을 매개변수로 입력받는 생성자
name = pname;
}
public Person(String pname, float pheight, float pweight) {
name = pname;
height = pheight;
weight = pweight;
//이름, 키, 몸무게를 매개변수로 입력받는 생성자
}
}
클래스 구동 연습
package classpractice;
public class CatFn {
int catId;
String catName;
String catColor;
int age;
float weight;
public void showCatInfo() {
System.out.println("ID: " + catId + ", Name: "+ catName + ", Color: " + catColor
+ ", Age: " + age + ", Weight: " + weight + "kg");
}
public CatFn(int cId, String cName, String cColor, int cAge, float cWeight) {
catId = cId;
catName = cName;
catColor = cColor;
age = cAge;
weight = cWeight;
}
}
package classpractice;
public class CatMn {
public static void main(String[] args) {
CatFn cat1 = new CatFn(1, "Luppang", "Brown", 3, 4.5F);
CatFn cat2 = new CatFn(2, "Luka", "Black", 17, 4.3F);
CatFn cat3 = new CatFn(3, "Louie", "White", 15, 5.7F);
cat1.showCatInfo(); //ID: 1, Name: Luppang, Color: Brown, Age: 3, Weight: 4.5kg
cat2.showCatInfo(); //ID: 2, Name: Luka, Color: Black, Age: 17, Weight: 4.3kg
cat3.showCatInfo(); //ID: 3, Name: Louie, Color: White, Age: 15, Weight: 5.7kg
}
}
package classpractice;
public class CatFn2 {
int catId;
String catName;
String catColor;
int age;
float weight;
public void showCatInfo() {
System.out.println("ID: " + catId + ", Name: "+ catName + ", Color: " + catColor
+ ", Age: " + age + ", Weight: " + weight + "kg");
}
public String getCatName() {
return catName;
}
public void setCatName(String name) {
catName = name;
}
}
package classpractice;
public class CatMn2 {
public static void main(String[] args) {
CatFn2 cat1 = new CatFn2();
cat1.catId = 001;
cat1.catName = "Luppang";
cat1.catColor = "Brown";
cat1.age = 3;
cat1.weight = 4.5F;
CatFn2 cat2 = new CatFn2();
cat2.catId = 002;
cat2.catName = "Luka";
cat2.catColor = "Black";
cat2.age = 17;
cat2.weight = 4.3F;
CatFn2 cat3 = new CatFn2();
cat3.catId = 003;
cat3.catName = "Louie";
cat3.catColor = "White";
cat3.age = 15;
cat3.weight = 5.7F;
cat1.showCatInfo(); //ID: 1, Name: Luppang, Color: Brown, Age: 3, Weight: 4.5kg
cat2.showCatInfo(); //ID: 2, Name: Luka, Color: Black, Age: 17, Weight: 4.3kg
cat3.showCatInfo(); //ID: 3, Name: Louie, Color: White, Age: 15, Weight: 5.7kg
System.out.println(cat1); //classpractice.CatFn2@5ca881b5
System.out.println(cat2); //classpractice.CatFn2@24d46ca6
System.out.println(cat3); //classpractice.CatFn2@4517d9a3
}
}
참조 자료형(reference data type)
기본 자료형
int, long, floatm double 등
참조 자료형
String, Date, 직접 만든 자료형 등
package reference;
public class Point { int x; int y; }
package reference;
public class Circle {
Point point; //직접 만든 클래스 int radius;
public Circle() {
point = new Point();
}
}
package reference;
public class Student {
int studentId;
String studentName;
Subject korea;
Subject math; //선언-선언만으로 클래스가 생기진 않음
public Student() {
korea = new Subject("국어");
math = new Subject("수학"); //각 과목 인스턴스 생성
}
public Student(int id, String name) {
studentId = id;
studentName = name;
korea = new Subject("국어");
math = new Subject("수학");
}
public void setKorea(int score) {
korea.setScore(score);
}
public void setMath(int score) {
math.setScore(score);
}
public void showStudentInfo() {
int total = korea.getScore() + math.getScore();
System.out.println(studentName + "학생의 총점은 " + total + "점 입니다.");
}
}
package reference;
public class Subject {
String subjectName;
int score;
public Subject(String name) { //Subject를 생성할 떄 이름을 주기
subjectName = name;
}
public void setSubjectName(String name) {
subjectName = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getSubjectName() {
return subjectName;
}
}
package reference;
public class StudentTest {
public static void main(String[] args) {
Student studentJay = new Student(100, "JBR");
studentJay.setKorea(100);
studentJay.setMath(100);
Student studentLu = new Student(101, "LPG");
studentLu.setKorea(80);
studentLu.setMath(60);
studentJay.showStudentInfo();
studentLu.showStudentInfo();
}
}
정보은닉(information hiding)
private-접근제어자
클래스의 외부에서 클래스 내부의 멤버 변수나 메서드에 접근(access) 하지 못하게 하는 경우 사용
멤버 변수나 메서드를 외부에서 사용하지 못하도록 하여 오류를 줄일 수 있음
변수에 대해서는 필요한 경우 get(), set() 메서드를 제공
public
외부 클래스 갖다 쓰기 가능
private
그 클래스 안에서만 가능
default(아무것도 안 쓸 경우)
같은 패키지 안에서 가능
package hiding;
class BirthDay {
private int day; //private는 이 클래스 안에서만 쓸 수 있음
private int month;
private int year;
public int getDay() { //public은 다른 클래스에서 쓸 수 있음
return day;
}
public void setDay(int day) {
if(month ==2) {
if(day < 1 || day > 28) {
System.out.println("날짜 오류입니다.");
}
}
else {
this.day = day;
}
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
}
public class BirthDayTest{ //public class는 1개이고 작업파일 이름과 같다
public static void main(String[] args) {
BirthDay day = new BirthDay();
day.setMonth(2);
day.setDay(30);
day.setYear(2018);
}
}
this가 하는 일
자신의 메모리를 가리킴
생성자에서 다른 생성자를 호출
자신의 주소를 반환함
public Person(String name, int age){ //name, age는 지역변수
this.name = name;
this.age = age; //this.age부분은 매개변수, 자신의 메모리를 가리키는 this
//위 코드에서 this를 생략하면 name이나 age는 파라미터로 사용되는 name과 age로 인식된다(가장 가까운 것)
public Person(){
this(”이름없음”, 1); //다른 생성자를 호출하는 this
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
//this를 이용하여 다른 생성자를 호출할 때는 그 이전에 어떠한 statement도 사용할 수 없다.
//위와 같이 생성자가 여러 개이고 파라미터만 다른 경우 constructor overloading이라고 한다.
package thisex;
class Birthday{
int day;
int month;
int year;
public void setYear(int year) {
this.year = year; //이 클래스의 year에 year의 수를 넣어라
}
public void printThis() {
System.out.println(this);
}
}
public class ThisEx {
public static void main(String[] args) {
Birthday b1 = new Birthday();
Birthday b2 = new Birthday();
System.out.println(b1); //thisex.Birthday@5ca881b5
b1.printThis(); //thisex.Birthday@5ca881b5
System.out.println(b2); //thisex.Birthday@24d46ca6
b2.printThis(); //thisex.Birthday@24d46ca6
}
}
package thisex;
class Person{
String name;
int age;
public Person() {
//this를 쓸 때는 this가 가장 먼저 나오는 statement여야한다
this("이름없음", 1); //매개변수 개수, 데이터타입이 맞으면 알아서 호출해줌
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person returnSelf() {
return this; //자신의 주소 반환
}
}
public class CallAnotherConst {
public static void main(String[] args) {
Person p1 = new Person();
System.out.println(p1.name); //이름없음
System.out.println(p1.returnSelf()); //this값 출력
}
}
객체 간의 협력
package cooperation;
public class Student {
String studentName;
int grade;
int money;
public Student(String studentName, int money) {
this.studentName = studentName;
this.money = money;
}
public void takeBus (Bus bus) {
bus.take(1000); //객체협업, Bus메소드 호출해서 사용
money -= 1000;
}
public void takeSubway (Subway subway) {
subway.take(1500); //객체협업, Subway메소드 호출해서 사용
money -= 1500;
}
public void showInfo() {
System.out.println(studentName + "님의 잔액은 " + money + "원 입니다.");
}
}
package cooperation;
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 + "원 입니다.");
}
}
package cooperation;
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 showInfo() {
System.out.println("지하철 " + lineNumber + "호선의 승객은 " + passengerCount
+ "명이고, 수입은 " + money + "원 입니다.");
}
}
package cooperation;
public class TakeTrans {
public static void main(String[] args) {
Student luppang = new Student("Luppang", 5000);
Student luka = new Student("Luka", 10000);
Bus bus100 = new Bus(100);
luppang.takeBus(bus100);
luppang.showInfo(); //Luppang님의 잔액은 4000원 입니다.
bus100.showInfo(); //버스 100번의 승객은 1명이고, 수입은 1000원 입니다.
Subway subwayGreen = new Subway(2);
luka.takeSubway(subwayGreen);
luka.showInfo(); //Luka님의 잔액은 8500원 입니다.
subwayGreen.showInfo(); //지하철 2호선의 승객은 1명이고, 수입은 1500원 입니다.
}
}
static 변수
정적변수
여러 개의 인스턴스가 같은 메모리의 값을 공유하기 위해 사용
기준이 되는 값은 static변수로 생성하여 유지
인스턴스가 생성될 때마다 다른 메모리를 가지는 것이 아니라 프로그램이 메모리에 적재(load)될 떄 데이터 영역의 메모리에 생성됨
따라서 인스턴스의 생성과 관계없이 클래스 이름으로 직접 참조함
클래스 변수라고도 함
static int serialNum; //static예약어 자료형 변수이름
Student.serialNum = 100l //serialNum이 static변수
static 메서드
클래서 메서드라고도 함
메서드에 static키워드를 사용하여 구현
주로 static변수를 위한 기능 제공
static메서드에서 인스턴스 변수를 사용할 수 없음
static메서드도 인스턴스의 생성과 관계없이 클래스 이름으로 직접 메서드 호출
인스턴스 변수의 경우 꼭 인스턴스가 먼저 생성되어야 하므로 static메서드에서는 생성이 불확실한 인스턴스 변수를 사용할 수 없음
Student.getSerialNum(); //getSerialNum()이 static메서드
package staticex;
public class Student {
private static int serialNum = 10000;
int studentId;
String studentName;
public Student() {
serialNum++;
studentId = serialNum;
}
public static int getSerialNum() {
// int i = 10; //지역변수
// studentName = "루팽구"; //멤버변수, 인스턴스변수
// static메서드에선 인스턴스 변수를 사용할 수 없음!
return serialNum; //static변수, 클래스변수
}
}
package staticex;
public class StudentTest1 {
public static void main(String[] args) {
System.out.println(Student.getSerialNum()); //10000
Student studentJ = new Student();
System.out.println(studentJ.studentId); //10001
Student studentL = new Student();
System.out.println(studentL.studentId); //10002
}
}
변수의 유효 범위
| 변수유형 | 선언위치 | 사용범위 | 메모리 | 생성과 소멸 |
| 지역변수(로컬변수) | 함수 내부에 선언 | 함수 내부에서만 사용 | 스택 | 함수가 호출될 떄 생성되고 함수가 끝나면 소멸함 |
| 멤버변수(인스턴스 변수) | 클래스 멤버 변수로 선언 | 클래스 내부에서 사용하고 private이 아니면 참조 변수로 다른 클래스에서 사용 가능 | 힙 | 인스턴스가 생성될 떄 힙에서 생성되고, 가비지 컬렉터가 메모리를 수거할 때 소멸됨 |
| static변수(클래스 변수) | static예약어를 사용하여 클래스 내부에 선언 | 클래스 내부에서 사용하고 private이 아니면 클래스 이름으로 다른 클래스에서 사용 가능 | 데이터 영역 | 프로그램이 처음 시작할 때 상수와 함께 데이터 영역에 생성되고 프로그램이 끝나고 메모리를 해제할 때 소멸됨 |
static 응용-singleton 패턴
전 시스템에 단 하나의 인스턴스만이 존재하도록 구현하는 방식
package singleton;
public class Company {
private static Company instance = new Company();
private Company() {} //디폴트 생성자, private-외부 호출 금지
public static Company getInstance() {
if(instance == null)
instance = new Company();
return instance;
}
}
package singleton;
public class CompantTest {
public static void main(String[] args) {
Company c1 = Company.getInstance();
Company c2 = Company.getInstance();
System.out.println(c1); //5ca881b5
System.out.println(c2); //5ca881b5
}
}'공부기록 > 사전학습' 카테고리의 다른 글
| Java 사전학습_5 (0) | 2022.11.19 |
|---|---|
| Java 사전학습_4 (1) | 2022.11.02 |
| Java 사전학습_2 (1) | 2022.10.28 |
| Java 사전학습_1 (1) | 2022.10.25 |
| Oracle (1) | 2022.10.22 |
댓글