재밌고 어려운 IT를 이해해보자~!
클래스(Class), 메서드(Method), 생성자(Constructor) 본문
Q. 학생 1명의 이름,나이,점수 어떻게 저장할까?
-> 배열, 원시타입으로는 한번에 다른 자료형들을 저장할 수 없다.
A. "학생"이라는 자료형이 필요한 순간!!!!!
객체지향의 시작 클래스~!
클래스(Class)란 ? ★★★★
JAVA의 기본단위이며 자료형의 일종이다.
ex) 이름, 나이, 번호를 가지고있는 학생 클래스!
JAVA에서 이미 수많은 클래스들을 미리 만들어놨고 사용한 적이 있다. ex) Random, Scanner, ...
이미있는것 외에도 개발자(우리)가 새로 정의할수 있음!
클래스명 선언은 대문자로 시작하는것이 규칙이다. 따라서 함수(메서드),변수명 드은 대문자 X
원시타입들은 new 연산자 사용 X
배열, 클래스 객체(우리가 만든 자료형)들은
"개발자 영역(heap 메모리 영역)"을 사용해야하기 때문에 new 사용(O)
Student 클래스 선언
// Class 선언(정의)하는 방법
// "학생"이라는 자료형 정의(선언)완료
// "학생"이라는 자료형은
// 이름,나이,점수를 가지고있음
// class안의 정의된 것들을 멤버변수라고 부른다!!!!!!
// 다른말로는 ... 필드, 속성. attribute, property !!
// static == 객체와 무관하게 라는뜻!!!!!!!!!!!!다시외우자
// 클래스(객체)에 포함되는 함수(메서드)들에게는 static이 붙지않음!
class Student{
String name;
int age;
int score;
void printInfo() {// ->객체와 관련이 있기 떄문에 static이 붙지않는다.
System.out.println();
System.out.println("Student클래스 안의 메서드 printInfo()에서 출력함");
System.out.println(name);
System.out.println(age);
System.out.println(score);//scope가 맞아 떨어진다. 사용가능!
}
}
내가 만든 Student 클래스!
Student 라는 자료형을 새롭게 정의(선언).
Student 라는 자료형은 name, age, score를 가지고있다.
class 안에 선언된 변수들을 맴버변수 라고 부른다. or 다른말로는 필드, 속성. attribute, property -> 업무에 따라 다름.
메서드
class 안에 선언된 함수를 메서드 라고 부른다.
앞으로 함수 != 메서드 인것을 구분하자.
static의 의미는 "객체와 무관하게" 라는 뜻
class에 포함되는 메서드들에게는 static이 붙지 않는다. -> 객체와 관련있음.
Student클래스를 만들었으면 main문에서 Student 클래스를 사용해 객체를 만들어서 사용해야한다.
public static void main(String[] args) {
Student stu=new Student(); // stu를 바로 객체라고 부른다!!!★★★★★
//상위코드의 뜻은 개발자가 만든 자료형 Student 클래스 타입의 변수 stu 객체를
//new 연산자를 사용해서 heap 메모리 영엯에 생성하겠습니다!!!!!
//Scanner sc = new Scanner(); // sc 는 ! Scanner 클래스 타입의 변수 sc 객체 선언 or 생성
stu.name = "멍멍이"; // .(점 연산자) -> 멤버접근연산자 or 멤버변수접근연산자
stu.age= 20;
stu.score=100;
System.out.println(stu.name);
System.out.println(stu);//-> 객체를 담고있는 클래스의 주소가나온다!! 배열처럼 heap 메모리 주소
//class02.Student@ ~~~~~~ 클래스주소!
stu.printInfo();
Student teemo=new Student();
teemo.name="티모";
teemo.age=16;
teemo.score=71;
teemo.printInfo();
//매우완전중요☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
//어떻게 둘다 메서드시그니쳐가 같은 printInfo인데 다른 출력을 할까?
// 객체지향언어를 사용하면
// "누가 함수(메서드)를 호출했느냐"에 따라 결과가 달라집니다!!!!!
//-->함수(메서드)에게 주어(주체)가 생기는 언어
//멤버함수 -> 메서드라고부른다!! 아무도 멤버함수라고 부르지않음
//일반적인 함수는 주어(주체)가 없고
//메서드(멤버함수)는 주어(주체)가 있다.
//★ 함수!= 메서드 ★
// 같은 메서드인데 다른 결과가 나오는 현상
// == 다형성
// == 다형성이 실현(구현)되었다.
}
}
매우매우 중요한 개념이 마구나온다.
Student stu = new Studnet();
stu 가 바로 "객체(Instacne)"이며 상위코드의 뜻은 개발자가 만든 자료형 Student 클래스 타입의 변수 stu 객체를 new 연산자를 사용해서 heap 메모리 영역에 생성한다.
System.out.println(stu); -> 객체를 담고있는 클래스의 주소가나온다!! 배열처럼 heap 메모리 주소
class02.Student@~~~~~ 패키지.클래스주소가 나온다.
(점 연산자) 를통해서 클래스의 멤버변수에 접근할 수 있으며, 점 연산자를 멤버접근연산자 or 멤버변수접근연산자 라고 부른다.
객체는 몇개든지 만들어낼 수 있다.
Student stu = new Studnet();
Student stu2 = new Studnet();
일반적인 함수는 주어(주체)가 없고
메서드(멤버함수)는 주어(주체)가 있다.
이 주어와 멤버접근연산자를 통해서 멤버에 접근해 데이터를 다룰 수 있다.
stu.age = 20;
같은 메서드인데 다른 결과가 나오는 현상 (내부일떄)
다형성이 실현(구현)되었다.
매우중요! ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★
특이한점은 메서드 시그니쳐가 같은 상황에서 둘 다 printInfo() 를 사용했는데도
객체지향언어를 사용하기 때문에 누가 함수(메서드)를 호출했느냐에 따라 결과가 달라진다.
함수(메서드)에게 주어(주체)가 생기는 언어.
stu.name = "강아지";
stu2.name = "고슴도치";
stu.printInfo() ;
stu2.printInfo() ;
stu 와 stu2가 주어가 되고 주어를 사용해서 접근하기에 printInfo()가 두개인데도 사용이 가능한 것이다.
주어(생기면)를 사용해서 접근하기 때문에 같은 메서드를 사용해도 다른 결과를 얻을 수 있다.
과제
package class05;
import java.util.Scanner;
class Person {
String name;
int age;
void hello() {
System.out.println(name+"씨는 "+age+"살 입니다.");
}
int inputAge(Scanner sc) {
System.out.println("나이 입력: ");
while (true) {
age = sc.nextInt();
if(age<1 || age>100) {
System.out.println("범위를 벗어났습니다 재입력하세요");
}
else {
return age;
}
}
}
String inputName(Scanner sc) {
System.out.println("이름 입력 :");
while(true) {
name = sc.next();
System.out.println("정말 이 이름으로 하시겠습니까?");
String ans = sc.next();
if (ans.equals("네")) {
return name;
}
System.out.println("이름을 다시 입력하세요");
continue;
}
}
Person() {
name ="입력없음";
age = -1;
}
Person(String n) {
name =n;
age = 20;
}
Person(String n, int s) {
name = n;
age = s;
}
}
public class Test01 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Person p1 = new Person("너굴너굴");
Person p2 = new Person("멍멍");
Person[] pArr = new Person[5];
for (int i=0; i<pArr.length; i++ ) {
System.out.println((i+1)+"번째의 이름과 나이를 입력하세요");
pArr[i] = new Person();
pArr[i].inputName(sc);
pArr[i].inputAge(sc);
}
int i=0;
for (Person p : pArr) {
System.out.println("Person형 배열 pArr의 "+(i++)+"번 index값 :");
p.hello();
}
}
}
생성자
생성자를 알아보기 전에 heap 메모리 영역의 특징을 보자.
0, null 로 자동초기화 해준다. 개발자가 귀찮아할거라고 생각함.
String[] datas=new String[3];
int[] datas2=new int[3];
다음처럼 heap 메모리 영역애 공간이 생성되는 것들은 자동초기화를 해준다!
datas[0]을 출력하면 null이나오고 (아무것도 없다는 것은 null도없고 0도없는 정말 빈공간상태)
datas2[0]을 출력하면 1이나온다.
즉, 개발자 메모리 영역(heap 메모리 영역)에 변수를 생성하면 자동 초기화 해준다!!!
원시타입인 변수들은 초기화하지않으면 값이 아무것도없다 Null X 0 X 둘다아님 진짜 빈공간 이다.
-> 에러발생 아무것도 실행못함.
누군가 "아 ....멤버변수 초기화를 강제해줬으면 좋겠다..." 라는 생각을 하였고, 멤버변수에 아무것도 입력하지 않아도
자동 초기화 해주는 것을 바로 기본 생성자 라고한다.
Student stu1=new Student(); 이 코드의 의미는 다음과 같다.
Student = 개발자자료형 클래스
stu1 = 클래스에서나오는 변수 객체
new = new 연산자
Student() = 함수
Student() 함수는 뭘 하는 함수일까?
클래스와 이름이 똑같은 함수가 있다 new 연산자 뒤에서 호출됨.
멤버변수 초기화하는 역할 이것을 바로 "생성자" 라고 부른다!!!
함수를 호출해서 사용하려면 선언해야함!
원래 생성자 없이는 객체를 생성할 수 없다.
하지만 class Student { }
에 아무런 생성자를 선언하지 않았는데도 우리는 Student stu1=new Student(); 코드를 작성하였고, Student() 생성자를
호출했는데도 아무런 에러가 나지 않았다.
그이유는 바로 JAVA는 인자가없는 생성자를 기본으로 제공하기 때문이고 그것을 기본생성자(디폴트 생성자) 라고한다.
주의사항!
메게변수를 받는 생성자를 선언하면 기본생성자는 자바가 더이상 제공해주지 않는다.
다음 코드를 보자.
class Student {
String name;
int score;
Student() {
}
Student(String n) {
name=n;
score=0;
System.out.println("하나 더 만든 생성자");
}
Student(String n, int s) {
name=n;
score=s;
System.out.println("생성자로 멤머변수 초기화 강제");
}
Student 클래스 메게변수로 이름을 입력받는생성자, 메게변수로 이름과 나이를 입력받는 생성자가 있다.
그럼 우리는 과연 Student stu1=new Student(); 코드를 작성할 수 있을까? 정답은 false 다.
메게변수를 받는 생성자를 선언한 순간 기본생성자는 사라진다.
따라서 우리는 다음처럼 코드를 작성해야한다.
Student stu1=new Student("티모");
or
Student stu1=new Student("티모", 5);
두개 모두 가능한 이유는 선언한 생성자 2개가 오버로딩 되어있기 때문에 받는 메게변수를 생성자가 판단해서
멤버변수에 대입을 한다.
그렇다면 아무것도 입력을 안했을때 defualt값을 주거나 error가 나지 않게 하려면 어떻게 해야할까?
바로 기본생성자를 직접 선언하면 된다.
다음처럼 선언을 해주면 기본생성자를 이용해 객체를 선언할때 에러가 나지 않는다.
입력을 안했을때 초기값을 주려면 기본 생성자 안에다가 멤버변수 초기화를 시켜주면 된다.
Student() {
name = "오소리";
age = 27;
}
초기화 완료!
이제 어떤 형식을 생성자를 불러오든 내가 선언한 생성자와 메게변수가 일치하다면 에러가 나지 않는다!
★ 강제성
~~~ 기능 덕분에 ~~를 "강제" 할수있다.
좋은 것 이며 많이 쓰는 것이다.
자유도가 높으면 사람이 많아질수록 결과물이 제각각이다.
프로그래밍 언어에는 하면안되거나 반드시해야하는 것들은 "강제"하는 기능이 많이 있다.
그럼 규칙을 따라서 같은 프로그램을 구현할때 강제성을 띄우는 것들로 인해서 틀을 벗어나지 않는다.
다음 문제를 풀어보자.
문제 1 .(해당 문제는 Scanner를 사용하지않습니다.)
사람 클래스가 있습니다.
사람은 반드시 이름(문자열)이 있습니다.
나이를 별도로 알려주지않는 경우 자동으로 20살 설정됩니다.
사람 객체를 2명 생성해주세요.
사람객체명.hello(); 하면
"ㅇㅇ은 ㅇ살입니다."라고 출력됩니다.
문제 2.
나이를 별도로 입력할때에 1~100살까지만 입력할수있습니다.
이외 범위를 입력하는 경우 재입력할수있게 '메서드'를 정의해보세요.
HINT) int inputAge()
문제 3.
사용자에게 이름도 입력받아보세요! ㅎㅎ
문제 4.
사용자가 이름을 입력했을때, "정말 이 이름으로 하시겠습니까?"라고 질문하고,
"네"라고 하면 해당 이름을 사용해주세요.
"네" 이외의 입력시 재입력하게해주세요.
문제 4-2.
문제 4의 기능을 모듈화 해보세요.
HINT) String inputName()
문제 5.
사람들이 5명 저장되어있는 배열을 만들어보세요.
package class05;
import java.util.Scanner;
class Person {
String name;
int age;
void hello() {
System.out.println(name + "은" + age + "살 입니다.");
}
int inputAge(Scanner sc) {
System.out.println("나이를 직접 입력하세요");
while (true) {
age = sc.nextInt();
if (age < 1 || age > 100) {
System.out.println("범위를 벗어났습니다 재입력하세요");
} else {
return age;
}
}
}
String inputName(Scanner sc) {
System.out.println("이름을 직접 입력하세요");
while (true) {
name = sc.next();
System.out.println("정말 이 이름으로 하시겠습니까?");
String ans = sc.next();
if (ans.equals("네")) {
return name;
}
System.out.println("이름을 다시 입력하세요");
continue;
}
}
Person() {
name = "입력없음";
age = -1;
}
Person(String n) {
name = n;
age = 20;
}
Person(String n, int s) {
name = n;
age = s;
}
void printInfo() {
System.out.println("이름: " + name + ", 나이: " + age);
}
}
public class Test01 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Person p1 = new Person("너구리");
Person p2 = new Person("개구리");
Person[] pArr = new Person[5
];
for (int i = 0; i < pArr.length; i++) {
System.out.println((i + 1) + "번째의 이름과 나이를 입력하세요");
pArr[i] = new Person();
pArr[i].inputName(sc);
pArr[i].inputAge(sc);
}
for (Person p : pArr) {
System.out.println("이름: " + p.name + ", 나이: " + p.age);
}
}
}
'코리아IT핀테크과정' 카테고리의 다른 글
상속(Inheritance) (2) | 2023.12.01 |
---|---|
this 예약어, 로그출력, 클래스와 배열의 활용 (0) | 2023.12.01 |
선택정렬 코드 실행 (0) | 2023.11.29 |
함수를 활용한 학생부 프로그램 리팩토링(Refactoring) (2) | 2023.11.28 |
삽입정렬 코드 실행 (0) | 2023.11.28 |