JAVA – kompozycja a dziedziczenie
class Point { int x,y;
Point() {x =0; y = 0;}
Point(int x, int y) { this.x = x; this.y = y; }
boolean equals( Point p) { // przesłonięcie equals z klasy Object if ( (this.x == p.x) && (this.y == p.y) ) return true; else return false; } // porównuje współrzędne a nie adresy }
class StringAtPoint {
Point p; // kompozycja
String s; // kompozycja
StringAtPoint() {p = new Point(); s = new String(); } StringAtPoint( Point p, String s) { this.p = p; this.s = s; } void isStringAtPoint( Point p) {
if ( (this.p).equals(p) ) System.out.println(" Yes "); // bez przesłonięcia equals else System.out.println(" No "); } // będzie porównywać referencje void changeStringAtPoint( String s) { this.s = s; }
JAVA – kompozycja a dziedziczenie
public class Prog27 {
public static void main(String [] arg) {
StringAtPoint first = new StringAtPoint();
Point p1 = new Point(); // domyślny a więc x == 0 i y == 0 Point p2 = new Point(2,3);
System.out.println(p1 == first.p); // false, porównuje referencje StringAtPoint second = new StringAtPoint(p2,"second");
first.changeStringAtPoint("first");
second.isStringAtPoint(p1); // bez przesłonięcia No z przesłonięciem-> No second.isStringAtPoint(p2); // bez przesłonięcia Yes z przesłonięciem-> Yes first.isStringAtPoint(p1); // bez przesłonięcia No z przesłonięciem-> Yes } } //Prog27
kompozycja
Obiekt klasy X zawiera w sobie obiekt klasy Y dziedziczenie
Obiekt klasy X jest rodzajem obiektu klasy Y
JAVA – dziedziczenie, składnia
class Point { int x,y;
Point() {x =0; y = 0;}
Point(int x, int y) {this.x = x; this.y = y; }
Point(Point p) {this.x = p.x; this.y = p.y; } // konstruktor kopiujący void name() {System.out.println("klasa Point");}
}
class StringAtPoint extends Point{ // teraz dziedziczy z Point
String s; // kompozycja
StringAtPoint() {super(); s = new String(); } // super woła konstruktora klasy macierzystej
// Point(), super() może być dołożony automatycznie StringAtPoint(int x, int y, String s) {super(x,y); this.s = s; }
StringAtPoint( Point p, String s) {super(p); this.s = s; } // super woła konstruktora kopiującego Point(Point) StringAtPoint(String s) {this(); this.s = s; } // this() to wywołanie konstruktora StringAtPoint();
void isStringAtPoint( Point p) { if ( (x == p.x) && (y == p.y) ) System.out.println(" Yes ");
else System.out.println(" No "); }
void changeStringAtPoint( String s) { this.s = s; }
void name() {super.name(); // przesłonięcie i odwołanie do metody name System.out.println("klasa StringAtPoint");} // klasy macierzystej
JAVA – dziedziczenie
public class Prog28 {
public static void main(String [] arg) {
StringAtPoint first = new StringAtPoint();
Point p1 = new Point();
Point p2 = new Point(2,3);
StringAtPoint second = new StringAtPoint(p2,"second");
StringAtPoint third = new StringAtPoint(" third ");
first.changeStringAtPoint("first");
second.isStringAtPoint(p1); //-> No second.isStringAtPoint(p2); //-> Yes first.isStringAtPoint(p1); //-> Yes third.isStringAtPoint(p1); //-> Yes
second.name();
super class (klasa macierzysta, bazowa)
subclass (klasa pochodna)
class One {
void s() { System.out.println(" I'm One");}}
class Two extends One{
void s() { super.s(); System.out.println(" I'm Two");}}
class Three extends Two{
void s() { super.s(); System.out.println(" I'm Three");}}
public class HowThis {
public static void main(String [] arg) { Three t = new Three();
t.s(); // I'm One, I'm Two, I'm Three
JAVA – dziedziczenie
class BoxInt { int x;
BoxInt() { this(0); } BoxInt(int x) { this.x = x;}
int returnFromBoxInt() { return x; } }
class NboxInt extends BoxInt { static int i;
int nr;
NboxInt() { super(); nr = i++; } NboxInt(int x) { super(x); nr = i++; } int returnFromBoxInt(int n) {
return nr; } // przeciążenie metody klasy bazowej }
class SboxInt extends NboxInt { String s;
SboxInt() { super(); s = new String(); } SboxInt(int x, String s) { super(x); this.s = s; } String returnFromBoxString() { return s; } }
public class Prog29 {
public static void main(String [] arg) {
SboxInt a = new SboxInt();
SboxInt b = new SboxInt(3,"b");
System.out.println(a.returnFromBoxInt()); // - > 0 System.out.println(b.returnFromBoxInt()); // - > 3 System.out.println(a.returnFromBoxInt(0)); // - > 0 System.out.println(b.returnFromBoxInt(0)); // - > 1 System.out.println(a.returnFromBoxString()); // - >
System.out.println(b.returnFromBoxString()); // - > b }
} //Prog29
JAVA – dziedziczenie, kolejność inicjalizacji
// zmienna statyczna a klasy bazowej jest inicjalizowana jako pierwsza
// ponieważ wartości pól w klasie pochodnej mogą zależeć od pól klasy bazowej class First {
static int a;
First() {a = 5;}
int getValue() { return a+2;}
}
class Second extends First { static int b;
Second() { b = getValue(); } // można jawnie this.getValue();
}
public class Prog32 {
public static void main(String [] arg) { Second s = new Second();
System.out.println(s.a); // - > 5 System.out.println(s.b); // - > 7
JAVA – dziedziczenie i dostęp protected
package kb.ath.library;
public class XY { protected int x,y;
public XY() { this(0,0);}
public XY(int x, int y) { this.x = x; this.y = y;}
protected void clearXY() {x=0; y=0;} }
import kb.ath.library.XY;
class XYZ extends XY{
private int z;
public XYZ() { this(0,0,0);}
public XYZ(int x, int y, int z) { super(x,y); this.z = z;}
private void clearXYZ() {super.clearXY(); z=0;}
void showXYZ() {
System.out.println(x + " " + y + " " + z); } void eraseXYZ() { clearXYZ(); }
} import kb.ath.library.XY;
public class Prog33 {
public static void main(String [] arg) { XY p1 = new XY(1,2);
// p1.clearXY(); // brak dostępu XYZ p2 = new XYZ(1,2,4);
p2.showXYZ();
// p2.clearXYZ(); // brak dostępu p2.eraseXYZ(); p2.showXYZ();
}} //Prog33
JAVA – kiedy nie działa dostęp protected
//pakiet domyślny class XY { protected int x,y;
public XY() { this(0,0);}
public XY(int x, int y) { this.x = x; this.y = y;}
protected void clearXY() {x=0; y=0;}
}
public class Prog34 {
public static void main(String [] arg) { XY p1 = new XY(1,2);
p1.clearXY(); // działa p1.x = 5; // działa System.out.println(" End");
} } //Prog34
import kb.*;
public class Prog34 {
public static void main (String [] arg) { XYbis a = new XYbis();
a.changeXY(); // też działa } } //Prog34
package kb;
public class XY { protected int x,y;
public XY(int x, int y) { this.x = x; this.y = y;}
protected void clearXY() {x=0; y=0;}}
package kb;
public class XYbis { XY a = new XY(2,3);
public void changeXY() { a.x = 5; }}
JAVA – rzutowanie w górę
class Shape { float area,perim;
Shape() {}
Shape(float x, float y) { area = x; perim = y; } void describeShape() {
System.out.println(" area = "
+ area + " perim = " + perim); } }
class Rectangle extends Shape { String color;
Rectangle() {} // sam wywoła Shape() Rectangle(float x, float y, String s) { super(x,y); color = s; }
void describeRectangle() {
System.out.println(area + " " + perim + " " + color); }
}
public class Prog30 {
static void isShape(Shape s) {
System.out.println(" jest typu shape ? " + (s instanceof Shape) ); } public static void main(String [] arg) {
Shape s = new Shape(3.1f,4.2F);
Rectangle r = new Rectangle(2.1f,5.2F, " blue ");
s.describeShape();
r.describeRectangle();
r.describeShape(); // rzutowanie w górę
Prog30.isShape(s); //-> true Prog30.isShape(r); // rzutowanie w górę //-> true
s = r; // rzutowanie w górę
}} //Prog30
JAVA – modyfikator final
przed nazwą zmiennej class Third {
final int a = 5;
public static final float F_CONST = 3.5f;
final double d;
final double g = Math.random();
final int [] t1 = {1,2,3,4,5};
final int [] t2;
// inicjalizacja zmiennych ostatecznych Third(double x, int [] y) {d = x; t2 = y; } przed argumentem metody
void changeT(final int x) {
// x++; } // argument ostateczny nie podlega zmianie }
a, F_CONST – stałe czasu kompilacji; d-pusta zmienna ostateczna; t1-stała referencja F_CONST musi być definiowana i inicjalizowana jednocześnie
public class Prog31 {
public static void main(String [] arg) { int [] tab = {0,1,0,2};
Third th = new Third(3.14,tab);
System.out.println(th.t2[3]); // -> 2 //th.a = 2; // nie można System.out.println(th.d); // -> 3.14
th.t1[0] = 9; // można zmienić wartość //th.t1 = tab; // referencja jest stała }
} //Prog31
JAVA – modyfikator final
przed definicją klasy final class Shape { //...//}
//class Rectangle extends Shape { // nie można dziedziczyć z klasy final // ...//
//}
przed definicją metody class First {
final void getFirst() {} // zadziała podobnie jak inline w C++ ale nie można jej przesłonić }
class Second extends First {
// void getFirst() {} // nie można przesłonić }
Metody prywatne klasy stają się pośrednio final
JAVA – polimorfizm
class Shape {
public double area() { return 0.0;}
public double perim() { return 0.0;}
}
class Square extends Shape { double b;
Square(double x) { b = x; }
public double area() { return b*b; } public double perim() { return 4 * b; } }
class Rectangle extends Shape { double a,b;
Rectangle(double x, double y) { a = x; b =y;}
public double area() { return a*b; } public double perim() { return 2*a+2*b; } }
public class Prog35 {
public static void main (String [] arg) {
Shape [] tab = {new Square(3), new Rectangle(1,2)};
System.out.print(" Square : ");
System.out.println(" area = " + tab[0].area() + " perim = " + tab[0].perim());
System.out.print(" Rectangle : ");
System.out.println(" area = " + tab[1].area() + " perim = " + tab[1].perim());
}
} //Prog35
JAVA – polimorfizm
class Animals {
boolean hungry = true;
Animals() {}
public String song() { if (hungry) return " ???????? ";
else return " OK " ;}
public void change() { hungry = !hungry; } }
class Dog extends Animals {
public String song() {//przesłonięcie if (hungry) return " wow wow wow ";
else return " woooooow " ;}
}
class Cat extends Animals {
public String song() { //przesłonięcie if (hungry) return " miau miau miau ";
else return " miauuuuu " ;}
}
public class Prog36 {
public static void main (String [] arg) { Animals [] collection = new Animals [6];
collection [0] = new Dog();
collection [1] = new Cat();
collection [2] = new Animals();
for(int i =0; i< 3; i++) System.out.println( collection[i].song() );
// " wow wow wow „ // " miau miau miau „ // " ?????????????? "
System.out.println(" teraz zmiana ");
for(int i =0; i< 3; i++) { collection[i].change();
System.out.println( collection[i].song() ); } // " woooooooow „ // " miauuuuuuu „ // " OK "
}
} //Prog36
JAVA – klasy i metody abstrakcyjne
abstract class Shape {
abstract public double area();
abstract public double perim();
}
class Square extends Shape { double b;
Square(double x) { b = x; }
public double area() { return b*b; } // każda metoda abstrakcyjna public double perim(){ return 0.0;} // musi być implementowana
} // w klasie pochodnej
public class Prog37 {
public static void main (String [] arg) {
// Shape s = new Shape(); //klasa abstrakcyjna nie ma instancji Shape tab = new Square(3); // można rzutować
System.out.println(tab.area());
}
abstract class Shape {
public double area(){ return 0.0;}
public double perim(){ return 0.0;}
}
klasa abstrakcyjna nie musi posiadać metod abstrakcyjnych
abstract class Shape {
public double area(){ return 0.0;}
abstract public double perim();
}
w klasie abstrakcyjnej mogą być metody zwykłe
klasa posiadająca metodę abstrakcyjną musi być definiowana jako abstrakcyjna
JAVA – interfejsy
interface Shape {
double area(); // automatycznie public double perim();
String whoI();
}
class Square implements Shape { private double a;
Square(double n ) { a = n;}
public double area() {return a*a;} // wymagane public public double perim() {return 4*a;} // dla metod
public String whoI() {return "Square";} // dziedziczonych } // z intefejsu class Rectangle implements Shape {
private double a,b;
Rectangle(double x, double y){a = x; b = y;}
public double area() {return a*b;}
public double perim() {return 2*a+2*b;}
public String whoI() {return "Rectangle";}
}
public class Prog41 {
public static void main(String [] arg) { Square s = new Square(2);
Rectangle r = new Rectangle(3,1);
Shape t = s; // na interfejs można rzutować
System.out.println(t.whoI()); // późne wiązanie // dalej działa }
} //Prog41
JAVA – dziedziczenie interfejsów
interface OriginPoint {
double originX = 0.0d; // automatycznie static i final double originY = 0.0d;
public double distanceToOrigin();
}
interface Shape { public double area();
public double perim();
public String whoI();
}
//dziedziczenie interfejsu
interface ShapeCP extends Shape { public void setCP(double x, double y);
public void viewCP();
}
// implementacja wielu interfejsów
class Square implements ShapeCP, OriginPoint { private double a,xc,yc;
Square(double n ) { a = n;}
public double area() {return a*a;}
public double perim() {return 4*a;}
public String whoI() {return "Square";}
public void setCP(double x, double y){xc = x; yc = y; };
public void viewCP(){ System.out.println("Center at " + xc +
" : " + yc); }
public double distanceToOrigin() {
return Math.sqrt(Math.pow(xc-originX,2.0)+
Math.pow(yc-originY,2.0));};
}
JAVA – interfejsy
class Rectangle implements ShapeCP, OriginPoint { private double a,b,xc,yc;
Rectangle(double x, double y){a = x; b = y;}
public double area() {return a*b;}
public double perim() {return 2*a+2*b;}
public String whoI() {return "Rectangle";}
public void setCP(double x, double y){xc = x; yc = y; } public void viewCP(){
System.out.println("Center at " + xc + " : " + yc); } public double distanceToOrigin() {
return Math.sqrt(Math.pow(xc-originX,2.0)+
Math.pow(yc-originY,2.0));}
}
public class Prog42 {
public static void main(String [] arg) { Square s = new Square(2);
Rectangle r = new Rectangle(3,1);
s.setCP(1,1);
r.setCP(5,5);
ShapeCP t1 = s; // na interfejs można rzutować
t1.viewCP(); // późne wiązanie ShapeCP t2 = r;
t2.viewCP(); // późne wiązanie
// t1 i t2 nie można użyć bo ShapeCP nie zna metody // distanceToOrigin()
if (s.distanceToOrigin() > r.distanceToOrigin())
System.out.println(r.whoI() + " jest bliżej niż " + s.whoI());
else System.out.println(s.whoI() + " jest bliżej niż " + r.whoI());
JAVA – interfejsy definiowane wewnątrz klas
class Point { double x,y;
interface OriginPoint { double originX = 0.0;
double originY = 0.0;
public double distanceToOrigin();
void f();
}
Point(double a, double b) { x = a; y = b;}
double distanceToOrigin() { return Math.sqrt(Math.pow(x-OriginPoint.originX,2.0) // pełny dostęp +Math.pow(y-OriginPoint.originY,2.0));} // jest wymagany // void f(){} // nie trzeba definiować metod !!!
}
public class Prog43 {
public static void main(String [] arg) { Point p = new Point(3,0);
System.out.println(p.distanceToOrigin());
}
JAVA – interfejsy wewnątrz interfejsów poza klasami
interface OriginPoint { interface Origin{
boolean isInOrigin();
void f(); }
double originX = 0.0;
double originY = 0.0;
public double distanceToOrigin();
}
class Point implements OriginPoint{
double x,y;
Point(double a, double b) {x = a; y = b;}
public double distanceToOrigin() { // musi być publiczna
return Math.sqrt(Math.pow(x-originX,2.0) + Math.pow(y-originY,2.0));}
boolean isInOrigin() { return( (x==originX) && (y==originY));}
//void f() {} // dla interfejsów wewnątrz interfejsów nie trzeba } // definiować wszystkich metod
public class Prog44 {
public static void main(String [] arg) { Point p = new Point(3,0);
System.out.println(p.distanceToOrigin());
Point s = new Point(0,0);
if(s.isInOrigin()) System.out.println("Yes");
else System.out.println("No");
}} //Prog44
JAVA – interfejsy wewnątrz interfejsów w klasach
class Point { double x,y;
interface OriginPoint { interface Origin{
boolean isInOrigin();
void f(); }
double originX = 0.0;
double originY = 0.0;
public double distanceToOrigin();
}
Point(double a, double b) { x = a; y = b;}
double distanceToOrigin() { // teraz !!! może być chroniona!!!
return Math.sqrt(Math.pow(x-OriginPoint.originX,2.0) // pełny dostęp +Math.pow(y-OriginPoint.originY,2.0));} // jest wymagany
boolean isInOrigin() { return( (x==OriginPoint.originX) && (y==OriginPoint.originY));}
//void f() {} // dla interfejsów wewnątrz klasy nie trzeba } // definiować wszystkich metod
public class Prog45 {
public static void main(String [] arg) { Point p = new Point(3,0);
System.out.println(p.distanceToOrigin());
Point s = new Point(0,0);
if(s.isInOrigin()) System.out.println("Yes");
else System.out.println("No");
}} //Prog45
JAVA – klasy wewnętrzne
interface Setvalue { void setvalue(int x);
}
class OutClass { int a = 2;
public void setvalue(int x){a=10*x;} // zwykła metoda, wersja 1 IntClass k = new IntClass();
class IntClass implements Setvalue{
public void setvalue(int x){a=x;} // metoda klasy wewnętrznej } // zgodnie z interfejsem } // wersja 2
public class Prog46 {
OutClass2 o = new OutClass2();
public static void main(String [] arg) { OutClass p = new OutClass();
System.out.println(p.a);
p.setvalue(3); // wersja1 System.out.println(p.a);
p.k.setvalue(1); // wersja 2 System.out.println(p.a);
}
} //Prog46
klasa wewnętrzna ma dostęp do pól klasy w której została zdefiniowana
JAVA – klasy wewnętrzne prywatne i dziedziczące
class OnlyInt{
int a = 2;
}
class OutClass2 { int x;
private class IntClass { int value;
}
class IntClass2 extends OnlyInt{
void setInt(int v){a=v;}
}
IntClass i = new IntClass();
// instancja klasy wewnętrznej }// OutClass2
public class Prog47 {
OutClass2 o = new OutClass2();
public static void main(String [] arg) { OutClass2 p2 = new OutClass2();
p2.i.value = 2; // klasa zewnętrzna może dostać się do składnika nie private klasy wewnętrznej Prog47 g = new Prog47();
g.o.i.value = 2; // !!!!!! klasa z tego samego pakietu też !!!!!!
OutClass2.IntClass2 w = p2.new IntClass2(); // dla nie private
// instancja klasy wewnętrznej
w.setInt(8); // metoda tej klasy
System.out.println(w.a); // pole tej klasy
// OutClass2.IntClass s = p2.new IntClass(); // prywatna, nie można
JAVA – klasy wewnętrzne
import kb.OutClass2;
public class Prog48 {
OutClass2 o = new OutClass2();
public static void main(String [] arg) {
OutClass2 p2 = new OutClass2();
// p2.i.value = 2; // nie ma dostępu do instancji klasy // wewnętrznej – chroniona pakietem Prog48 g = new Prog48();
// g.o.i.value = 2; // chroniona pakietem // OutClass2.IntClass w = p2.new IntClass();
// klasa wewnętrzna jest prywatna }
} //Prog48 // plik kb\OutClass2
package kb;
public class OutClass2 { int x;
private class IntClass { int value;
}
IntClass i = new IntClass();
}
JAVA – klasy wewnętrzne przykład
class Master { int aM;
Slave s;
Master(int x) { aM = x; s = new Slave();}
void giveMaster(int x) { aM = x;}
void viewSlave() {System.out.println("Slave a = " + s.aS);}
class Slave { int aS;
Slave() {aS = aM;}
}
void rememberSlave() {s.aS = aM;}
}
public class Prog49 {
public static void main(String [] arg) {
Master m = new Master(3);
m.viewSlave(); //--> 3
m.giveMaster(5);
m.viewSlave(); //--> 3 m.rememberSlave();
m.viewSlave(); //--> 5 }
} //Prog49
JAVA – klasy wewnętrzne w metodach i blokach
import java.util.*;
class BC { int baytcode;
int give() { return baytcode;}
}
class Command { int code;
Command(int x) { code = x; } BC c;
void runCommand() {
class CommandHandle extends BC{
CommandHandle() {baytcode = code*10; c = this;}
} new CommandHandle();
}
void whatIsRunning() {
class CommandHandle extends BC{
CommandHandle() {baytcode = c.give()/10;
System.out.println("CmRun " + baytcode + " started at " + new Date()); } } new CommandHandle();
}
public class Prog50 {
public static void main(String [] arg) {
Command m = new Command(30);
m.runCommand();
m.whatIsRunning();
m.runCommand();
{
tutaj też można zdefiniować klasę }
}} //Prog50
JAVA – anonimowe klasy wewnętrzne
public class Prog51 {
public Enumerator make() {
return new Enumerator() { // anonimowa klasa wewnętrzna int j = 5;
int Jamp() {return ++j;} //przysłonięcie }; //koniecznie !!!!
}
public Nothing use(final int x) { // argument musi być final return new Nothing(x) {
int n = x;
}; //koniecznie !!!!
}
public static void main(String [] arg) {
Prog51 a = new Prog51();
Enumerator e = a.make();
System.out.println(e.Jamp()); //--> 6 Nothing n = a.use(2); //--> 2
class Enumerator { int f =0;
int Jamp() {return f;}
}
class Nothing { int n;
Nothing(int x) { n = x;}
int give() {return n;}
}
JAVA – klasy anonimowe
class Enumerator { int f =0;
int Jamp() {return f;}
}
public class Prog52 {
public static void main(String [] arg) {
Prog52 a = new Prog52();
Enumerator e = new Enumerator() { int j = 5;
int Jamp() {return ++j;} //przysłonięcie }; //koniecznie !!!!
Enumerator c = new Enumerator();
System.out.println(c.Jamp()); // 0 System.out.println(e.Jamp()); // 6 System.out.println(e.f); // 0
JAVA – statyczne klasy wewnętrzne
interface Side {
static class InSide { // klasa taka może być definiowana int k = 20; // w przestrzeni nazwy interfejsu;
int returnS() { return k;}
}
InSide giveInSide();
int returnI();
}
class Out { int value = 5;
static class Iner implements Side{
int i = 10;
//int j = value; // wewnętrzna klasa statyczna nie ma dostępu do zewnętrznej public int returnI () { return i ;} // implementacja funkcji z interfejsu
public InSide giveInSide() { return new InSide();}
}
// funkcja zwracająca referencję do obiektu klasy wewnętrznej public static Iner giveIner() {return new Iner();}
}
public class Prog53 {
public static void main(String [] arg) {
// wywołanie metody statycznej , klas wewnętrzna jest rzutowana do Side
Side ob = Out.giveIner();
System.out.println(ob.returnI()); // --> 10 int whatIsK = (ob.giveInSide()).returnS();
System.out.println(whatIsK); // --> 20 } } //Prog53
JAVA – kolekcje obiektów, klasa Arrays
import java.util.Arrays;
public class Prog54 {
static void print(int [] x) { for(int i =0; i < x.length; i++) System.out.print(x[i]); System.out.println(); } public static void main( String [] arg) {
int a[] = {5,3,2,4,6,9,0};
int b[] = new int [7];
System.arraycopy(a,0,b,0,a.length); // kopiowanie szybsze niż własna implementacja boolean isEqual = Arrays.equals(a,b);
System.out.println(isEqual); //--> true Arrays.sort(a);
Prog54.print(a); //--> 0,2,3,4,5,6,9 isEqual = Arrays.equals(a,b);
System.out.println(isEqual); // --> false Arrays.fill(a,2);
Prog54.print(a); //--> 2,2,2,2,2,2,2 Arrays.sort(b);
int position = Arrays.binarySearch(b,4); // można korzystać dopiero po sort System.out.println(position); //--> 3
} } //Prog54
JAVA –Arrays a tablice obiektów własnych typów
import java.util.Arrays;
class Duo implements Comparable{ // pierwszy sposób rozwiązania problemu porównywania obiektów int i; int j; // rozwiązanie jako metoda klasy
Duo(int x, int y) { i = x; j = y;}
public int compareTo (Object t) { // - 1 jeśli mniejszy, 0 jeśli są równe, 1 jeśli większy int ti = ((Duo)t).i; int tj = ((Duo)t).j;
return ( (i*j) < (ti*tj) ? -1 : ( ((i == ti) && (j == tj)) ? 0 : 1 ));
}
public void print(Duo [] f) { for(int i = 0; i < f.length; i++) System.out.print("\t"+ f[i].i + ":" + f[i].j);
System.out.println(); }}//Duo public class Prog55 {
public static void main(String [] arg) {
Duo [] d1 = new Duo [] { new Duo(4,4), new Duo(2,2), new Duo(1,1), new Duo(3,3)};
Duo [] d2 = new Duo [] { new Duo(1,1), new Duo(2,2), new Duo(3,3), new Duo(4,4)};
d1[0].print(d1); //--> 4:4 2:2 1:1 3:3 Arrays.sort(d1);
d1[0].print(d1); //--> 1:1 2:2 3:3 4:4
boolean isEqual = Arrays.equals(d1,d2);
System.out.println(isEqual); // false bo porównuje referencje, można przesłonić }} //Prog55
JAVA – Arrays a tablice obiektów własnych typów
import java.util.Arrays;
import java.util.Comparator; // drugi sposób rozwiązania problemu porównywania obiektów // dodatkowa klasa definiująca komparator
class DuoComparator implements Comparator { public int compare (Object t1, Object t2) { int i = ((Duo)t1).i; int j = ((Duo)t1).j;
int ti = ((Duo)t2).i; int tj = ((Duo)t2).j;
return ( (i*j) < (ti*tj) ? -1 : ( ((i == ti) && (j == tj)) ? 0 : 1 ));
} }
class Duo { int i; int j;
Duo(int x, int y) { i = x; j = y;}
public void print(Duo [] f) { for(int i = 0; i < f.length; i++) System.out.print("\t"+ f[i].i + ":" + f[i].j);
System.out.println(); }}//Duo public class Prog56 {
public static void main(String [] arg) { //...jak wcześniej w Prog55
Arrays.sort(d1,new DuoComparator());
}