상속(기능을 확장 extends)을 한다는 것은 메소드의 기능을 상속한다는 뜻
this 현재 객체
super 상속을 했을 시 상위 클래스를 지칭하는 용어
<객체를 casting할 때 주의할 점>
참조변수의 하향캐스팅
(클래스) 참조변수 ==> 하향캐스팅
public static void init(Bread bread) {
if(bread instanceof Bread) {
bread.setName("단팥빵");
bread.setPrice(500);
}
if(bread instanceof Cake) {
Cake cake = (Cake)bread; //하향캐스팅
cake.setName("3단 케잌");
cake.setPrice(35000);
cake.setSize(150);
}
if(bread instanceof Roll) {
Roll roll = (Roll)bread;
roll.setName("초코롤빵");
roll.setPrice(27000);
roll.setLength(30);
}
}
instanceof
: 상속관계에 있는지 확인할 수 있는 연산자
: 참조변수 instanceof 클래스명 =? T/F
<클래스의 종류>
1) concreate class : 객체를 생성 가능한 클래스
2) abstract class
: 추상클래스, 객체생성불가능, 오로지 상속을 위해 만들어짐! (상속전문클래스)
: 현재 클래스에서는 구현할 수 없는 기능이 포함되어 있어 하위클래스에서 구현하도록 하기 위한 클래스
3) interface
: abstract클래스에서 멤버변수가 빠진 형태로 메소드만 존재, 멤버라는 개념이 아예 없다. 오로지 추상메소드만 가지고 있음!
: 메소드 꼭 구현하라고 강조할 수 있음 ==> implement를 사용한다.
<추상클래스>
public abstract class Car {
private String name;
private int liter;
private int gear;
private int price;
//구현하는 본체{}를 삭제하고 ;로 닫아버림
//현재 클래스에서 구현하지 않고, 자식클래스에서 구현하겠다는 키워드 abstract를 써준다.
public abstract int tax(); //메소드 시그니처
}
abstract라는 키워드가 붙어있으면 new로 객체 생성할 수 없다. ==> 객체를 생성할 생각이 없다는 것을 표시라는 것
미완성 상태의 클래스를 상속받은 클래스는 자기 혹은 그것을 상속받은 클래스가 구현을 해줘야 한다.
abstract클래스 또한 setter, getter, 생성자를 만들 수 있고 공통적인 기능을 abstract으로 만들어 두면 편하다.
public class SmallCar extends Car{
@Override
public int tax() {
// TODO Auto-generated method stub
return 0;
}
}
==> override가 자동으로 생기고 본체{}가 자동으로 생긴다.
abstract을 사용하지 않으면 instanceof, if문를 사용하지 않고 동적바인딩되어 훨씬 편하다.
public class CarTest {
public static void main(String[] args) {
Car car = null; //아직 아무것도 가지고 있지 않은 상태
car = new SmallCar();
init(car);
car = new LargeCar();
init(car);
}
private static void init(Car car) {
car.tax();//동적바인딩, instanceof연산자를 사용하지 않고서도 자기가 가리키는 곳을 알아서 사용한다.
}
}
<인터페이스>
멤버를 가질 수 없기때문에 상수로 인식함. 상수는 static fianl을 붙여야함. 상수는 멤버변수가 아님. fianl을 쓰지않으면 JVM이 알아서 붙임.
인터페이스 안에 상수값을 넣기 위해서는 초기화까지 해줘야 한다.
public interface Tax {
//public을 써주지 않으면 JVM이 자동으로 붙인다.
public int tax();
public static int DATA = 10; //(상수)
}
<인터페이스 다중구현 가능: 두개의 인터페이스를 동시에 구현>
공통된 메소드가 있을 경우 중복으로 구현하지 않고 한가지만 가져온다.
package myinterface;
//LifeCycle, Tax는 MyCar의 상위인터페이스
public class MyCar implements LifeCycle, Tax {
@Override
public int calc() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int tax() {
// TODO Auto-generated method stub
return 0;
}
}
참조변수의 타입에 따라 호출할 수 있는 메소드(불러오는 것)가 다름
public static void main(String[] args) {
//t는 MyCar를 가리키지만 자신을 Tax라고 생각함.
Tax t = new MyCar();
t.tax(); //Tax로 가서 구현이 되지 않은 것을 알고 구현된 곳으로 찾아감!
LifeCycle l = new MyCar();
l.tax();
l.calc();
}
공통적인 기능을 있다고 생각하면 상위클래스를 만들어 상속하여 사용!
하나의 인터페이스를 만들고 그것을 구현한 a,b,c,d의 콘크리트 클래스에서 메소드를 기능을 바꾸어 사용할 수 있음.
인터페이스의 단점
: 인터페이스를 수정할 경우, 하위에 있는 클래스들에서 에러가 남. 왜? 구현되지 않은 메소드가 생겨버리기 때문에
: 인터페이스의 설계가 매우 중요하다. => 이 문제를 해결하기 위해 functional interface(시그니처 + 본체)가 존재한다.
: 현장, 실무에서는 람다, functional interface에서 사용함. 중요~!
https://docs.oracle.com/javase/8/docs/api/
Java Platform SE 8
docs.oracle.com
API
String
StringBuffer
Math
Calender
<Wrapper 클래스>
: 기본 자료형을 클래스화시킨 것을 Wrapper 클래스라고 함
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Char
boolean Boolean
<Integer>
System.out.println("최대값 : " + Integer.MAX_VALUE);
System.out.println("최소값 : " + Integer.MIN_VALUE);
System.out.println("사이즈(비트 수) : " + Integer.SIZE);
출력값
최대값 : 2147483647
최소값 : -2147483648
사이즈(비트 수) : 32
▶parseInt(String s)
: 문자열을 정수로 변환시켜줌
: parsing하는 것은 구문분석을 의미
메소드들
▶compareTo
: 비교대상 보다 크면 양수가 나오고, 뒤의 값이 더 크면 음수가 나오며 숫자가 의미하는 것은 n 코드값의 차이를 의미한다.
▶concat
: 붙여주는 메소드
String str1 = "bbc";
String str2 = new String("bcd");
String data = str1.concat(str2);
System.out.println(data);
출력값
bbcbcd
▶substring
: 문자열을 가져오는 메소드
String str3 = new String("무궁화 꽃이 피었습니다.");
System.out.println(str3.substring(5));
System.out.println(str3.substring(0,5));
System.out.println(str3.substring(4,5));
출력값
이 피었습니다.
무궁화 꽃
꽃
System.out.println(str3.substring(4,5));는 charAt과 동일
String str1 = "abc";
String str2 = new String("abc"); 가 같다 or 다르다.
String str1 = "abc";
String str2 = new String("abc"); //객체
String temp = "abc";
System.out.println(str1==str2); //주소비교
System.out.println(str1.equals(str2)); //내용비교
System.out.println(str1==temp); //t
System.out.println(str1.equals(temp)); //t
출력값
false
true
String Pool이라는 독특한 메모리 구조
Heap에서는 공통된 데이터가 있으면 새롭게 만들지 않는다.
참고해서 읽어보기
https://starkying.tistory.com/entry/what-is-java-string-pool
String Constant Pool이란? | Java String Pool
Java에서 String 객체를 생성하는 방법은 2가지가 있다. 첫번째는 String literal, 즉 큰 따옴표("")를 사용하는 것이고, 두번째는 new 연산자를 사용하는 것이다. 두 방법에는 어떤 차이가 있을까? 간단한
starkying.tistory.com
▶split
: 문자열을 나눔
String text = "서울 대전 대구 부산 제주";
String[] ary = text.split(" ");
System.out.println(ary[3]);
토큰
: 끊을 수 있는 하나의 데이터 대전, 서울, 부산과 같은 데이터
: 그렇게 하는 것을 토크나이징이라고 한다.
▶length
: 문자열의 총 길이를 숫자로 return
Stirng은 immutable한 데이터이다. => 수정하지 말라는 것 !
String a = "a";
String b = "b";
String c = "c";
String d = a+b+c; 성능이 매우 떨어짐
mutable한 문자열을 다루는 클래스 : StringBuffer
▶capacity
: 용량 확인
StringBuffer buf = new StringBuffer();
System.out.println("용량: " + buf.capacity());
출력
용량: 16
▶append
: 문자열 안에 boolean을 포함한 모든 타입을 다 붙일 수 있다.
: +를 사용하지 않고 붙일 수 있음
: return 타입은 StringBuffer이다.
buf.append("서울")
.append("대전")
.append("&")
.append(true)
.append(43);
System.out.println(buf);
출력
서울대전&true43
StringBuffer buf = new StringBuffer();의 용량은 자동으로 늘어난다.
StringBuffer은 String이 가지고 있는 단점을 보완한, String은 데이터에 변경을 가하는 것이 좋지 않기 때문에,
연산이 많을 경우 StringBuffer를 사용한다.
▶insert(int offset, 타입)
: 위치를 지정해 원하는 값을 중간에 끼워 넣을 수 있음
System.out.println(buf.insert(5, false));
출력값
서울대전&falsetrue43서울대전&true43서울대전&true43서울대전&true43
▶ensureCapacity
: 용량을 늘이기
▶trimToSize
: 실제 사용하는 크기 용량만큼, 사용하지 않는 공간은 버리는 메소드
Math
System.out.println(Math.PI); //파이
System.out.println(Math.max(5, 6)); //최대
System.out.println(Math.min(5, 6)); //최소
System.out.println(Math.round(42.195)); //반올림
System.out.println(Math.floor(-42.195)); //올림
System.out.println(Math.ceil(-42.195)); //내림
System.out.println(Math.pow(2,3)); //제곱
System.out.println(Math.sqrt(9)); //숫자의 제곱근
출력값
3.141592653589793
6
5
42
-43.0
-42.0
8.0
3.0
final 키워드
지역변수, 멤버변수 앞 : 값 수정 불가
method 앞 : 오버라이딩 금지
clsaa 앞 : 상속 금지! 더 이상 기능을 늘릴 수 없음!
연습문제2번 다시 풀어보기 !
어려운 부분 배열에 값 넣는 것
<자리수 찍기 String.format>
String.format을 이용해 10,000원 세자리에 하나씩 ","을 넣을 수 있다.
int i = 10000000;
String a = String.format("%,d", i);
System.out.println(a);
출력값
10,000,000