[211112] 교육 12일차

oxllz·2022년 1월 27일
0

교육

목록 보기
10/41

Object

class Temp {
	public String toString() {
		return "HelloWorld";
	}
}
//
public class Test097 {
	public static void main( String[] args ) {
		Object t = new Temp();
		// 오버라이딩 전 : Temp@2a139a55 - 클래스명@인스턴스고유번호
		System.out.println( t.toString() );  // Helloworld
		System.out.println( t ); // Helloworld
	}
}

java 는 명시하지 않으면 extends Object 를 자동으로 붙인다. 따라서 Object 는 모든 클래스의 조상이 된다.

Object 타입의 변수는 모든 인스턴스를 가리킬수 있다는 얘기가 된다.

toString() 은 뭐다? Object 에서 상속받았다. ( 클래스명@인스턴스 고유번호 )
"인스턴스에 관련된 걸 간단한 문자열로 정보를 보고 싶을때는 toString() 을 애용한다"

// 오버로딩
void println( Object x ) {
	//	x.toString() 을 호출해서 결과를 찍는다.
}

void println( String x ) {
	//	t 문자열 그냥 찍어준다.
}

참조형 변수의 비교

class Temp {
	int data = 0;
	Temp( int i ) {
		data = i;
	}
	//
	public boolean equals( Object b ) {
		System.out.println( this.toString() );
		Temp t = (Temp)b;
		if( this.data == t.data ){	// b.data 는 왜 안되지? this.data 는 되나?
			return true;
		} else {
			return false;
		}
	}
}
//
public class Test098 {
	public static void main( String[] args ) {
		Temp t = new Temp( 100 );
		Temp l = new Temp( 100 );
		System.out.println( t == l ); // false
		System.out.println( t.data == l.data );	// true
		Object t2 = new Temp( 200 );
		Object l2 = new Temp( 201 );
		System.out.println( t2 == l2 );
		// 에러 : System.out.println( t2.data == l2.data );
		// 자식 클래스의 멤버변수에 접근할 수 없다.
		// equals 의 정체는 ? 호출 가능 ? 결과는 ?
		boolean b = t2.equals( l2 );
		System.out.println( b );
	}
}

System.out.println( t == l ); // false

참조형 변수의 비교는 같은 대상을 가리킬때 true를 출력한다.
t와 l 은 각각 다른 인스턴스를 가라키고 있기때문에 false 출력.

boolean b = t2.equals( l2 );
public boolean equals( Object b ){...}
if( this.data == t.data )

b.data가 안되는 이유는 b는 Object 를 가리키고 있기때문에 자식 클래스인 Temp의 멤버변수에 접근할 수 없다. 그렇기 때문에 Temp t = (Temp)b 로 캐스팅해줘야 한다.

class A {}
//
class B extends A {
	void print() {}	
}
//
public class Test099 {
	public static void main( String[] args ) {
		A t = new A();
		boolean b = ( t instanceof B );
		System.out.println( b );
		//	실행시 에러 : B t2 = (B)t;
		A t2 = new B();
		boolean b2 = ( t2 instanceof B );
		System.out.println( b2 );		
		B t3 = (B)t2;
	}
}

(참조형변수) instanceof (클래스)
: 참조형변수가 가리키는 대상을 클래스로 캐스팅 가능하면 true / false

위의 Test098 에서 코드 추가가 필요하다

if( b == null || ( ( b instanceof Temp ) == false ) ) {
	return false;
}

접근 지정자

class A {
	private int drug = 0;
	protected int vijagum = 1;
	public int budongsan = 2;
	//
	void picnic() {
		System.out.println( this.drug );		//  가능 ( 바람직하진 않음 )
		System.out.println( this.vijagum );		//	가능
		System.out.println( this.budongsan );	//	가능
		// 접근지정자 ( public protected private ) 상관없이 나는 얼마든지 접근 가능
	}
}
//
class B extends A {
	void print() {
		// 에러 : System.out.println( this.drug ); 
		System.out.println( this.vijagum );	// OK
		System.out.println( this.budongsan );	// OK
	}
}
//
public class Test100 {
	public static void main( String[] args ) {
		// 에러 : private int i = 0; : 로컬변수 앞에는 붙을수 없다
		//
		A t = new A();
		System.out.println( t.budongsan );
		// 에러 : System.out.println( t.drug ); : 외부인은 포인터로 접근불가.
		// 같은 패키지에 속한 클래스는 protected 멤버에 접근 가능
		// 다른 패키지에 속한 클래스는 protected 멤버에 접근 불가능
		System.out.println( t.vijagum );
	}
}


friendly 는 같은 패키지에서는 public 하게 다른 패키지에서는 private 하게 동작한다.

자식 클래스

  • private : 존재하지만 접근 불가
  • protected : 접근 가능
  • public : 접근 가능

외부에서

  • private : 접근 불가
  • protected : 같은 패키지 안에서는 접근 가능
  • public : 접근 가능

Package

package apple;
//
public class 패키지 {
	private int rivate = 0;
	protected int rotected = 0;
	public int ublic = 0;
	int riendly = 0;
}

패키지는 소스코드 맨 위에 지정하고, 한번만 지정한다.
해당 파일에서 선언된 모든 클래스는 해당 패키지에 속한다.

import apple.패키지;
//
public class Test101 {
	public static void main( String[] args ) {
		패키지 t = new 패키지();
		// System.out.println( t.rivate );
		// System.out.println( t.rotected );
		System.out.println( t.ublic );
		// System.out.println( t.riendly );
	}
}

다른 패키지에 있는 클래스를 사용할 때 import 패키지명.클래스명; 을 언급한다.


Abstract

abstract class Temp {
	abstract public void print();
}
///
class Temp2 extends Temp {
	public void print() {
		System.out.println("HelloWorld");
	}
}
///
public class Test102 {
	public static void main( String[] args ) {
		Temp t = new Temp2();
		t.print();
	}
}

abstract class: 인스턴스를 만들 수 없는 클래스
( 클래스로 하는 일 : 참조형 변수 선언, 인스턴스 생성, 상속 받아 클래스 선언

abstract method : 선언되었지만 정의되지 않은 메소드. 이걸 가진 클래스는 반드시 abstract 로 선언되어야 한다. 오버라이딩 하면 abstract 가 떨어져 나간다.

abstract class 를 활용할 때 [A t = new B()] 형태로 쓰는 경우가 매우많다.

부모의 클래스의 abstract method 를 자식 클래스가 상속받기 때문에 자식 클래스도 abstract 로 선언해야한다. but! 오버라이딩 하면 내용이 생기므로 abstract 가 떨어져나가 자식 클래스는 abstract 로 선언하지 않아도 된다.

  • abstract method 는 함수 포인터에 null 값이 들어있는 함수에 해당한다. 그렇기때문에 함수를 호출하는 것을 방지하기 위해 abstract method 를 가진 클래스는 인스턴스 가 존재해서는 안된다.
  • abstract method 를 오버라이딩 하면 null 값이 들어있는 함수 포인터가 새로운 실체를 가리키게 된다. ( abstract 성질 사라지고 인스턴스 생성 가능 )

interface

interface ITemp {
	abstract public void print() ;
	public void print( int i ) ;
}
//
class Temp implements ITemp {
	public void print() { System.out.println("print"); }
	public void print( int i ) { System.out.println("print2"); }
}
//
public class Test104 {
	public static void main( String[] args ) {
		ITemp t = new Temp();
		t.print();
		t.print( 100 );
	}
}

abstract 한 메서드만 멤버로 가진다. 인스턴스 생성 불가

인터페이스를 상속받을때는 implements 를 사용하고, 인터페이스에 선언된 모든 메서드를 오버라이딩 해줘야 한다.

0개의 댓글