Object : 모든 클래스의 조상
package ~~
class O {}
는 사실 class O extens Object {} 이다. ( 자바안에서 비록 우리에게 눈으로 안보여도)
공통적인 기능들을 Object 클래스에 구현해놓았다.
Object 클래스 ( 2/5 ) : toString
toString () 메소드 : 문자화 하는것
c1.toString()
자바는 내부적으로 toString 이라는 메소드를 호출 ( 문자화 )
부모클래스 Object 는 모든 클래스의 상위클래스인데 Object 에 있는 toString을 overriding 을 통해서 사용을 변경할 수 있다.
Object 클래스 ( 3/5 ) : equals
class Student {
String name ;
Student ( String name ) {
this.name = name ;
}
//오버라이딩중
public boolean equals ( Object obj ) { //데이터 타입이 Object 이고 밑에서 obj 로 오려고 하는 그 s2 는 Student 타입이다. -> Student 의 부모가 Object 이다.
Student s = (Student) obj ;
return this.name = s.name ;
}
}
******중요*********
**Object obj = s2 ( 데이터타입은 Student ) 즉 자식데이터타입을 부모데이터타입을 가지고 있는 변수에 할당하려고함 ( 다형성 -> 자식 데이터 타입은 부모 데이터 타입에 할당 될 수 있다. ) 그렇게 되면 Object에는 존재하지 않고 자식인 s2 ( Student 타입 ) 만 가지고 있는 name 이라는 인스턴스 변수에 접근을 할 수 없다. ( 다형성에서 배웠잖아 ) 따라서 Object 타입을 -> Student 타입으로 다시 변환시켜야 할 필요가 있다...
Student s =obj; 전환할 수 없다 (그냥은 불가능 ) ( Object obj = s2 가능 . 부모가 더 크니까 ) --> Student s = (Student)obj 이렇게 써야한다.( 중요 : 즉 자식이 부모로 변환은 가능하지만 부모가 자식으로 되려면 강제로 명시적으로 형변환을 해야하지만 형변환이 되는... 정책을 java 가 가지고 있다. )
-- 완벽하게 동일하게 하려면 Object 클래스의 메소드중 하나인 hashCode() 까지 함께 구현해서 오버라이딩해되 ! . (심화)
class ObjectDemo {
public static void main ( String [][ args {
Student s1 = new Student ( "egoing " ) ;
Student s2 = new Student ( "egoing " ) ;
System.out.println ( s1 == s2 ) ; false
System.out.println ( s1.equals(s2) ) ; false
}
//name 이라는 애가 같다면 s1 과 s2 가 같다고 할 수 있도록 equals를 오버라이딩해서 만들 수 있다.
}
Object 클래스 ( 4/5 ) : finalize
여러가지이유로 사용을 만류하고 있다.
finalize 는 객체가 소멸될 때 호출되기로 약속된 메서드
원시 데이터형 ( byte, short, int , long , float , double, boolean, char ) 를 사용할 때는 비교연산자 == 를 쓰고 , String 이나 객체를 비교할 때는 equals 를 사용한다.
-toString 가급적 구현하기를 권장한다.
-equals 를 기본적으로 사용하는 것이 권장된다.
가비지 컬렉션 (garbage colletion ) 인스턴스를 만드는 것은 내부적으로는 컴퓨터의 메모리를 사용하는 것이다. 메모리는 RAM
프로그램은 RAM (아주빠른) 에 올라온 상태로 실행된다.
좋은 애플리케이션은 RAM을 작게 사용하고 파워풀하게 기능해야 한다.
자바는 아주 제한적으로 제공을 한다. ( 램을 관리하는 작업을 자바에서는 자동화시켰다. -> 가비지 컬렉션 )
변수를 사용하는 곳이 더이상 없다면 이 변수와 변수에 담겨 있는 인스턴스는 더 이상 메모리에 머물고 있을 필요가 없다. 자바는 이를 감지 -> 자동으로 쓰지 않은 데이터를 삭제
Object 클래스 ( 5/5 ) : colone
복제 하는 역할
class Student implements Cloneable {
String name
Student ( String name ) {
this.name = name ;
}
public Object clone() throws CloneNotSupportedException {
return super.clone() ;
}
** clone 에 들어가 보면 protected Object clone()
throws CloneNotSupportedException
이렇게 되어 있다. 즉 RuntimeExceptin 이 아니라 그냥 exception 이라서 반드시 처리를 해야한다. throws CloneNotSupportedException 써줘야함
}
public class ObjectDem {
public static void main ( String [] args ) {
Student s1 = new Student ( "egoing" ) ;
s1.clone () ; --> 에러가 난다. : Student 라는 클래스를 복제를 하려면 Student 클래 스가 복제가능한 클래스라고 자바 버추얼머신에 알려줘야 한다.(위)
Cloneable 은 비어있다 . 비어있는 인터페이스를 구현 단지 Student 클래스가 복제가 능한 클래스라고 알려주기 위한 구분자의 역할
class 에서 implements Cloneable 를 해줬는데도 오류가 계속 있다. (파랑)
clone() 은 protected Object 이다. (public 이 아니다 ) -> protected 는 같은 패키지.
Object 는 java.lang 패키지에 속해 있다. ( 다른 패키지 )
접근제어자가 public 이기 때문에Object 안에 있는 애들을 호출 할 수 이썼다.
(파랑 다음 ) -> 사용하는 쪽에서 throws 할건지 해결할건지 결정 해야함.
-->> try {
Student s2 = (Student)s1.clone () ; 명시적형변환 필요
} catch ( CloneNoteSupportedException e ) {
e.printStackTrace() ;
}
}
어려우면 다시 한번 봐 : https://www.youtube.com/watch?v=g7zFI2Mr_Xc&list=PLuHgQVnccGMCeAy-2-llhw3nWoQKUvQck&index=137&ab_channel=%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9
상수와 enum ( 1/4 ) : 상수에 대한 복습
상수 2 - enum
interface FRUIT {
int APPLE = 1 , PEACH = 2 , BANANA = 3 ; // 인터페이스를 통해서 이름이 충돌할 가능성이 없어져서 접두사를 붙일 필요가 없다.
}
interface COMPANY {
int GOOGLE = 1, APPLE =2, ORACLE = 3 ;
}
pubic class ConstantDemo {
/* public final static int APLLE = 1;
public final static int PEACH = 2;
ublic final static int BANANA = 3;
private final static int COMPANY_GOOGLE = 1;
private final static int COMPANY_APPLE = 2; //APPLE 을 두번 쓸 수 있어서 접두사붙여줌
private final static int COMPANY_ORACLE = 3;
*/
public static void main ( String [] args ) {
if ( FRUIT.APPLE == COMPANY.APPLE) {
System.out.println("과일애플과 기업애플은 같습니다." )
} --> 컴파일오류가 나지 않지만 오류다 FRUIT.APPLE , COMPANY.APPLE 두개는 모두 int 타입이라서 오류가 나지 않는데, 하나는 String 타입이었다면
컴파일 단계부터 막혔겠지. 그런데 실상은 두개는 다른것이기 때문에 문제
int type = FRUIT.APPLE;
switch(type) {
case FRUIT.APPLE :
System.out.pritnl ( 57 + "kcal " ) ;
break;
case FRUIT.PEACH :
System.out.println(34 + "kcal " ) ;
break;
case FRUIT.BANANA :
System.out.println(93+"kcal" ) ;
break;
}
}
------------------------------> 위에 있는 녹색 문제 해결하기 서로 다른 애니까 컴파일에러 나게 하기
class Fruit {
public static final Fruit APPLE = new Fruit(); //인스턴스화
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
// APPLE , PEACH , BANANA 모두 다른 인스턴스이기 때문에 모두 다름 ( 데이터타입은 Fruit 로 같지만... )
}
class Company {
public static final Company GOOGLE = new Company(); //인스턴스화
public static final Company APPLE = new Company();
public static final Company ORACLE = new Company();
}
pubic class ConstantDemo {
public static void main ( String [] args ) {
if ( Fruit.APPLE == Company.APPL ) { //컴파일에러가 뜸
데이터타입이 하나는 Fruit 하나는 Company 이기 때문에
System.out.println( "과일 애플과 회사 애플이 같다. )
}
int type = Fruit.APPLE;
switch(type) {
case Fruit.APPLE :
System.out.pritnl ( 57 + "kcal " ) ;
break;
case Fruit.PEACH :
System.out.println(34 + "kcal " ) ;
break;
case Fruit.BANANA :
System.out.println(93+"kcal" ) ;
break;
}
}
switch 문에 들어가는 조건이 제한적 데이터타입만을 사용할 수 있다.
byte, short, char, in, enum , String , Character, Byte, Short , Integer
그런데 위에 예시로 든것은 class 타입으로 만든 상수를 switch 에서 사용불가. if 문에서는 사용 가능
-----> 해결책 : enum 사용하자
상수와 enum ( 3/4) : enum 의 문법
enum 은 열거형 ( enumerated type ) 이라고 부른다 열거형은 서로 연관된 상수들의 집합이라고 할 수 있다.
class Fruit {
public static final Fruit APPLE = new Fruit();
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
}
== 둘이 동일하다
enum Fruit { //Fruit 은 클래스다 . 위에 있는거랑똑같은 코드다.
APPLE , PEACH, BANANA
}
public class ConstantDmo {
public static void main ( String[] args ) {
Fruit type = Fruit.APPLE;
switch ( type ) {
case APPLE : // 앞에 Fruit 를 써주지 않아도 자바가 안다.
System.out.println( 57 + " kcal" ) ;
break;
}
}
}
이 가능하다.
기능
코드가 단순해진다
인스턴스의 생성과 상속을 방지한다.
enum 을 사용하는 Fruit 는 열거를 위한 목적을 알 수 있다. (구현의 의도)
상수와 enum ( 4/4 ) : 열거형의 활용
enum 은 사실상 class 따라서 생성자를 가질 수 있다.
public static final Fruit APPLE = new Fruit();
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
밑에 있는 것과 위에있는 거는 동일한것.
enum Fruit {
APPLE("red"), PEACH("pink"), BANANA("yellow") ; ( 인스턴스화한것 )
Private String color; //public 보다는 Private 으로 해서 직접 변하게하지 않게 (사용자들이)
public String getColor () {
return this.color ;
}
Fruit(String color) { // 컬러에 위에 있는 red , pink , yellow 가 들어가는것
// 생성자 -> 인스턴스(new)하면 생성자를 호출한다. -> 밑에가 실행이 되는데 여기서는 출력하는것을 적어놓은것 . 근데 위에 있는 보라부분이랑 위에 파랑부분이 동일하다고 했으니까. 세번 생성자를 호출한게 된다
System.out.println("Call Constructor " + this ); // ( this 는 APPLE, PEACH , BANANA 가 차례대로출력 )
this.color = color ( 전역변수 호출 )
}
}
--> 상수가 3개인 경우에는 Call Constructor 가 3번 출력이 된다.
Main 에
Fruit type = Fruit.APPLE ;
switch(type ) {
case APPLE :
System.out.println(57 + "kcal, color " + Fruit.Apple.getColor ) :
break;
결론 : enum 은 그 필드안에 변수, 메소드 등도 다 들어갈 수 있는 클래스 같은것.
values() 메소드
public class ConstantDemo {
main ~ {
for(Fruit f : Fruit.values() ) {
System.out.println(f);
}
}
}
열거형이 가지고 있는 상수들을 담은 배열들을 가지고 올 수 있어서 그 상수들을 하나하나 꺼내서 가지고 올 수 있다.
배열처럼 상수들을 하나하나 꺼내서 처리할 수 있는 기능도 제공 ( values() 메소드)
댓글
댓글 쓰기