[JAVA+국비교육] 상속, Object 클래스, 생성자, Override, super(), 클래스를 활용해서 계산기 만들기
by 무작정 개발2022.01.03(월요일)
벌써 국비교육을 시작한 지 3주 차가 되었다. 파이팅
이번에는 Java의 생성자, super(), 상속 Override 등에 대해 배우게 되었다.
오늘의 수업 내용
생성자
객체 생성 시 호출되어 멤버 변수를 초기화하는 역할을 수행한다. 생성자 내부에서 특정 작업을 수행할 수 있고 데이터를 인자에 전달하여 전달받은 데이터를 활용할 수도 있다.
생성자 안에 있는 super()
모든 생성자에는 super()가 생략되어 있다.
super는 this와 함께 객체를 참조할 수 있는 reference 변수이다.
A class - B class - C class (부모 - 자식) 관계일 때 전혀 상관이 없는 별도의 D class에서 C class의 객체를 생성할 때
개본 생성자 안에 있는 super를 통해 부모 클래스의 메모리를 먼저 할당받은 뒤 마지막에 자식 클래스 생성.
Object (오브젝트)
Object는 java에서 가장 큰 자료형이다. 또한 java에서 모든 클래스 + 내가 만든 클래스의 부모(조상)는 Object이다.
Override
상속관계에서 같은 역할을 하는 메서드의 이름을 통일시키는 작업이다. 부모의 클래스를 재정의(다형성)해서 사용.
메서드는 하늘이 두쪽 나도 무조건 자신 것을 사용해야 함.
조건 : 메서드의 이름이 부모 메서드와 정확히 같아야 함.
Override(오버 라이드)된 생성자
Override(오버라이드, 재정의, 다형성) : 저장공간이 다르기 때문에 메서드 이름이 동일해도 가능
상속관계에서 부모의 메서드와 똑같이 만들고 내용(메서드명, 매개변수 등)만 다르게 만든다.
javapackage com.day9; //부모 class Test { // 기본생성자로 객체 만들어보고 오버로딩된 생서자로도 객체 만들어보기 private String title; protected double area; //기본 생성자 public Test() {} //기본 생성자 꺼내놓음 why? 오버로딩된 생성자 만들려고 //오버로딩된 생성자 public Test(String title) { this.title = title; } public void write() { System.out.println(title + ":" + area); } } //자식 class Circle extends Test { private int r; protected static final double PI = 3.14;// static 알아서 메모리에 올라감 //오버로딩된 생성자 public Circle(int r) {//new Circle(10)때문에 r에 10이 들어가고 super("원"); //원이 위에 title로 들어감 this.r = r; } public void circleArea() { area = (double)r * r * PI; //구분하기 편하게 double써도된다. 지워도 오류 안뜸. } } class Rect extends Test { private int w, h; public void rectArea(int w, int h) {//메소드로 초기화 / 여긴 메소드 Rect의 메소드이다 this.w = w; this.h = h; area = w * h; } //Override //상속관계에서 같은 역할을 하는 메소드의 이름을 통일시키는 작업 //부모의 클래스를 재정의(다형성)해서 사용 //조건 : 메소드의 이름이 부모 메소드와 정확히 같아야 한다. //메소드는 하늘이 두쪽나도 무조건 자신 것을 사용함 //부모의 내용이 맘에 안들어서 자식이 마음대로 내용을 변형! @Override //어노테이션 public void write() { System.out.println("가로 : " + w + " 세로 : " + h); System.out.println("넓이 : " + area); //super.write(); } } public class Test1 { public static void main(String[] args) { Circle ob1 = new Circle(10); ob1.circleArea(); ob1.write();//부모의 메소드를 사용한다 Rect ob2 = new Rect(); //기본 생성자 생성 ob2.rectArea(10, 20); //매개변수 값 필요 ob2.write(); //5. 부모도 가지고있고, 나도 갖고 있으면 내껄 쓴다.무조건!!! } }

Object의 메서드
javapackage com.day9; //java에서 모든 클래스(class) + 내가만든 클래스의 부모(조상)는 오브젝트다(Object) // Object는 가장 큰 자료형. 오브젝트 메소드에서 equals랑 toString 메소드 기억하기 class TestA { //내가 만든 클래스라 부모가 없어보일 수 있지만 기본적으로 조상은 Object이다. // class TestA extends Object { 이렇게 써도 오류 안뜸 private int a = 10; public void write() { System.out.println("a" + a); } } public class Test2 { public static void main(String[] args) { TestA ob1 = new TestA(); TestA ob2 = new TestA(); System.out.println("ob1 == ob2:" + (ob1 == ob2)); //false가 나옴 //why? 똑같은 클래스로 객체를 생성했지만 ob1에 들어있는 주소와 ob2에 들어있는 주소가 다르기 때문. System.out.println("ob.equals(ob2):" + ob1.equals(ob2)); // false가 나옴 //equals는 Object의 메소드인데 TestA의 부모는 Object라서 사용가능 System.out.println("ob1 : " + ob1);//주소//ob1 : com.day9.TestA@7852e922 -> @뒤에 숫자는 해쉬코드(hashcode) System.out.println("ob2 : " + ob2);//주소//ob2 : com.day9.TestA@4e25154f -> @뒤에 숫자는 해쉬코드(hashcode) System.out.println("ob1.toString(): " + ob1.toString());//주소//ob1.toString(): com.day9.TestA@7852e922 //toString메소드 : 안에 들어있는 것이 자료형이 무엇이든 (string형태)문자로 출력한다 //TestA의 부모가 Objectㅇ서 toString을 사용 가능한거다. } }

String 클래스
String은 Class(클래스)이다.(자료형이 아니다.)
String을 자료형처럼 사용하는 이유는 저장할 데이터는 방대하고 사용 빈도는 높기 때문이다.
stack 영역에 저장할 수 없고 heap 영역에 저장해야 한다.
String 데이터는 equalse로 비교해야 정확한 값이 나온다.
String은 불변의 법칙(메모리에 값이 저장되면 수정 or삭제 못함) 새로운 곳에 만듦.
javapackage com.day9; //String //String은 Class(클래스)이다. (자료형이 아님) //String클래스를 자료형처럼 사용하는 이유는 저장할 데이터는 방대하고 사용 빈도는 높기 때문이다. //String 데이터는 equalse로 비교해야 정확한 값이 나옴 //String은 불변의 법칙(메모리에 값이 저장되면 수정or삭제 못함) 새로운 곳에 만듬 public class Test3 { public static void main(String[] args) { String ob1 = "Seoul"; // 자료형처럼 생성 String ob2 = "Seoul"; String ob3 = new String ("Seoul"); //클래스 생성 정석 System.out.println("ob1 == ob2 : " + (ob1 == ob2)); //true | why? String은 문자가 100%같으면 새로 만들지 않고, 주소를 공유한다. System.out.println("ob1 == ob3 : " + (ob1 == ob3)); //false | new가 들어가는 순간 무조건 만들어야함. // 내용이 같더라도 주소가 달라서 false System.out.println("ob1.equals(ob3) : " + ob1.equals(ob3)); //true ob2 = "korea"; System.out.println("ob1 == ob2 : " + (ob1 == ob2)); // false ob2 = "use"; System.out.println("ob1 == ob2 : " + (ob1 == ob2)); // false ob2 = "Seoul"; System.out.println("ob1 == ob2 : " + (ob1 == ob2)); // true System.out.println(ob2); // hashcode ( x) //String 클래스는 자료형 흉내를 최대한 내기 위해 hascode 주소값이 안나오고 주소로 찾아가 있는 데이터를 출력해줌 System.out.println(ob2.toString()); // Seoul } }

String을 도와주는 2개의 클래스
StringBuffer클래스 / StringBuilder클래스
StringBuffer - 동기화 지원 O (builder보다 느림)
StringBuilder - 동기화 지원 X (지원하지 않아 빠름)
출력 속도 : String < StringBuffer < StringBuilder
javapackage com.day9; // StringBuffer클래스 // StringBuilder클래스 public class Test4 { public void stringTime() { System.out.println("String Test...."); // long start = System.currentTimeMillis(); long start = System.nanoTime(); String str = "A"; for (int i = 1; i < 50000; i++) { str += "A"; } long end = System.nanoTime(); System.out.println("실행시간 : " + (end - start)); } public void stringBufferTime() { System.out.println("StringBuffer Test...."); long start = System.nanoTime(); StringBuffer str = new StringBuffer("A"); for (int i = 1; i < 50000; i++) { str.append("A"); //문자 누적 } long end = System.nanoTime(); System.out.println("실행시간 : " + (end - start)); } public void stringBuilderTime() { System.out.println("StringBuilder Test...."); long start = System.nanoTime(); StringBuilder str = new StringBuilder("A"); for (int i = 1; i < 50000; i++) { str.append("A"); //문자 누적 } long end = System.nanoTime(); System.out.println("실행시간 : " + (end - start)); } public static void main(String[] args) { Test4 ob = new Test4(); ob.stringTime(); ob.stringBufferTime(); ob.stringBuilderTime(); } }

javapackage com.day9; public class Test5 { public static void main(String[] args) { StringBuffer sb = new StringBuffer(); sb.append("서울"); sb.append("부산"); System.out.println(sb); String str = sb.toString(); System.out.println(str); } }
String 클래스의 다양한 메서드
split()
- 기준을 정해 나열한다. ex) split(", "); -> " , "를 기준으로 나열
equals()
- 두 값이 동일한지 비교해 준다. 그래서 반환 값은 boolean형이다.
- 대소문자를 비교한다.
equalsIgnorerCase()
- 대소문자 구분 없이 문자열 제차만으로 비교해 준다. 반환 값은 boolean형
indexOf()
- 특정 문자나 문자열이 앞에서부터 처음 발견되는 인덱스를 반환하며 만약 찾지 못할 경우 -1을 반환함.
replaceAll()
- replaceAll("대한", "大韓"); -> 대한을 大韓로 바꿔준다.
trim()
- 양쪽 공백을 지워준다.
charAt()
- 인덱스의 문자 값을 불러온다. ex) charAt(3) : 3번째 인덱스의 문자 값을 불러온다.
javapackage com.day9; //String 클래스의 메소드들 배우기! // 여기 적힌 메소드들은 알고 있어야한다.(자주사용) public class Test6 { public static void main(String[] args) { //split은 String클래스의 메소드 String s1 = "서울,부산,대구"; String [] ss = s1.split(","); for(String s : ss) System.out.print(s + " "); System.out.println(); String s2 = "seoul"; String s3 = "Seoul"; System.out.println(s2.equals(s3)); //false System.out.println(s2.equalsIgnoreCase(s3)); //true String s4 = "abc.def.hij"; // 01234567890 < - index 번호 부여 System.out.println(s4.indexOf(".")); // 3 System.out.println(s4.lastIndexOf("."));// 7 System.out.println(s4.indexOf("def")); // 4 System.out.println(s4.indexOf("x"));// -1 String s5 = "우리나라 대한민국 좋은나라 대한민국"; String s6 = s5.replaceAll("대한", "大韓"); System.out.println(s6); String s7 = " a b c "; System.out.println(s7); System.out.println(s7.trim()); //trim 메소드는 양쪽의 공백을 없애준다. System.out.println(s7.replaceAll(" ", "")); // ex)공백이 있는걸 공백이 없는 것으로 만들자. System.out.println(s7.replaceAll("\\s", "")); char ch = "abcdefg".charAt(2); System.out.println(ch); // c System.out.println("abcdefg".length()); // 7 String s8 = "abcdefg"; String s9 = "abceefg"; //아스키값으로 비교하는 방법 System.out.println(s8.compareTo(s9)); // -1 System.out.println(s9.compareTo(s8)); // 1 } }
String 메서드를 이용해서 계산기 만들기
javapackage com.day9; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; //계산기 만들기 : 오로지 String의 메소드만 사용하기 public class Test7 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("수식[3+5] : "); String str = br.readLine(); str = str.replaceAll("\\s", ""); // 공백제거 //System.out.println(str); //String [] oper = {"+", "-", "*", "/"}; //for(String op : oper) { for(String op : new String [] {"+", "-", "*", "/"}) { int pos = str.indexOf(op); // op가 있는 자리의 index 번호를 가져와라 if(pos>-1) { int num1 = Integer.parseInt(str.substring(0, pos)); int num2 = Integer.parseInt(str.substring(pos+1)); //System.out.println(num1 +":"+ num2); 중간체크 int result = 0; //결과값을 담을 변수 char oper = str.charAt(pos); switch(oper) { case '+' : result = num1 + num2; break; case '-' : result = num1 - num2; break; case '*' : result = num1 * num2; break; case '/' : result = num1 / num2; break; } //System.out.printf("%d %c %d = %d", num1, oper, num2, result); //모양을 만들어서 변수를 만들어놓고 리턴값을 받아 원하는 위치에 출력 String sf = String.format("%d %c %d = %d", num1, oper, num2, result); System.out.println(sf); } } } }
Q. 퀴즈풀이
1. 상단 코드는 유지하면서 클래스를 활용해서 계산기 만들기
javaclass Result { public void print(String r) { System.out.println(r); } } // -----------------------------------------상단 코드는 유지--- class Calc extends Result { } public class Test8 { public static void main(String[] args) { } }
답 1
javapackage com.day9; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; class Result { public void print(String r) { System.out.println(r); } } // ---------------------------------------------------위에 그대로 한 상태에서 만들기 class Calc extends Result { private int num1, num2, r; // 숫자1, 숫자2, 연산결과 private char oper; // 연산자(문자) //private String result, str; public void input() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("수식[3+5] : "); String str = br.readLine(); str = str.replaceAll("\\s", ""); // 공백제거 for(String op : new String [] {"+", "-", "*", "/"}) { int pos = str.indexOf(op); // op가 있는 자리의 index 번호를 가져와라 if(pos>-1) { int num1 = Integer.parseInt(str.substring(0, pos)); int num2 = Integer.parseInt(str.substring(pos+1)); } } } public String calc() { switch(oper) { case '+' : r = num1 + num2; break; case '-' : r = num1 - num2; break; case '*' : r = num1 * num2; break; case '/' : r = num1 / num2; break; } String result = String.format("%d %c %d = %d", num1, oper, num2, r); return result; } } public class Test8 { public static void main(String[] args) throws IOException { Calc ob = new Calc(); ob.input(); String r = ob.calc(); ob.print(r); } }
답 2
javapackage com.day9; import java.io.IOException; import java.util.Scanner; class Result1{ public void print(String r) { System.out.println(r); } } class Calc1 extends Result1{ int num1,num2; String num; char op; public void input() throws IOException { Scanner sc = new Scanner(System.in); System.out.println("µÎ°³ÀÇ ¼ö[?,?]"); num = sc.next(); String[] ss = num.split(","); num1 = Integer.parseInt(ss[0]); num2 = Integer.parseInt(ss[1]); System.out.println("¿¬»êÀÚ?"); op = (char)System.in.read(); } public String calc() { int result = 0; switch(op) { case '+' : result = num1 + num2; break; case '-' : result = num1 - num2; break; case '*' : result = num1 + num2; break; case '/' : result = num1 + num2; break; } String s = String.format("%d %c %d = %d",num1,op,num2,result); return s; } } public class Test8_1 { public static void main(String[] args) throws IOException { Calc1 ob = new Calc1(); ob.input(); String r = ob.calc(); ob.print(r); } }
오늘 퀴즈문제가 많이 헷갈렸다.. 아직 많이 부족하다는 게 느껴진다. 자바가 끝난 후에 DB를 배운다 들었는데
그때도 꾸준히 자바 복습을 해야겠다.
블로그의 정보
무작정 개발
무작정 개발