Private Constructor 객체지향개념상속, 추상클래스, 다형성 514760-1 2017 년가을학기 9/25/2017 박경신 Private 생성자 정적멤버만포함하는클래스에서일반적으로사용 클래스가인스턴스화될수없음을분명히하기위해 private constructor를사용 public class Counter { private Counter() { public static int currentcount; public static int IncrementCount() { return ++currentcount; class TestCounter { //Counter acounter = new Counter(); // Error Counter.currentCount = 100; Counter.IncrementCount(); System.out.println( count= +Counter.currentCount); Protected Constructor Protected 생성자 Protected 생성자는추상클래스 (abstract class) 에서사용을권함. 추상클래스에는 protected 또는 default 생성자를정의함. 추상클래스를상속받은파생클래스에서추상클래스의 protected 생성자를호출하여초기화작업을수행함. abstract class Shape { protected Shape(String name) { this.name = name; private String name; public void print() { System.out.println(this.name); class Triangle extends Shape { public Triangle(string name) { super(name); class Rectangle extends Shape { public Rectangle(string name) { super(name); public class ShapeTest { //Shape s= new Shape( 도형 ); // error Shape is abstract: cannot be instantiated Shape s = new Triangle( 삼각형 ); s.print(); // 삼각형 s = new Rectangle( 직사각형 ); s.print(); // 직사각형 Static vs Instance Initializer Block Static Initializer Block 클래스로딩시호출 instance 필드메소드사용못함 static 변수초기화에사용 Instance Initializer Block 객체생성시호출 super 생성자이후에실행하고생성자보다먼저실행 instance 필드메소드에접근가능 모든생성자의공통부분을 instance initializer block 에넣어줌 class StaticPoint { private static int[] data ; static { data = new int[] { 1, 2, 3 ; class InstancePoint { private int[] data ; { data = new int[] { 100, 200 ; public InstancePoint() { System.out.println( 기본생성자 ); public InstancePoint(int x) { System.out.println( 생성자 );
Instance vs Static Field Instance field 객체의현재상태를저장할수있는자료 객체생성시메모리공간할당 Static(Class) field 전역데이터, 공유데이터로클래스로드시공간을할당함 클래스당하나만정적필드가할당 객체의개수를카운트하거나통계값들을저장하는경우사용함 Withdraw( ) Deposit( ) balance 1000 interest 7% Withdraw( ) Deposit( ) balance 50000 interest 7% Instance vs Static Method Instance method 객체생성시메모리공간할당 정적멤버 (static field & method) 도사용가능 Static(Class) method 클래스로딩시할당, 객체생성없이정적메소드실행가능 정적멤버 (static field & method) 를접근할수있는메소드 인스턴스멤버 (instance field & method) 사용불가 this 사용불가 BankAccount Instance BankAccount Class InterestRate( ) interest 7% Withdraw( ) Deposit( ) balance 10000 상속 (Inheritance) 상속관계예 상속 상위클래스의특성 ( 필드, 메소드 ) 을하위클래스에물려주는것 슈퍼클래스 (superclass) 특성을물려주는상위클래스 서브클래스 (subclass) 특성을물려받는하위클래스 슈퍼클래스에자신만의특성 ( 필드, 메소드 ) 추가 슈퍼클래스의특성 ( 메소드 ) 을수정 구체적으로오버라이딩이라고부름 슈퍼클래스에서하위클래스로갈수록구체적 예 ) 폰 -> 모바일폰 -> 뮤직폰 상속을통해간결한서브클래스작성 동일한특성을재정의할필요가없어서브클래스가간결해짐 class Phone class MobilePhone class MusicMobilePhone 전화걸기전화받기 상속 무선기지국연결배터리충전하기 상속 음악다운받기음악재생하기 구체화
상속의필요성 클래스상속과객체 상속이없는경우중복된멤버를가진 4 개의클래스 상속을이용한경우중복이제거되고간결해진클래스구조 상속선언 public class Person {... public class Student extends Person { // Person 을상속받는클래스 Student 선언... public class StudentWorker extends Student { // Student 를상속받는 StudentWorker 선언... 자바상속의특징 클래스다중상속지원하지않음 다수개의클래스를상속받지못함 상속횟수무제한 상속의최상위클래스는 java.lang.object 클래스 모든클래스는자동으로 java.lang.object 를상속받음 예제 : Point & ColorPoint 클래스 (x,y) 의한점을표현하는 Point 클래스와이를상속받아컬러점을표현하는 ColorPoint 클래스를만들어보자. public class Point { private int x, y; // 한점을구성하는 x, y 좌표 public void set(int x, int y) { this.x = x; this.y = y; public int getx() { return x; public int gety() { return y; public void showpoint() { // 점의좌표출력 System.out.println("(" + x + "," + y + ")"); 예제 : Point & ColorPoint 클래스 public class ColorPoint extends Point { // Point 를상속받은 ColorPoint 선언 String color; // 점의색 void setcolor(string color) { this.color = color; void showcolorpoint() { // 컬러점의좌표출력 System.out.print(color); showpoint(); // Point 클래스의 showpoint() 호출 public static void main(string [] args) { ColorPoint cp = new ColorPoint(); cp.set(3,4); // Point 클래스의 set() 메소드호출 cp.setcolor("red"); // 색지정 cp.showcolorpoint(); // 컬러점의좌표출력 red(3,4) 12
예제 : Shape & Rectangle 클래스 예제 : Shape & Rectangle 클래스 public class Shape { private int x; private int y; public int getx() { return x; public int gety() { return y; void set(int x, int y) { this.x = x; this.y = y; void print() { // x,y 좌표출력 System.out.println("(" + x + "," + y + ")"); public class Rectangle extends Shape { private int width; // 사각형의너비 private int height; // 사각형의높이 public void getwidth() { return width; public void getheight() { return height; public void setwidth(int width) { this.width = width; public void setheight(int height) { this.height = height; public double area() { // 사각형의넓이 ( 영역 ) return (double)width * height); void draw() { // x, y 출력 System.out.println( 사각형 " + getx()+ x" + gety() + " 의영역은 + area()); public class RectangleTest { public static void main(string [] args) { Rectangle r1 = new Rectangle(); Rectangle r2 = new Rectangle(); r1.set(5,3); // Shape 클래스의 set() 메소드호출 r1.setwidth(10); // Rectangle 클래스의 setwidth() 메소드호출 r1.setheight(20); // Rectangle 클래스의 setheight() 메소드호출 r2.set(8,9); // Shape 클래스의 set() 메소드호출 r2.setwidth(10); // Rectangle 클래스의 setwidth() 메소드호출 r2.setheight(20); // Rectangle 클래스의 setheight() 메소드호출 r1.print(); // x,y 좌표출력 r1.draw(); // x,y,width,height,area 출력 r2.print(); // x,y 좌표출력 r2.draw(); // x,y,width,height,area 출력 서브클래스의객체와멤버사용 슈퍼클래스와서브클래스의객체관계 서브클래스의객체와멤버접근 서브클래스의객체에는슈퍼클래스멤버포함 슈퍼클래스의 private 멤버는상속되지만서브클래스에서직접접근불가 슈퍼클래스의 private 멤버는슈퍼클래스의 public/protected 메소드를통해접근 16
서브클래스의객체멤버접근 상속과접근지정자 자바의접근지정자 4 가지 public, protected, default, private 상속관계에서주의할접근지정자는 private 와 protected 슈퍼클래스의 private 멤버 슈퍼클래스의 private 멤버는다른모든클래스에접근불허 슈퍼클래스의 protected 멤버 같은패키지내의모든클래스접근허용 동일패키지여부와상관없이서브클래스에서슈퍼클래스의 protected 멤버접근가능 10 20 슈퍼클래스멤버의접근지정자 슈퍼클래스와서브클래스가같은패키지 ( 같은폴더, 디렉토리 ) 에있는경우
슈퍼클래스와서브클래스가서로다른패키지 ( 다른폴더, 디렉토리 ) 에있는경우 예제 : 상속관계에있는클래스간멤버접근 Person 클래스는아래와같은멤버필드를갖도록선언한다. int age; public String name; protected int height; private int weight; Student 클래스는 Person 클래스를상속받아각멤버필드에값을저장한다. Person 클래스의 private 필드인 weight는 Student 클래스에서는접근이불가능하여슈퍼클래스인 Person의 get, set 메소드를통해서만조작이가능하다. class Person { int age; public String name; protected int height; private int weight; public void setweight(int weight) { this.weight = weight; 21 public int getweight() { return weight; 예제 : 상속관계에있는클래스간멤버접근 public class Student extends Person { void set() { age = 30; name = " 홍길동 "; height = 175; setweight(99); 서브클래스 / 슈퍼클래스의생성자호출과실행 new에의해서브클래스의객체가생성될때 슈퍼클래스생성자와서브클래스생성자모두실행됨 호출순서 서브클래스의생성자가먼저호출, 서브클래스의생성자는실행전슈퍼클래스생성자호출 실행순서 슈퍼클래스의생성자가먼저실행된후서브클래스의생성자실행 Student s = new Student(); s.set();
슈퍼클래스와서브클래스의생성자간의호출및실행관계 생성자 A 생성자 B 생성자 C 서브클래스와슈퍼클래스의생성자짝맞추기 슈퍼클래스와서브클래스 각각여러개의생성자작성가능 슈퍼클래스와서브클래스의생성자사이의짝맞추기 서브클래스와슈퍼클래스의생성자조합 4 가지 서브클래스에서슈퍼클래스의생성자를선택하지않는경우 컴파일러가자동으로슈퍼클래스의기본생성자선택 서브클래스개발자가슈퍼클래스의생성자를명시적으로선택하는경우 super() 키워드를이용하여선택 슈퍼클래스의기본생성자자동호출 서브클래스의기본생성자경우 슈퍼클래스에기본생성자가없어오류난경우 서브클래스의생성자가슈퍼클래스의생성자를선택하지않은경우 서브클래스의생성자가기본생성자인경우, 컴파일러는자동으로슈퍼클래스의기본생성자와짝을맺음 컴파일러가 public B() 에대한짝을찾을수없음 생성자 A 생성자 B 컴파일러에의해 Implicit super constructor 28 A() is undefined. Must explicitly invoke another constructor 오류발생
슈퍼클래스의기본생성자자동호출 서브클래스의매개변수를가진생성자경우 서브클래스의생성자가슈퍼클래스의생성자를선택하지않은경우 super() 를이용하여슈퍼클래스생성자선택 super() 서브클래스에서명시적으로슈퍼클래스의생성자를선택호출할때사용 사용방식 super(parameter); 인자를이용하여슈퍼클래스의적당한생성자호출 반드시서브클래스생성자코드의제일첫라인에와야함 생성자 A 매개변수생성자 B super() 를이용한사례 객체의타입변환 업캐스팅 (upcasting) 프로그램에서이루어지는자동타입변환 서브클래스의레퍼런스값을슈퍼클래스레퍼런스에대입 슈퍼클래스레퍼런스가서브클래스객체를가리키게되는현상 객체내에있는모든멤버를접근할수없고슈퍼클래스의멤버만접근가능 super(); 라고하면 A() 호출 class Person { class Student extends Person {... 매개변수생성자 A5 매개변수생성자 B5 31 Student s = new Student(); Person p = s; // 업캐스팅, 자동타입변환
업캐스팅사례 class Person { String name; String id; public Person(String name) { this.name = name; class Student extends Person { String grade; String department; public Student(String name) { super(name); public class UpcastingEx { Person p; Student s = new Student( 이재문 ); p = s; // 업캐스팅발생 System.out.println(p.name); // 오류없음 //p.grade = "A"; // 컴파일오류 //p.department = "Com"; // 컴파일오류 이재문 객체의타입변환 다운캐스팅 (downcasting) 슈퍼클래스레퍼런스를서브클래스레퍼런스에대입 업캐스팅된것을다시원래대로되돌리는것 명시적으로타입지정 class Person { class Student extends Person {... Student s = (Student)p; // 다운캐스팅, 강제타입변환 다운캐스팅사례 instanceof 연산자와객체의타입구별 업캐스팅된레퍼런스로는객체의진짜타입을구분하기어려움 슈퍼클래스는여러서브클래스에상속되기때문 슈퍼클래스레퍼런스로서브클래스객체를가리킬수있음 instanceof 연산자 instanceof 연산자 레퍼런스가가리키는객체의진짜타입식별 사용법 객체레퍼런스 instanceof 클래스타입 연산의결과 : true/false 의불린값
업캐스팅된객체의실제타입은무엇? instanceof 사용예 예제 : instanceof 를이용한객체구별 instanceof 를이용하여객체의타입을구별하는예를만들어보자 jee 는 Student 타입 kim 은 Professor 타입 kim 은 Researcher 타입 kim 은 Person 타입 "java" 는 String 타입 class Person { class Student extends Person { class Researcher extends Person { class Professor extends Researcher { public class InstanceofExample { Person jee= new Student(); Person kim = new Professor(); Person lee = new Researcher(); if (jee instanceof Student) // jee는 Student 타입이므로 true System.out.println("jee는 Student 타입 "); if ( jee instanceof Researcher) // jee는 Researcher 타입이아니므로 false System.out.println("jee는 Researcher 타입 "); if (kim instanceof Student) // kim은 Student 타입이아니므로 false System.out.println("kim은 Student 타입 "); if (kim instanceof Professor) // kim은 Professor 타입이므로 true System.out.println("kim은 Professor 타입 "); if (kim instanceof Researcher) // kim은 Researcher 타입이기도하므로 true System.out.println("kim은 Researcher 타입 "); if (kim instanceof Person) // kim은 Person 타입이기도하므로 true System.out.println("kim은 Person 타입 "); if (lee instanceof Professor) // lee는 Professor 타입이아니므로 false System.out.println("lee는 Professor 타입 "); if ("java" instanceof String) // "java" 는 String 타입의인스턴스이므로 true System.out.println("\"java\" 는39String 타입 "); Method Overriding class Animal { public void sound() { ; class Dog extends Animal { public void sound() { System.out.println(" 멍멍!"); ; public class DogTest { Dog d = new Dog(); d.sound(); ; Animal 1부터멍멍! 10까지의정수의합 = 55
Method Overriding Method Overriding 사례 메소드오버라이딩 (Method Overriding) 슈퍼클래스의메소드를서브클래스에서재정의 슈퍼클래스의메소드이름, 메소드인자타입및개수, 리턴타입등모든것동일하게작성 이중하나라도다르면메소드오버라이딩실패 동적바인딩발생 서브클래스에오버라이딩된메소드가무조건실행되도록동적바인딩됨 동적바인딩발생 메소드 2() 오버라이딩 서브클래스객체와오버라이딩된메소드호출 예제 : void draw() 메소드오버라이딩예 class DObject { public DObject next; public DObject() { next = null; System.out.println("DObject draw"); class Line extends DObject { // 메소드오버라이딩 System.out.println("Line"); class Rect extends DObject { // 메소드오버라이딩 System.out.println("Rect"); class Circle extends DObject { // 메소드오버라이딩 System.out.println("Circle"); public class MethodOverringEx { DObject obj = new DObject(); Line line = new Line(); DObject p = new Line(); DObject r = line; obj.draw(); // DObject.draw() 실행. "DObject draw" 출력 line.draw(); // Line.draw() 실행. "Line" 출력 p.draw(); // 오버라이딩된 Line.draw() 실행, "Line" 출력 r.draw(); // 오버라이딩된 Line.draw() 실행, "Line" 출력 DObject rect = new Rect(); DObject circle = new Circle(); rect.draw(); // 오버라이딩된 Rect.draw() 실행, "Rect" 출력 circle.draw(); // 오버라이딩된 Circle.draw() 실행, "Circle" 출력 DObject draw Line Line Line Rect Circle
예제실행과정 45 메소드오버라이딩조건 1. 반드시슈퍼클래스메소드와동일한이름, 동일한호출인자, 반환타입을가져야한다. 2. 오버라이딩된메소드의접근지정자는슈퍼클래스의메소드의접근지정자보다좁아질수없다. public > protected > private 순으로지정범위가좁아진다. 3. 반환타입만다르면오류 4. private, final 메소드는오버라이딩될수없다. class Person { String name; String phone; private int ID; public void setname(string s) { name = s; public String getphone() { return phone; public final int getid() { return ID; class Professor extends Person { //protected void setname(string s) { // public 을 protected 로지정할수없음 // // 동일한메소드명, 인자, 반환타입을가짐 public String getphone() { return phone; //public void getphone(){ // 반환타입다르면오류 // //public int getid() { // final 은 override 할수없음 // return ID // Person 의 ID 는 private 이라서오류 // 오버라이딩활용 public static void main(string [] args) { DObject start, n, obj; // 링크드리스트로도형생성하여연결하기 start = new Line(); //Line 객체연결 n = start; obj = new Rect(); n.next = obj; //Rect 객체연결 n = obj; obj = new Line(); // Line 객체연결 n.next = obj; n = obj; obj = new Circle(); // Circle 객체연결 n.next = obj; // 모든도형출력하기 while(start!= null) { start.draw(); start = start.next; Line Rect Line Circle 동적바인딩 오버라이딩메소드가항상호출된다. public class SuperObject { protected String name; public void paint() { draw(); System.out.println("Super Object"); public static void main(string [] args) { SuperObject a = new SuperObject(); a.paint(); class SuperObject { protected String name; public void paint() { draw(); 동적바인딩 System.out.println("Super Object"); public class SubObject extends SuperObject { System.out.println("Sub Object"); public static void main(string [] args) { SuperObject b = new SubObject(); b.paint(); Super Object Sub Object 47
super 키워드 super 키워드 super 는슈퍼클래스의멤버를접근할때사용되는레퍼런스 서브클래스에서만사용 슈퍼클래스의메소드호출시사용 컴파일러는 super 호출을정적바인딩으로처리 class SuperObject { protected String name; public void paint() { draw(); System.out.println(name); public class SubObject extends SuperObject { protected String name; name = "Sub"; super.name = "Super"; super.draw(); System.out.println(name); public static void main(string [] args) { SuperObject b = new SubObject(); b.paint(); Super Sub 예제 : Method Overriding Person 을상속받는 Professor 라는새로운클래스를만들고 Professor 클래스에서 getphone() 메소드를재정의하라. 그리고이메소드에서슈퍼클래스의메소드를호출하도록작성하라. class Person { String phone; public void setphone(string phone) { this.phone = phone; super.getphone() 은 public String getphone() { 아래 p.getphone() 과 return phone; 달리동적바인딩이 일어나지않는다. class Professor extends Person { public String getphone() { return "Professor : " + super.getphone(); public class Overriding { Professor a = new Professor(); a.setphone("011-123-1234"); System.out.println(a.getPhone()); Person p = a; System.out.println(p.getPhone()); Professor : 011-123-1234 Professor : 011-123-1234 동적바인딩에의해 Professor 의 getphone() 호출. Method Overloading vs Overriding 추상메소드와추상클래스 추상메소드 (abstract method) 선언되어있으나구현되어있지않은메소드 abstract 키워드로선언 ex) public abstract int getvalue(); 추상메소드는서브클래스에서오버라이딩하여구현 추상클래스 (abstract class) 1. 추상메소드를하나라도가진클래스 클래스앞에반드시 abstract라고선언해야함 2. 추상메소드가하나도없지만클래스앞에 abstract로선언한경우 추상클래스 추상메소드 abstract class DObject { public DObject next; public DObject() { next = null; abstract public void draw() ;
2 가지종류의추상클래스사례 추상클래스의인스턴스생성불가 // 추상메소드를가진추상클래스 abstract class DObject { // 추상클래스선언 public DObject next; public DObject() { next = null; abstract public void draw(); // 추상메소드선언 // 추상메소드없는추상클래스 abstract class Person { // 추상클래스선언 public String name; public Person(String name) { this.name = name; public String getname() { return name; abstract class DObject { // 추상클래스선언 public DObject next; public DObject() { next = null; abstract public void draw(); // 추상메소드선언 public class AbstractError { public static void main(string [] args) { DObject obj; obj = new DObject(); // 컴파일오류, 추상클래스 DObject 의인스턴스를생성할수없다. obj.draw(); // 컴파일오류 추상클래스의상속 추상클래스의상속 2 가지경우 추상클래스의단순상속 추상클래스를상속받아, 추상메소드를구현하지않으면서브클래스도추상클래스됨 서브클래스도 abstract로선언해야함 abstract class DObject { // 추상클래스 public DObject next; public DObject() { next = null; abstract public void draw(); // 추상메소드 abstract class Line extends DObject { // draw() 를구현하지않았기때문에추상클래스 public String tostring() { return "Line"; 추상클래스구현상속 서브클래스에서슈퍼클래스의추상메소드구현 ( 오버라이딩 ) 서브클래스는추상클래스아님 추상클래스의구현및활용예 class Line extends DObject { System.out.println( Line ); 추상클래스를상속받아추상메소드 draw() 를구현한클래스 abstract class DObject { public DObject next; public DObject() { next = null; abstract public void draw(); class Rect extends DObject { System.out.println( Rect ); class DObject { public DObject next; public DObject() { next = null; System.out.println( DObject draw ); 추상클래스로수정 class Circle extends DObject { System.out.println( Circle );
추상클래스의용도 설계와구현분리 서브클래스마다목적에맞게추상메소드를다르게구현 다형성실현 슈퍼클래스에서는개념정의 서브클래스마다다른구현이필요한메소드는추상메소드로선언 각서브클래스에서구체적행위구현 계층적상속관계를갖는클래스구조를만들때 예제 : Calculator 추상클래스 다음의추상클래스 Calculator 를상속받는 GoodCalc 클래스를작성하라. abstract class Calculator { public abstract int add(int a, int b); public abstract int subtract(int a, int b); public abstract double average(int[] a); 예제 : GoodCalc 클래스 다형성 (Polymorphism) class GoodCalc extends Calculator { public int add(int a, int b) { return a+b; public int subtract(int a, int b) { return a - b; public double average(int[] a) { double sum = 0; for (int i = 0; i < a.length; i++) sum += a[i]; return sum/a.length; public static void main(string [] args) { Calculator c = new GoodCalc(); System.out.println(c.add(2,3)); System.out.println(c.subtract(2,3)); System.out.println(c.average(new int [] {2,3,4)); 5-1 3.0 다형성 (polymorphism) 이란객체들의타입이다르면똑같은메시지가전달되더라도각객체의타입에따라서서로다른동작을하는것 (dynamic binding)
예제 : 다형성예시 class Shape { protected int x, y; System.out.println("Shape Draw"); class Rectangle extends Shape { private int width, height; System.out.println("Rectangle Draw"); class Triangle extends Shape { private int base, height; System.out.println("Triangle Draw"); 예시 : 다형성예시 class Circle extends Shape { private int radius; System.out.println("Circle Draw"); public class ShapeTest { public static void main(string arg[]) { Shape s1 = new Shape(); Shape s2 = new Rectangle(); Shape s3 = new Triangle(); Shape s4 = new Circle(); s1.draw(); Shape Draw s2.draw(); Rectangle Draw s3.draw(); Triangle Draw s4.draw(); Circle Draw 예시 : 다형성예시 public class ShapeTest2 { private static Shape arrayofshapes[]; public static void main(string arg[]) { arrayofshapes = new Shape[3]; arrayofshapes[0] = new Shape(); arrayofshapes[1] = new Rectangle(); arrayofshapes[2] = new Triangle(); arrayofshapes[3] = new Circle(); 자바의클래스계층구조 자바에서는모든클래스는반드시 java.lang.object 클래스를자동으로상속받는다. // 실행시객체의타입에맞는메소드를호출하는동적바인딩 (dynamic binding) for (int i = 0; i < arrayofshapes.length; i++) { arrayofshapes[i].draw(); Shape Draw Rectangle Draw Triangle Draw Circle Draw
Object 의메소드 Object 의메소드 class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; public class ObjectProperty { public static void main(string [] args) { Point p = new Point(2,3); System.out.println(p.getClass().getName()); System.out.println(p.hashCode()); System.out.println(p.toString()); System.out.println(p); Point 12677476 Point@c17164 Point@c17164 instanceof getclass() 메소드 객체의실제타입인지여부를반환한다. Shape s = getshape(); if (s instanceof Rectangle) { System.out.println("Rectangle 이생성되었습니다 "); else { System.out.println("Rectangle 이아닌다른객체가생성되었습니다 "); class Car {... public class CarTest { Car obj = new Car(); System.out.println("obj is of type " + obj.getclass().getname()); obj is of type Car obj is of type Car
equals() 메소드 class Car { private String model; public Car(String model) { this.model= model; public boolean equals(object obj) { if (obj instanceof Car) return model.equals(((car) obj).model); else return false; public class CarTest { Car firstcar = new Car("HMW520"); Car secondcar = new Car("HMW520"); Object 의 equals() 를재정의 if (firstcar.equals(secondcar)) { System.out.println(" 동일한종류의자동차입니다."); else { System.out.println(" 동일한종류의자동차가아닙니다."); 동일한 1부터 10종류의까지의자동차입니다정수의합 = 55. 객체비교 (== 과 equals()) 객체레퍼런스의동일성비교엔 == 연산자이용 객체내용비교 서로다른두객체가같은내용물인지비교 boolean equals(object obj) 이용 class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; c a b x=2 y=3 x=2 y=3 Point Point Point a = new Point(2,3); Point b = new Point(2,3); Point c = a; if(a == b) // false System.out.println("a==b"); if(a == c) // true System.out.println("a==c"); a==c 객체비교 (== 과 equals()) class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; public boolean equals(point p) { if(x == p.x && y == p.y) return true; else return false; a is equal to b Point a = new Point(2,3); Point b = new Point(2,3); Point c = new Point(3,4); if(a == b) // false System.out.println("a==b"); if(a.equals(b)) // true System.out.println("a is equal to b"); if(a.equals(c)) // false System.out.println("a is equal to c"); a b c x=2 y=3 x=2 y=3 x=3 y=4 Point Point Point 예시 : Rect 클래스 equals() int 타입의 width, height 의필드를가지는 Rect 클래스를작성하고, 두 Rect 객체의 width, height 필드에의해구성되는면적이같으면두객체가같은것으로판별하도록 equals() 를작성하라. Rect 생성자에서 width, height 필드를인자로받아초기화한다. class Rect { int width; int height; public Rect(int width, int height) { this.width = width; this.height = height; public boolean equals(rect p) { if (width*height == p.width*p.height) return true; else return false;
예시 : Rect 클래스 equals() public class EqualsEx { Rect a = new Rect(2,3); Rect b = new Rect(3,2); Rect c = new Rect(3,4); if(a.equals(b)) System.out.println("a is equal to b"); if(a.equals(c)) System.out.println("a is equal to c"); if(b.equals(c)) System.out.println("b is equal to c"); hashcode() 메소드 hashcode() 는해싱이라는탐색알고리즘에서필요한해시값을생성하는메소드이다. a is equal to b tostring() 메소드 Object 클래스의 tostring() 메소드는객체의문자열표현을반환한다. class Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; public String tostring() { return "Point(" + x + "," + y+ ")"; public class ObjectProperty { public static void main(string [] args) { Point a = new Point(2,3); System.out.println(a.toString()); Point(2,3) Object 의 tostring() 를재정의 System.out.println(a); 라고해도동일 tostring() 메소드사용 String tostring() 객체를문자열로반환 Object 클래스에구현된 tostring() 이반환하는문자열 클래스이름 @ 객체의 hash code 각클래스는 tostring() 을오버라이딩하여자신만의문자열리턴가능 컴파일러에의한자동변환 객체 + 문자열 -> 객체.toString() + 문자열 로자동변환 Point a = new Point(2,3); String s = a + " 점 "; System.out.println(s); 변환 Point a = new Point(2,3); String s = a.tostring()+ " 점 "; System.out.println(s.toString()); Point@c17164 점
IS-A 관계 is-a 관계 : ~ 은 ~ 이다 와같은관계 상속은 is-a 관계이다. HAS-A 관계 has-a 관계 : ~ 은 ~ 을가지고있다 와같은관계 자동차는탈것이다 (Car is a Vehicle). 강아지는동물이다 (Dog is a animal). 도서관은책을가지고있다 (Library has a book). 거실은소파를가지고있다 (Living room has a sofa). HAS-A 관계 HAS-A 관계의예제 객체지향프로그래밍에서 has-a 관계는구성관계 (composition) 또는집합관계 (aggregation) 를나타낸다.
예시 : Date 클래스 public class Date { private int year; private int month; private int date; public Date(int year, int month, int date) { this.year = year; this.month = month; this.date = date; @Override public String tostring() { return "Date [year=" + year + ", month=" + month + ", date=" + date + "]"; 예시 : Employee 클래스 has-a Date 클래스 public class Employee { private String name; private Date birthdate; public Employee(String name, Date birthdate) { this.name = name; this.birthdate = birthdate; @Override public String tostring() { return "Employee [name=" + name + ", birthdate=" + birthdate + "]"; 예시 : Employee 클래스 has-a Date 클래스 public class EmployeeTest { Date birth = new Date(1990, 1, 1); Employee employee = new Employee(" 홍길동 ", birth); System.out.println(employee); Employee [name= 홍길동, birthdate=date [year=1990, month=1, date=1]] 정적메소드오버라이딩 부모클래스의메소드중에서정적메소드를재정의 ( 오버라이드 ) 하면부모클래스객체에서호출되느냐아니면자식클래스에서호출되느냐에따라서호출되는메소드가달라진다. public class Animal { public static void eat() { System.out.println("Animal의정적메소드 eat()"); public void sound() { System.out.println("Animal의인스턴스메소드 sound()");
정적메소드오버라이딩 public class Cat extends Animal { public static void eat() { System.out.println("Cat의정적메소드 eat()"); public void sound() { System.out.println("Cat의인스턴스메소드 sound()"); Cat mycat = new Cat(); Cat.eat(); Animal myanimal = mycat; Animal.eat(); Cat의정적메소드 eat() myanimal.sound(); Animal의정적메소드 eat() Cat의인스턴스메소드 sound()