모든 생성자안에는 super()가 생략되어 있다.
A class - B class - C class 부모-자식 관계일 때
전혀 상관 없는 별도의 D class에서 C class의 객체를 생성할때 기본생성자안에있는 super를 통해
부모클래스의 메모리를 먼저 할당받은 뒤 마지막에 자식클래스 생성.
이때 최상위에 있는 A class의 부모클래스는? Object .
java에서 가장 큰 자료형 = Object . 무엇이든지 넣을 수 있다. 자동으로 옮길 경우에는 무조건 object로 옮김. 제일 크니까.
class Test{
private String title;
protected int area;
//public Test(){}//기본생성자
public Test(String title){ //오버로딩된 생성자
this.title = title;
}
public void print(){
System.out.println(title + " : " + area);
}
}
class Rect extends Test{ //에러발생.
//기본생성자 생략되어있음.
//이 기본생성자안에는 super(); 포함
//부모클래스의 기본생성자를 생략하게 되면, 사용하지 않겠다는 의미.
//자식클래스에서 부모클래스의 기본생성자를 사용못해서 오류
private int w,h;
public Rect(int w, int h){
//default값은 기본생성자임 super();
//-> 그런데 부모클래스에 기본생성자를 삭제했으므로 오버로딩된 생성자를 통해 객체 생성해야함
super("사각형"); //super에 매개변수를 할당하면 오류 사라짐. 부모클래스의 오버로딩된 생성자를 호출
//부모클래스가 먼저 만들어져야 자식클래스가 생성 가능
this.w =w;
this.h =h;
//super("사각형"); 밑에 쓰면 오류남. 부모클래스 없는데 매개변수를 입력받아 처리 불가능. 두번입력도 불가능
}
public void rectArea(){
area=w*h; //부모클래스 생성된 상태이므로 부모클래스의 변수 사용 가능
}
}
public class Test1 {
public static void main(String[] args) {
Rect ob = new Rect(10,20);
ob.rectArea();
ob.print(); //부모클래스에서 가져다 씀
}
}
기본생성자와 super()
class Super{
public Super(){}
public Super(int x){
}
public Super(int x, int y){
}
}
class Sub extends Super{
//Sub(){} 기본생성자 존재
//그 안에 super() 숨겨져있음. super()의 역할은 부모-자식간의 관계를 유지시켜주는 것
public Sub(){
this(10); //public Sub(int a){} 호출. 생성자에서 생성자 호출. 이럴땐 this사용
}
public Sub(int a){
//super(); 기본생성자 호출
super(10,20); //오버로딩된 생성자를 호출.
}
}
public class Test2 {
public static void main(String[] args){
Sub ob = new Sub(10);
}
}
오버로딩된 생성자
override(오버라이드, 재정의, 다형성) : 저장공간이 다르기 때문에 메소드이름이 동일해도 가능함.
상속관계에서 부모의 메소드와 똑같이 만들고...(메소드명, 매개변수 등) 내용만 다르게 만듦
하는 역할은 유사. 자식의 마음대로 내용을 변형. 프로그래머의 의도가 반영
@Override 어노테이션(Annotation)
class SuperA{
private String title;
protected double area;
public SuperA(){} //기본생성자
public SuperA(String title){ //오버로딩된 생성자
this.title = title;
}
//메소드
public void write(){
System.out.println(title + " : " + area);
}
}
//Circle클래스와 Recta클래스는 아무 상관 없음.
class Circle extends SuperA{
private int r;
protected static final double PI = 3.14; //static이므로 폰트 기울여짐. 메모리상에 알아서 올라감
public Circle(int r){
super("원"); //SuperA클래스의 기본생성자를 찾아가는데 그곳에 기본생성자가 없다면. 에러
this.r=r;
}
public void circleArea(){
area=r*r*PI; //PI가 double이므로 형변환됨
}
}
class Recta extends SuperA{
private int w,h;
public void rectArea(int w, int h){
this.w= w; //이게없으면 초기값 0으로 처리
this.h= h;
area = w*h;
//super.write();
}
//마우스우클릭 - Source > Override > 부모클래스중에 어느 메소드를 재정의할지 어노테이션 기능 사용 가능
//Annotation : 메소드명이나 매개변수 갯수,자료형들이 달라지면 알려줌
//부모클래스가 무엇인지도 쉽게 볼 수 있음
@Override
public void write() {
//super.write(); //자식클래스의 메소드안에서 부모의 메소드를 간접적으로 사용 가능. main문에서는 작성안됨.
System.out.println("가로:"+w);
System.out.println("세로:"+h);
System.out.println("면적:"+area);
}
}
public class Test3 {
public static void main(String[] args) {
Circle ob1 = new Circle(10);
ob1.circleArea();
ob1.write();
System.out.println("------------------------------------");
Recta ob2 = new Recta();//기본생성자로 생성
ob2.rectArea(10, 20); //매개변수값 필요
ob2.write(); //5. 부모도 가지고 있고 나도 가지고 있으면 내꺼 쓴다. 무조건!!
//어떠한 방법으로도 부모 메소드를 사용할 수 없음. 보안이 철저하기 때문. 클래스 정의시 메소드 안에서는 가능(53줄).
//메소드는 하늘이 두쪽나도 자신 것을 사용함. 그만큼 보안이 철저.
}
}
Object : 모든클래스는 Object를 상속받는다.
class TestA extends Object{ // 모든클래스의 부모클래스는 Object.
//extends Object를 쓰지 않아도 오류 안남. 기본적으로 상속개념이 이미 반영되어있음
private int a = 10;
public void write(){
System.out.println("a: " + a);
}
}
public class Test4 {
public static void main(String[] args) {
TestA ob1 = new TestA(); // new : 물리적으로 새롭게 만들어라. 100번 썼으면 100개 만들어짐
TestA ob2 = new TestA();
System.out.println("ob1==ob2 : " + (ob1==ob2) ); //false : 주소를 비교한 것 이기 때문
//똑같은 클래스로 객체 생성했지만 ob1에 들은 주소와 ob2에 들은 주소가 다르기 때문
System.out.println("ob1.equals(ob2) : " + (ob1.equals(ob2)) ); //.equals()라는 메소드 사용
//모든 클래스의 부모는 Object. 내맘대로 가져다 쓸 수 있음
//equals() 메소드는 주소와 주소를 비교함
System.out.println("ob1: " + ob1); //com.day9.TestA@15db9742 <- @뒤에 숫자는 hashcode
System.out.println("ob2: " + ob2.toString()); //com.day9.TestA@6d06d69c 패키지.클래스.hashcode
//자바에서는 포인터변수 사용 안한다.
}
}
String
String은 class이다.(자료형이 아니다.)
다만, String을 자료형처럼 사용하는 이유는 저장하는 양은 방대하고 사용빈도가 높기 때문
stack영역에 저장할 수 없고 heap영역에 저장해야 함 -> 그러다보니 class여야함
그런데 사용빈도가 높다보니 new 쓰면 번거로움 -> 그래서 자료형모양새 처럼 씀
String은 불변의 법칙을 가지고 있다.
String은 equals로 비교한다.
public class Test5 {
public static void main(String[] args) {
String ob1 = "Seoul"; //heap영역에 "Seoul"이 저장됨
String ob2 = "Seoul"; //Call by reference
String ob3 = new String("Seoul"); //사용빈도가 높다보니 이렇게 쓰기 어려움
System.out.println("ob1 == ob2 : " + (ob1 == ob2)); //주소를 비교하면 false가 나와야하는데 true가 나옴
//ob1, ob2 객체 생성시 new를 사용한게 아니기 때문에 Call by reference. 주소를 나눠가짐
System.out.println("ob1 == ob2 : " + (ob1 == ob3)); //false
//new를 통해 객체 생성, 무조건 heap영역에 새로운 메모리 할당. 주소값 상이하므로 false나옴
System.out.println("ob1.equals(ob3) : " + ob1.equals(ob3)); //true
//String은 클래스지만 자료형의 흉내를 내야함.
//ob1의 주소를 찾아가서의 값과 ob3의 주소를 찾아가서의 값을 비교해야 함
//object.equals() : 이 메소드는 주소값 비교.
//object의 equals 메소드를 쓴게 아니라 String의 equals 메소드를 사용 (override : 자식클래스에서 메소드재정의)
ob2 = "korea"; //새롭게 메모리 할당함
System.out.println("ob1 == ob2 : " + (ob1 == ob2)); //false
ob2 = "japan"; //korea와는 다르게 또 새로운 메모리 할당함
System.out.println("ob1 == ob2 : " + (ob1 == ob2)); //false
//이게 바로 String 불변의 법칙
ob2 = "Seoul"; //이미 Seoul을 할당해둔 게 있으니 그 주소로 저장
System.out.println("ob1 == ob2 : " + (ob1 == ob2)); //True
//쓰레기값이 굉장히 많이 남아있다.
//일반적으로 많은 문자열을 입력할 경우 사용하는게 따로 있음
System.out.println(ob1); //hashcode가 아닌 Seoul이 나옴
System.out.println(ob1.toString()); //Seoul. override함. String의 toString()메소드 사용
//String을 보조해주는 클래스 2개 존재 -> Test6
}
}
StringBuffer - 동기화지원O(builder보다 느림)
StringBuilder - 동기화지원X(지원하지 않아 빠름)
위에 두 클래스는 import하지 않아도 사용가능! -> 즉, 둘다 lang에 있다.
둘은 하는 역할이 다름
동기화 지원 여부에 따라서 선택하여 사용하면 됨
public class Test6 {
public void stringTime(){ //쓰레기값이 많이생김, a, aa, aaa, aaaa ... 모두 저장됨.
System.out.println("stringTime...");
//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(){ //누적시키는 것. append메소드 이용.
System.out.println("stringBufferTime...");
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("stringBuilderTime...");
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) {
Test6 ob = new Test6();
ob.stringTime();
ob.stringBufferTime();
ob.stringBuilderTime();
}
}
Integer(int의 참조형 자료형) double의 참조자료형은 Double
int a = 10; //일반자료형
Integer b = new Integer(10); //자료형의 참조형 자료형 8개있음. (String은 class이므로 제외)
public class Test7 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("서울");
sb.append("부산");
sb.append("대구");
System.out.println(sb);
String str = sb.toString(); //object.toString을 override한 것. 결과만 저장.
System.out.println(str); //StringBuffer와 StringBuilder사용시 이렇게 저장 후 출력해주면 됨
int a = 24;
System.out.println(a); //정수 10
System.out.println(Integer.toString(a)); //문자 10
System.out.println(Integer.toString(a,2)); //2진수
System.out.println(Integer.toString(a,8)); //8진수
System.out.println(Integer.toString(a,16)); //16진수
}
}
'Dev > Java' 카테고리의 다른 글
[java] 추상클래스, 인터페이스 (0) | 2019.01.25 |
---|---|
[java] Calendar 클래스, Wrapper 클래스, Singleton, final (0) | 2019.01.24 |
[java] 생성자, instance블럭, static블럭, 재귀함수, Call By Reference (0) | 2019.01.24 |
[java] static변수, 변수 초기화 방법, Overloading (0) | 2019.01.22 |
[java] 전역/지역변수, 버블정렬,구구단만들기 (0) | 2019.01.22 |