[211112] 교육 12일차
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
를 사용하고, 인터페이스에 선언된 모든 메서드를 오버라이딩 해줘야 한다.
Author And Source
이 문제에 관하여([211112] 교육 12일차), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@choiyezz/211112-교육-12일차저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)