나 java봐랏 4일차

김혜성·2021년 7월 4일
0

나 java봐랏

목록 보기
4/7

갔을 줄 알았지? 다시 제개.....

클래스와 객체

객체지향

객체지향 프로그래밍 - OOP(Object Oriented Programming) ex. Java
vs
절차지향 프로그래밍 - PP(Procedural Programming) ex. C언어

  • 객체 정의, 객체 기능 구현, 객체 사이의 협력 구현

클래스

: 객체에 대한 속성과 기능을 코드로 구현한 것

  • 객체의 속성 - 멤버 변수로(= property, attribute)
  • 객체의 기능 - method(메서드), member function으로

(접근 제어자)class 클래스 이름{멤버 변수; 메서드;}

  • 대부분 하나의 java 파일에는 하나의 클래스(여럿일수도)
  • public 클래스는 단 하나!!!
  • public 클래스명 == java 파일명
  • java의 모든 코드는 class 내부에 위치
    밖에는 패키지 정의나 import 정도만
  • 패키지: 소스 코드 관리, 유지 보수 위함. 프로젝트 전체 소스코드를 구성하는 계층 구조

이부분은 메인없이 클래스만 있는 코드

package classpart;

public class Student {

	
		int studentID;
		String studentName;//string은 클래스다!
		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();
	}
	*/ //이렇게 class 안에서 메인 쓸 수도 있다 but 다른 클래스에서 쓰는게 일반적

}

이부분이 위의 코드에 대한 메인함수

package classpart;

public class Students {//실제로는 package name. class여서 classpart.Students이다

	public static void main(String[] args) {//메인만 뺸 코드
		Student studentLee = new Student();
		studentLee.studentName = "이순신";
		studentLee.address = "경기도 성남시 분당구 수내동";
		
		studentLee.showStudentInfo();
	}

}

메서드

: 함수의 일종, 객체의 기능 제공 위해 클래스 내부에 구현되는 함수

  • 함수 정의는 c나 파이썬이랑 같으니까...

함수 만드는 간단한 코드에용!

package classpart;

public class Function {
	public static void main(String[] args) {
		int num1 = 10;
		int num2 = 30;
		
		int result = addNum(num1, num2);
		
		System.out.println(result);
	}
	
	public static int addNum(int a, int b) {
		int sum = a+b;
		return sum;
	}
}

함수가 사용하는 메모리: stack

요런식으로 스택 메모리가 작동된다고...합니다...

위의 class 코드에서 학생이름 반환 함수, 학생이름 변경 함수 추가한 코드, 바로 보시죠!!

package classpart;

public class Student {

	
		int studentID;
		String studentName;//string은 클래스다!
		int grade;
		String address;
		
		public void showStudentInfo() {
			System.out.println(studentName+","+address);
		}
		
		public String getStudentName() {//student name반환 함수
			return studentName;
		}
		
		public void setStudentName(String name) {//student name 변경 함수
			studentName = name;
		}
	/*
	public static void main(String[] args) {
		Student studentLee = new Student();
		studentLee.studentName = "이순신";
		studentLee.address = "경기도 성남시 분당구 수내동";
		
		studentLee.showStudentInfo();
	}
	*/ //이렇게 class 안에서 메인 쓸 수도 있다 but 다른 클래스에서 쓰는게 일반적

}

클래스와 인스턴스


클래스 생성하기

  • 클래스형 변수이름 = new 생성자;
    ex) Student studentA = new Student();
  • 인스턴스는 힙(Heap) 메모리(동적할당)에 생성됨
    (지역변수는 스택메모리에서 생성)

인스턴스 여러개를 생성하여 위의 클래스 코드 업데이트!

package classpart;

public class Student {

	
		int studentID;
		String studentName;//string은 클래스다!
		int grade;
		String address;
		
		public void showStudentInfo() {
			System.out.println(studentName+","+address);
		}
		
		public String getStudentName() {//student name반환 함수
			return studentName;
		}
		
		public void setStudentName(String name) {//student name 변경 함수
			studentName = name;
		}
		
		
	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);
		System.out.println(studentKim);
		//classpart.Student@723279cf 끝의 수는 32비트 address
		//classpart.Student@10f87f48
	}
	 //이렇게 class 안에서 메인 쓸 수도 있다 but 다른 클래스에서 쓰는게 일반적

}

위에서 studentKim, studentLee 각각의 name, id, address등이 인스턴스이고 힙메모리에서 생성됨
이후에 Garbage Collector를 통해 힙메모리가 해제된다

studentLee: 참조변수
classpart.Student@723279cf: 참조값

정리된거!

생성자

: new 다음에 오는거

public Student() {}가 default로 추가된다 - 매개변수 읎어
(생성자 하나도 없을 때에만 추가된다)

생성자 추가했을 때
1. default생성자 임의로 넣는다
2. 생성자에 추가했던 인스턴스의 값을 직접넣는다

package classpart;

public class Student {

	
		int studentID;
		String studentName;//string은 클래스다!
		int grade;
		String address;
		
		//default 생성자
		//public Student() {}
		//생성자
		public Student(int id, String name) {
			studentID = id;
			studentName = name;
		}
		
		public void showStudentInfo() {
			System.out.println(studentName+","+address);
		}
		
		public String getStudentName() {//student name반환 함수
			return studentName;
		}
		
		public void setStudentName(String name) {//student name 변경 함수
			studentName = name;
		}
		
		
	public static void main(String[] args) {
		Student studentLee = new Student(100, "이순신");//힙메모리에 생성
		
		studentLee.address = "미국 샌디에고";
		
		Student studentKim = new Student();//힙메모리에 생성
		studentKim.studentName = "김만중";
		studentKim.studentID = 101;
		studentKim.address = "경기도 성남시 분당구 판교동";
		
		studentLee.showStudentInfo();
		studentKim.showStudentInfo();
		
		 
		
	}
	 //이렇게 class 안에서 메인 쓸 수도 있다 but 다른 클래스에서 쓰는게 일반적

}

생성자가 있으면 디폴트생성자 제공 안된다

  • 생성자 오버로드: 생성자가 하나의 클래스에 여럿 있을 수도 있다

참조 자료형(reference data type)

  • 변수의 자료형: 기본 자료형
  • 클래스 형으로 선언하는 자료형: 참조 자료형

    이처럼 너무 많이 담길 경우 학생과 과목으로 분류해줌

점에 대한 코드를

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;
	int koreanScore;
	int mathScore;
	String koreanSubject;
	String mathSubject;
	
	int engScore;
	String engSubject; */
	// 점수와 과목으로 나누면 더 깔끔해질것
	int studentID;
	String studentName;
	Subject korean;
	Subject math;
	
	public Student() {
		korean = new Subject();
		math = new Subject();
	}
	
	public Student(int id, String name) {
		studentID = id;
		studentName = name;
		
		korean = new Subject();
		math = new Subject();
	}
	
	public void setKorean(String name, int score) {
		korean.setSubjectName(name);
		korean.setScore(score);
	}
	
	public void setMath(String name, int score) {
		math.setSubjectName(name);
		math.setScore(score);
	}
	
	public void showStudentInfo() {
		int total = korean.getScore() + math.getScore();
		System.out.println(studentName+"학생의 총점은 "+total+"점 입니다.");
	}
}

이부분과

package reference;

public class StudentTest {

	public static void main(String[] args) {
		Student studentKim = new Student(100, "김만중");
		studentKim.setKorean("국어", 100);
		studentKim.setMath("수학", 100);
		
		Student studentLee = new Student(100, "이지은");
		studentLee.setKorean("국어", 40);
		studentLee.setMath("수학", 96);
		
		studentKim.showStudentInfo();
		studentLee.showStudentInfo();
		
	}

}

요부분과

package reference;

public class Subject {
	String subjectName;
	int score;
	
	public void setSubjectName(String name) {
		subjectName = name;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;//this 무엇??
	}

	public String getSubjectName() {
		return subjectName;
	}
}

요부분은 정신이 혼미해서 다시 봐야겠다...

정보은닉(information hiding)

  • private 접근 제어자: 클래스의 외부에서 내부의 멤버 변수나 메서드에 엑세스 못하게 함 -> 오류 줄임
  • public: 외부 클래스에서 다 가져다 쓸 수 있다
  • 아무것도 X: default: 같은 패키지 내에서는 쓸 수 있다
  • 상속관계에서만 public처럼 가능(나머지에선 private)
package hiding;

class BirthDay {
	private int day;	//public이었을 때는 괜찮은데
	private int month;	//private쓰니까 클래스 안에서만 작동해서 오류발생
	private int year;
	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 == 2) {
			if(day <1 || day > 28) {
				System.out.println("날짜 오류입니다");
			}
			
		}
		else {
			this.month = month;
		}
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
}

public class BirthDayTest{//java파일이랑 이름 같아야 함
	public static void main(String args) {
		BirthDay day = new BirthDay();
		
		day.setMonth(2);
		day.setDay(30);
		day.setYear(2018);
	}
}

클래스와 객체는 담에 할 줄 알았는데....
정신이 혼미해서 코드를 꼼꼼히 살피지 못했다...
다시 코드 찬찬히 보고 공부할 시간이...필...요...

"insane"

+

저번에 의식이 반만 멀쩡하게 글을 써서 대충 넘어간 부분을 좀 더 보충하자면...

이런식으로
Student studentLee = new Stundet()
클래스를 선언하게 되면 studentLee는 지역변수로 스택 메모리에 저장이 된다. 그리고 이 때 이 studentLee라는 지역변수가 heap메모리에 생성된 인스턴스를 가르키는 것이다!
여러개의 인스턴스가 생기면 각각 메모리공간을 따로 차지한다(그림처럼 각각 다른 주소의 힙메모리를 가르킨다)

Constructor

constructor(생성자)에 대해서도 추가로 얘기하자면,
constructor를 따로 명시하지 않으면 자동으로
public Student() {};
가 생성된다. 매개변수를 필수적으로 전달받아서 클래스를 선언하고 싶다면 그 때

public Student(int id, String name) {
	studentID = id;
    studentName = name;
    }

이처럼 써주어서 인수를 받을 수 있다(이 때는 인수를 받지 않으면 오류 발생!!)

Reference

출처를 밝히겠다는게 아니고 reference가 참조 자료형이다...

profile
똘멩이

0개의 댓글