initial commit
This commit is contained in:
59
src/oop/ch01/chess1/Board.java
Normal file
59
src/oop/ch01/chess1/Board.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package oop.ch01.chess1;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Board {
|
||||
ArrayList<Piece> pieces;
|
||||
|
||||
Board() {
|
||||
this.pieces = new ArrayList<Piece>();
|
||||
}
|
||||
|
||||
void add(Piece piece) {
|
||||
if (piece.board != this)
|
||||
throw new IllegalArgumentException("wrong board");
|
||||
final Piece existing = this.pieceAt(piece.row, piece.col);
|
||||
if (existing != null)
|
||||
throw new IllegalArgumentException("already occupied by " +
|
||||
existing.toString());
|
||||
this.pieces.add(piece);
|
||||
}
|
||||
|
||||
void printBoard() {
|
||||
System.out.println(" 1 2 3 4 5 6 7 8");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
for (int row = 1; row <= 8; row++) {
|
||||
System.out.print("" + row + " ");
|
||||
for (int col = 1; col <= 8; col++) {
|
||||
final Piece p = this.pieceAt(row, col);
|
||||
final char c = p == null ? ' ' : p.charRep();
|
||||
System.out.print("| " + c + " ");
|
||||
}
|
||||
System.out.println("|");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
}
|
||||
}
|
||||
|
||||
Piece pieceAt(int row, int col) {
|
||||
for (Piece p : this.pieces)
|
||||
if (p.row == row && p.col == col)
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
void check() {
|
||||
for (Piece p1 : this.pieces) {
|
||||
System.out.println(p1.toString());
|
||||
for (Piece p2 : this.pieces)
|
||||
if (p1 != p2)
|
||||
if (p1.canCapture(p2))
|
||||
System.out.println(" can capture " + p2.toString());
|
||||
else
|
||||
System.out.println(" cannot capture " + p2.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "pieces: " + this.pieces;
|
||||
}
|
||||
}
|
15
src/oop/ch01/chess1/Chess.java
Normal file
15
src/oop/ch01/chess1/Chess.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch01.chess1;
|
||||
|
||||
class Chess {
|
||||
public static void main(String[] args) {
|
||||
final Board board = new Board();
|
||||
final Piece p1 = new Piece(Kind.queen, Color.black, board, 1, 4);
|
||||
final Piece p2 = new Piece(Kind.queen, Color.white, board, 8, 4);
|
||||
final Piece p3 = new Piece(Kind.knight, Color.white, board, 3, 3);
|
||||
final Piece p4 = new Piece(Kind.knight, Color.black, board, 6, 4);
|
||||
System.out.println(board);
|
||||
System.out.println(board.toString());
|
||||
board.printBoard();
|
||||
board.check();
|
||||
}
|
||||
}
|
5
src/oop/ch01/chess1/Color.java
Normal file
5
src/oop/ch01/chess1/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch01.chess1;
|
||||
|
||||
enum Color {
|
||||
black, white
|
||||
}
|
5
src/oop/ch01/chess1/Kind.java
Normal file
5
src/oop/ch01/chess1/Kind.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch01.chess1;
|
||||
|
||||
enum Kind {
|
||||
queen, knight
|
||||
}
|
87
src/oop/ch01/chess1/Piece.java
Normal file
87
src/oop/ch01/chess1/Piece.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package oop.ch01.chess1;
|
||||
|
||||
import static java.lang.Integer.signum;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
class Piece {
|
||||
Kind kind;
|
||||
Color color;
|
||||
Board board;
|
||||
int row;
|
||||
int col;
|
||||
|
||||
Piece(Kind kind, Color color, Board board, int row, int col) {
|
||||
if (row < 1 || row > 8 || col < 1 || col > 8)
|
||||
throw new IllegalArgumentException("Invalid pos " + row + "/" + col);
|
||||
this.kind = kind;
|
||||
this.color = color;
|
||||
this.board = board;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
board.add(this);
|
||||
}
|
||||
|
||||
char charRep() {
|
||||
return switch (this.kind) {
|
||||
case queen -> this.queenCharRep();
|
||||
case knight -> this.knightCharRep();
|
||||
};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return switch (this.kind) {
|
||||
case queen -> this.queenToString();
|
||||
case knight -> this.knightToString();
|
||||
};
|
||||
}
|
||||
|
||||
boolean canCapture(Piece other) {
|
||||
return switch (this.kind) {
|
||||
case queen -> this.queenCanCapture(other);
|
||||
case knight -> this.knightCanCapture(other);
|
||||
};
|
||||
}
|
||||
|
||||
char queenCharRep() {
|
||||
return this.color == Color.white ? 'q' : 'Q';
|
||||
}
|
||||
|
||||
char knightCharRep() {
|
||||
return this.color == Color.white ? 'n' : 'N';
|
||||
}
|
||||
|
||||
String queenToString() {
|
||||
return "" + this.color + " queen at (" + this.row + ", " + this.col + ")";
|
||||
}
|
||||
|
||||
String knightToString() {
|
||||
return "" + this.color + " knight at (" + this.row + ", " + this.col + ")";
|
||||
}
|
||||
|
||||
boolean queenCanCapture(Piece other) {
|
||||
if (this.board != other.board || this.color == other.color)
|
||||
return false;
|
||||
if (other.row != this.row &&
|
||||
other.col != this.col &&
|
||||
abs(other.row - this.row) != abs(other.col - this.col))
|
||||
return false;
|
||||
final int dr = signum(other.row - this.row);
|
||||
final int dc = signum(other.col - this.col);
|
||||
int r = this.row + dr;
|
||||
int c = this.col + dc;
|
||||
while (r != other.row || c != other.col) {
|
||||
if (this.board.pieceAt(r, c) != null) return false;
|
||||
r += dr;
|
||||
c += dc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean knightCanCapture(Piece other) {
|
||||
if (this.board != other.board || this.color == other.color)
|
||||
return false;
|
||||
final int dr = abs(this.row - other.row);
|
||||
final int dc = abs(this.col - other.col);
|
||||
return dr == 2 && dc == 1 || dr == 1 && dc == 2;
|
||||
}
|
||||
}
|
4
src/oop/ch01/chess1/package-info.java
Normal file
4
src/oop/ch01/chess1/package-info.java
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Using objects with methods for the Java solution of the chess problem.
|
||||
*/
|
||||
package oop.ch01.chess1;
|
59
src/oop/ch01/chess2/Board.java
Normal file
59
src/oop/ch01/chess2/Board.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package oop.ch01.chess2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Board {
|
||||
ArrayList<Piece> pieces;
|
||||
|
||||
Board() {
|
||||
this.pieces = new ArrayList<Piece>();
|
||||
}
|
||||
|
||||
void add(Piece piece) {
|
||||
if (piece.board != this)
|
||||
throw new IllegalArgumentException("wrong board");
|
||||
final Piece existing = pieceAt(piece.row, piece.col);
|
||||
if (existing != null)
|
||||
throw new IllegalArgumentException("already occupied by " +
|
||||
existing.toString());
|
||||
pieces.add(piece);
|
||||
}
|
||||
|
||||
void printBoard() {
|
||||
System.out.println(" 1 2 3 4 5 6 7 8");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
for (int row = 1; row <= 8; row++) {
|
||||
System.out.print("" + row + " ");
|
||||
for (int col = 1; col <= 8; col++) {
|
||||
final Piece p = pieceAt(row, col);
|
||||
final char c = p == null ? ' ' : p.charRep();
|
||||
System.out.print("| " + c + " ");
|
||||
}
|
||||
System.out.println("|");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
}
|
||||
}
|
||||
|
||||
Piece pieceAt(int row, int col) {
|
||||
for (Piece p : pieces)
|
||||
if (p.row == row && p.col == col)
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
void check() {
|
||||
for (Piece p1 : pieces) {
|
||||
System.out.println(p1.toString());
|
||||
for (Piece p2 : pieces)
|
||||
if (p1 != p2)
|
||||
if (p1.canCapture(p2))
|
||||
System.out.println(" can capture " + p2.toString());
|
||||
else
|
||||
System.out.println(" cannot capture " + p2.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return pieces.toString();
|
||||
}
|
||||
}
|
15
src/oop/ch01/chess2/Chess.java
Normal file
15
src/oop/ch01/chess2/Chess.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch01.chess2;
|
||||
|
||||
class Chess {
|
||||
public static void main(String[] args) {
|
||||
final Board board = new Board();
|
||||
final Piece p1 = new Piece(Kind.queen, Color.black, board, 1, 4);
|
||||
final Piece p2 = new Piece(Kind.queen, Color.white, board, 8, 4);
|
||||
final Piece p3 = new Piece(Kind.knight, Color.white, board, 3, 3);
|
||||
final Piece p4 = new Piece(Kind.knight, Color.black, board, 6, 4);
|
||||
System.out.println(board);
|
||||
System.out.println(board.toString());
|
||||
board.printBoard();
|
||||
board.check();
|
||||
}
|
||||
}
|
5
src/oop/ch01/chess2/Color.java
Normal file
5
src/oop/ch01/chess2/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch01.chess2;
|
||||
|
||||
enum Color {
|
||||
black, white
|
||||
}
|
5
src/oop/ch01/chess2/Kind.java
Normal file
5
src/oop/ch01/chess2/Kind.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch01.chess2;
|
||||
|
||||
enum Kind {
|
||||
queen, knight
|
||||
}
|
87
src/oop/ch01/chess2/Piece.java
Normal file
87
src/oop/ch01/chess2/Piece.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package oop.ch01.chess2;
|
||||
|
||||
import static java.lang.Integer.signum;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
class Piece {
|
||||
Kind kind;
|
||||
Color color;
|
||||
Board board;
|
||||
int row;
|
||||
int col;
|
||||
|
||||
Piece(Kind kind, Color color, Board board, int row, int col) {
|
||||
if (row < 1 || row > 8 || col < 1 || col > 8)
|
||||
throw new IllegalArgumentException("Invalid pos " + row + "/" + col);
|
||||
this.kind = kind;
|
||||
this.color = color;
|
||||
this.board = board;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
board.add(this);
|
||||
}
|
||||
|
||||
char charRep() {
|
||||
return switch (kind) {
|
||||
case queen -> queenCharRep();
|
||||
case knight -> knightCharRep();
|
||||
};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return switch (kind) {
|
||||
case queen -> queenToString();
|
||||
case knight -> knightToString();
|
||||
};
|
||||
}
|
||||
|
||||
boolean canCapture(Piece other) {
|
||||
return switch (kind) {
|
||||
case queen -> queenCanCapture(other);
|
||||
case knight -> knightCanCapture(other);
|
||||
};
|
||||
}
|
||||
|
||||
char queenCharRep() {
|
||||
return color == Color.white ? 'q' : 'Q';
|
||||
}
|
||||
|
||||
char knightCharRep() {
|
||||
return color == Color.white ? 'n' : 'N';
|
||||
}
|
||||
|
||||
String queenToString() {
|
||||
return "" + color + " queen at (" + row + ", " + col + ")";
|
||||
}
|
||||
|
||||
String knightToString() {
|
||||
return "" + color + " knight at (" + row + ", " + col + ")";
|
||||
}
|
||||
|
||||
boolean queenCanCapture(Piece other) {
|
||||
if (board != other.board || color == other.color)
|
||||
return false;
|
||||
if (other.row != row &&
|
||||
other.col != col &&
|
||||
abs(other.row - row) != abs(other.col - col))
|
||||
return false;
|
||||
final int dr = signum(other.row - row);
|
||||
final int dc = signum(other.col - col);
|
||||
int r = row + dr;
|
||||
int c = col + dc;
|
||||
while (r != other.row || c != other.col) {
|
||||
if (board.pieceAt(r, c) != null) return false;
|
||||
r += dr;
|
||||
c += dc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean knightCanCapture(Piece other) {
|
||||
if (board != other.board || color == other.color)
|
||||
return false;
|
||||
final int dr = abs(row - other.row);
|
||||
final int dc = abs(col - other.col);
|
||||
return dr == 2 && dc == 1 || dr == 1 && dc == 2;
|
||||
}
|
||||
}
|
5
src/oop/ch01/chess2/package-info.java
Normal file
5
src/oop/ch01/chess2/package-info.java
Normal file
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Using objects with methods for the Java solution of the chess problem.
|
||||
* Qualification of members with "this." is avoided where possible.
|
||||
*/
|
||||
package oop.ch01.chess2;
|
79
src/oop/ch02/cards/Card.java
Normal file
79
src/oop/ch02/cards/Card.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package oop.ch02.cards;
|
||||
|
||||
/**
|
||||
* Represents any card with a name and a unique serial number.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class Card {
|
||||
/**
|
||||
* The name of this card.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Counts the number of instantiations of this class.
|
||||
*/
|
||||
private static int counter = 0;
|
||||
|
||||
/**
|
||||
* The unique serial number of this card.
|
||||
*/
|
||||
private final int number;
|
||||
|
||||
/**
|
||||
* Creates a new card with the specified name.
|
||||
*
|
||||
* @param name the name of this card
|
||||
*/
|
||||
public Card(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException("name is null");
|
||||
this.name = name;
|
||||
this.number = ++counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new card for a student with the specified number.
|
||||
*
|
||||
* @param num the student's number
|
||||
*/
|
||||
public Card(int num) {
|
||||
this("MatrNr. " + num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this card.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serial number of this card.
|
||||
*
|
||||
* @return the serial number
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of instantiations of this class.
|
||||
*
|
||||
* @return the number of instantiations.
|
||||
*/
|
||||
public static int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this card.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Card " + name + " (no " + number + ")";
|
||||
}
|
||||
}
|
20
src/oop/ch02/cards/CardExample.java
Normal file
20
src/oop/ch02/cards/CardExample.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package oop.ch02.cards;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CardExample {
|
||||
public static void main(String[] args) {
|
||||
Card c1 = new Card(12345);
|
||||
System.out.println(c1 + " erstellt.");
|
||||
|
||||
String[] names = {"Franz Mueller", "Hans Mustermann", "Peter Meier"};
|
||||
Card[] cards = new Card[names.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
cards[i] = new Card(names[i]);
|
||||
System.out.println(cards[i] + " erstellt.");
|
||||
}
|
||||
System.out.println("cards = " + cards);
|
||||
System.out.println("cards = " + Arrays.deepToString(cards));
|
||||
System.out.println("#Card = " + Card.getCounter());
|
||||
}
|
||||
}
|
34
src/oop/ch02/cards0/Card.java
Normal file
34
src/oop/ch02/cards0/Card.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package oop.ch02.cards0;
|
||||
|
||||
public class Card {
|
||||
private final String name;
|
||||
private static int counter = 0;
|
||||
private final int number;
|
||||
|
||||
public Card(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException("name is null");
|
||||
this.name = name;
|
||||
this.number = ++Card.counter;
|
||||
}
|
||||
|
||||
public Card(int num) {
|
||||
this("MatrNr. " + num);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public static int getCounter() {
|
||||
return Card.counter;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Card " + name + " (no " + number + ")";
|
||||
}
|
||||
}
|
59
src/oop/ch02/chess1/Board.java
Normal file
59
src/oop/ch02/chess1/Board.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package oop.ch02.chess1;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Board {
|
||||
private ArrayList<Piece> pieces;
|
||||
|
||||
public Board() {
|
||||
this.pieces = new ArrayList<Piece>();
|
||||
}
|
||||
|
||||
void add(Piece piece) {
|
||||
if (piece.getBoard() != this)
|
||||
throw new IllegalArgumentException("wrong board");
|
||||
final Piece existing = pieceAt(piece.getRow(), piece.getCol());
|
||||
if (existing != null)
|
||||
throw new IllegalArgumentException("already occupied by " +
|
||||
existing.toString());
|
||||
pieces.add(piece);
|
||||
}
|
||||
|
||||
public void printBoard() {
|
||||
System.out.println(" 1 2 3 4 5 6 7 8");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
for (int row = 1; row <= 8; row++) {
|
||||
System.out.print("" + row + " ");
|
||||
for (int col = 1; col <= 8; col++) {
|
||||
final Piece p = pieceAt(row, col);
|
||||
final char c = p == null ? ' ' : p.charRep();
|
||||
System.out.print("| " + c + " ");
|
||||
}
|
||||
System.out.println("|");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
}
|
||||
}
|
||||
|
||||
public Piece pieceAt(int row, int col) {
|
||||
for (Piece p : pieces)
|
||||
if (p.getRow() == row && p.getCol() == col)
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void check() {
|
||||
for (Piece p1 : pieces) {
|
||||
System.out.println(p1.toString());
|
||||
for (Piece p2 : pieces)
|
||||
if (p1 != p2)
|
||||
if (p1.canCapture(p2))
|
||||
System.out.println(" can capture " + p2.toString());
|
||||
else
|
||||
System.out.println(" cannot capture " + p2.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return pieces.toString();
|
||||
}
|
||||
}
|
15
src/oop/ch02/chess1/Chess.java
Normal file
15
src/oop/ch02/chess1/Chess.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch02.chess1;
|
||||
|
||||
public class Chess {
|
||||
public static void main(String[] args) {
|
||||
final Board board = new Board();
|
||||
final Piece p1 = new Piece(Kind.queen, Color.black, board, 1, 4);
|
||||
final Piece p2 = new Piece(Kind.queen, Color.white, board, 8, 4);
|
||||
final Piece p3 = new Piece(Kind.knight, Color.white, board, 3, 3);
|
||||
final Piece p4 = new Piece(Kind.knight, Color.black, board, 6, 4);
|
||||
System.out.println(board);
|
||||
System.out.println(board.toString());
|
||||
board.printBoard();
|
||||
board.check();
|
||||
}
|
||||
}
|
5
src/oop/ch02/chess1/Color.java
Normal file
5
src/oop/ch02/chess1/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch02.chess1;
|
||||
|
||||
public enum Color {
|
||||
black, white
|
||||
}
|
5
src/oop/ch02/chess1/Kind.java
Normal file
5
src/oop/ch02/chess1/Kind.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch02.chess1;
|
||||
|
||||
public enum Kind {
|
||||
queen, knight
|
||||
}
|
107
src/oop/ch02/chess1/Piece.java
Normal file
107
src/oop/ch02/chess1/Piece.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package oop.ch02.chess1;
|
||||
|
||||
import static java.lang.Integer.signum;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class Piece {
|
||||
private Kind kind;
|
||||
private Color color;
|
||||
private Board board;
|
||||
private int row;
|
||||
private int col;
|
||||
|
||||
public Piece(Kind kind, Color color, Board board, int row, int col) {
|
||||
if (row < 1 || row > 8 || col < 1 || col > 8)
|
||||
throw new IllegalArgumentException("Invalid pos " + row + "/" + col);
|
||||
this.kind = kind;
|
||||
this.color = color;
|
||||
this.board = board;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
board.add(this);
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public Board getBoard() {
|
||||
return board;
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
public int getCol() {
|
||||
return col;
|
||||
}
|
||||
|
||||
public char charRep() {
|
||||
return switch (kind) {
|
||||
case queen -> queenCharRep();
|
||||
case knight -> knightCharRep();
|
||||
};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return switch (kind) {
|
||||
case queen -> queenToString();
|
||||
case knight -> knightToString();
|
||||
};
|
||||
}
|
||||
|
||||
public boolean canCapture(Piece other) {
|
||||
return switch (kind) {
|
||||
case queen -> queenCanCapture(other);
|
||||
case knight -> knightCanCapture(other);
|
||||
};
|
||||
}
|
||||
|
||||
private char queenCharRep() {
|
||||
return color == Color.white ? 'q' : 'Q';
|
||||
}
|
||||
|
||||
private char knightCharRep() {
|
||||
return color == Color.white ? 'n' : 'N';
|
||||
}
|
||||
|
||||
private String queenToString() {
|
||||
return "" + color + " queen at (" + row + ", " + col + ")";
|
||||
}
|
||||
|
||||
private String knightToString() {
|
||||
return "" + color + " knight at (" + row + ", " + col + ")";
|
||||
}
|
||||
|
||||
private boolean queenCanCapture(Piece other) {
|
||||
if (board != other.board || color == other.color)
|
||||
return false;
|
||||
if (other.row != row &&
|
||||
other.col != col &&
|
||||
abs(other.row - row) != abs(other.col - col))
|
||||
return false;
|
||||
final int dr = signum(other.row - row);
|
||||
final int dc = signum(other.col - col);
|
||||
int r = row + dr;
|
||||
int c = col + dc;
|
||||
while (r != other.row || c != other.col) {
|
||||
if (board.pieceAt(r, c) != null) return false;
|
||||
r += dr;
|
||||
c += dc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean knightCanCapture(Piece other) {
|
||||
if (board != other.board || color == other.color)
|
||||
return false;
|
||||
final int dr = abs(row - other.row);
|
||||
final int dc = abs(col - other.col);
|
||||
return dr == 2 && dc == 1 || dr == 1 && dc == 2;
|
||||
}
|
||||
}
|
4
src/oop/ch02/chess1/package-info.java
Normal file
4
src/oop/ch02/chess1/package-info.java
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Using access modifiers in the Java solution of the chess problem.
|
||||
*/
|
||||
package oop.ch02.chess1;
|
54
src/oop/ch02/chess2/Board.java
Normal file
54
src/oop/ch02/chess2/Board.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package oop.ch02.chess2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Board {
|
||||
private final Piece[][] field = new Piece[8][8];
|
||||
private final ArrayList<Piece> pieces = new ArrayList<Piece>();
|
||||
|
||||
void add(Piece piece) {
|
||||
if (piece.getBoard() != this)
|
||||
throw new IllegalArgumentException("wrong board");
|
||||
final Piece existing = pieceAt(piece.getRow(), piece.getCol());
|
||||
if (existing != null)
|
||||
throw new IllegalArgumentException("already occupied by " +
|
||||
existing.toString());
|
||||
field[piece.getRow() - 1][piece.getCol() - 1] = piece;
|
||||
pieces.add(piece);
|
||||
}
|
||||
|
||||
public void printBoard() {
|
||||
System.out.println(" 1 2 3 4 5 6 7 8");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
for (int row = 1; row <= 8; row++) {
|
||||
System.out.print("" + row + " ");
|
||||
for (int col = 1; col <= 8; col++) {
|
||||
final Piece p = pieceAt(row, col);
|
||||
final char c = p == null ? ' ' : p.charRep();
|
||||
System.out.print("| " + c + " ");
|
||||
}
|
||||
System.out.println("|");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
}
|
||||
}
|
||||
|
||||
public Piece pieceAt(int row, int col) {
|
||||
return field[row - 1][col - 1];
|
||||
}
|
||||
|
||||
public void check() {
|
||||
for (Piece p1 : pieces) {
|
||||
System.out.println(p1.toString());
|
||||
for (Piece p2 : pieces)
|
||||
if (p1 != p2)
|
||||
if (p1.canCapture(p2))
|
||||
System.out.println(" can capture " + p2.toString());
|
||||
else
|
||||
System.out.println(" cannot capture " + p2.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return pieces.toString();
|
||||
}
|
||||
}
|
15
src/oop/ch02/chess2/Chess.java
Normal file
15
src/oop/ch02/chess2/Chess.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch02.chess2;
|
||||
|
||||
public class Chess {
|
||||
public static void main(String[] args) {
|
||||
final Board board = new Board();
|
||||
final Piece p1 = new Piece(Kind.queen, Color.black, board, 1, 4);
|
||||
final Piece p2 = new Piece(Kind.queen, Color.white, board, 8, 4);
|
||||
final Piece p3 = new Piece(Kind.knight, Color.white, board, 3, 3);
|
||||
final Piece p4 = new Piece(Kind.knight, Color.black, board, 6, 4);
|
||||
System.out.println(board);
|
||||
System.out.println(board.toString());
|
||||
board.printBoard();
|
||||
board.check();
|
||||
}
|
||||
}
|
5
src/oop/ch02/chess2/Color.java
Normal file
5
src/oop/ch02/chess2/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch02.chess2;
|
||||
|
||||
public enum Color {
|
||||
black, white
|
||||
}
|
5
src/oop/ch02/chess2/Kind.java
Normal file
5
src/oop/ch02/chess2/Kind.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch02.chess2;
|
||||
|
||||
public enum Kind {
|
||||
queen, knight
|
||||
}
|
107
src/oop/ch02/chess2/Piece.java
Normal file
107
src/oop/ch02/chess2/Piece.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package oop.ch02.chess2;
|
||||
|
||||
import static java.lang.Integer.signum;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class Piece {
|
||||
private Kind kind;
|
||||
private Color color;
|
||||
private Board board;
|
||||
private int row;
|
||||
private int col;
|
||||
|
||||
public Piece(Kind kind, Color color, Board board, int row, int col) {
|
||||
if (row < 1 || row > 8 || col < 1 || col > 8)
|
||||
throw new IllegalArgumentException("Invalid pos " + row + "/" + col);
|
||||
this.kind = kind;
|
||||
this.color = color;
|
||||
this.board = board;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
board.add(this);
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public Board getBoard() {
|
||||
return board;
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
public int getCol() {
|
||||
return col;
|
||||
}
|
||||
|
||||
public char charRep() {
|
||||
return switch (kind) {
|
||||
case queen -> queenCharRep();
|
||||
case knight -> knightCharRep();
|
||||
};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return switch (kind) {
|
||||
case queen -> queenToString();
|
||||
case knight -> knightToString();
|
||||
};
|
||||
}
|
||||
|
||||
public boolean canCapture(Piece other) {
|
||||
return switch (kind) {
|
||||
case queen -> queenCanCapture(other);
|
||||
case knight -> knightCanCapture(other);
|
||||
};
|
||||
}
|
||||
|
||||
private char queenCharRep() {
|
||||
return color == Color.white ? 'q' : 'Q';
|
||||
}
|
||||
|
||||
private char knightCharRep() {
|
||||
return color == Color.white ? 'n' : 'N';
|
||||
}
|
||||
|
||||
private String queenToString() {
|
||||
return "" + color + " queen at (" + row + ", " + col + ")";
|
||||
}
|
||||
|
||||
private String knightToString() {
|
||||
return "" + color + " knight at (" + row + ", " + col + ")";
|
||||
}
|
||||
|
||||
private boolean queenCanCapture(Piece other) {
|
||||
if (board != other.board || color == other.color)
|
||||
return false;
|
||||
if (other.row != row &&
|
||||
other.col != col &&
|
||||
abs(other.row - row) != abs(other.col - col))
|
||||
return false;
|
||||
final int dr = signum(other.row - row);
|
||||
final int dc = signum(other.col - col);
|
||||
int r = row + dr;
|
||||
int c = col + dc;
|
||||
while (r != other.row || c != other.col) {
|
||||
if (board.pieceAt(r, c) != null) return false;
|
||||
r += dr;
|
||||
c += dc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean knightCanCapture(Piece other) {
|
||||
if (board != other.board || color == other.color)
|
||||
return false;
|
||||
final int dr = abs(row - other.row);
|
||||
final int dc = abs(col - other.col);
|
||||
return dr == 2 && dc == 1 || dr == 1 && dc == 2;
|
||||
}
|
||||
}
|
4
src/oop/ch02/chess2/package-info.java
Normal file
4
src/oop/ch02/chess2/package-info.java
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Using arrays for speeding up the Java solution of the chess problem.
|
||||
*/
|
||||
package oop.ch02.chess2;
|
33
src/oop/ch02/clock/Clock1.java
Normal file
33
src/oop/ch02/clock/Clock1.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package oop.ch02.clock;
|
||||
|
||||
public class Clock1 {
|
||||
private int hour;
|
||||
private int minute;
|
||||
|
||||
public Clock1(int hour, int minute) {
|
||||
if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60)
|
||||
throw new IllegalArgumentException("Invalid time " + hour + ":" + minute);
|
||||
this.hour = hour;
|
||||
this.minute = minute;
|
||||
}
|
||||
|
||||
public int getHour() {
|
||||
return hour;
|
||||
}
|
||||
|
||||
public void setHour(int hour) {
|
||||
if (hour < 0 || hour >= 24)
|
||||
throw new IllegalArgumentException("Invalid hour " + hour);
|
||||
this.hour = hour;
|
||||
}
|
||||
|
||||
public int getMinute() {
|
||||
return minute;
|
||||
}
|
||||
|
||||
public void setMinute(int minute) {
|
||||
if (minute < 0 || minute >= 60)
|
||||
throw new IllegalArgumentException("Invalid minute " + minute);
|
||||
this.minute = minute;
|
||||
}
|
||||
}
|
27
src/oop/ch02/clock/Clock2.java
Normal file
27
src/oop/ch02/clock/Clock2.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package oop.ch02.clock;
|
||||
|
||||
public class Clock2 {
|
||||
private int hour;
|
||||
private int minute;
|
||||
|
||||
public Clock2(int hour, int minute) {
|
||||
if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60)
|
||||
throw new IllegalArgumentException("Invalid time " + hour + ":" + minute);
|
||||
this.hour = hour;
|
||||
this.minute = minute;
|
||||
}
|
||||
|
||||
public int getHour() {
|
||||
return hour;
|
||||
}
|
||||
|
||||
public int getMinute() {
|
||||
return minute;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
minute = (minute + 1) % 60;
|
||||
if (minute == 0)
|
||||
hour = (hour + 1) % 24;
|
||||
}
|
||||
}
|
24
src/oop/ch02/clock/Clock3.java
Normal file
24
src/oop/ch02/clock/Clock3.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package oop.ch02.clock;
|
||||
|
||||
public class Clock3 {
|
||||
public static final int MINUTES_PER_DAY = 60 * 24;
|
||||
private int mins;
|
||||
|
||||
public Clock3(int hour, int minute) {
|
||||
if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60)
|
||||
throw new IllegalArgumentException("Invalid time " + hour + ":" + minute);
|
||||
this.mins = 60 * hour + minute;
|
||||
}
|
||||
|
||||
public int getHour() {
|
||||
return mins / 60;
|
||||
}
|
||||
|
||||
public int getMinute() {
|
||||
return mins % 60;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
mins = (mins + 1) % MINUTES_PER_DAY;
|
||||
}
|
||||
}
|
13
src/oop/ch02/clock/Example.java
Normal file
13
src/oop/ch02/clock/Example.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package oop.ch02.clock;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
Clock3 clock = new Clock3(22, 55);
|
||||
for (int i = 0; i < 7; i++)
|
||||
clock.tick();
|
||||
System.out.printf("%02d:%02d%n", clock.getHour(), clock.getMinute());
|
||||
for (int i = 0; i < 60; i++)
|
||||
clock.tick();
|
||||
System.out.printf("%02d:%02d%n", clock.getHour(), clock.getMinute());
|
||||
}
|
||||
}
|
54
src/oop/ch03/chess/Board.java
Normal file
54
src/oop/ch03/chess/Board.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package oop.ch03.chess;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Board {
|
||||
private final Piece[][] field = new Piece[8][8];
|
||||
private final ArrayList<Piece> pieces = new ArrayList<Piece>();
|
||||
|
||||
void add(Piece piece) {
|
||||
if (piece.getBoard() != this)
|
||||
throw new IllegalArgumentException("wrong board");
|
||||
final Piece existing = pieceAt(piece.getRow(), piece.getCol());
|
||||
if (existing != null)
|
||||
throw new IllegalArgumentException("already occupied by " +
|
||||
existing.toString());
|
||||
field[piece.getRow() - 1][piece.getCol() - 1] = piece;
|
||||
pieces.add(piece);
|
||||
}
|
||||
|
||||
public void printBoard() {
|
||||
System.out.println(" 1 2 3 4 5 6 7 8");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
for (int row = 1; row <= 8; row++) {
|
||||
System.out.print("" + row + " ");
|
||||
for (int col = 1; col <= 8; col++) {
|
||||
final Piece p = pieceAt(row, col);
|
||||
final char c = p == null ? ' ' : p.charRep();
|
||||
System.out.print("| " + c + " ");
|
||||
}
|
||||
System.out.println("|");
|
||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||
}
|
||||
}
|
||||
|
||||
public Piece pieceAt(int row, int col) {
|
||||
return field[row - 1][col - 1];
|
||||
}
|
||||
|
||||
public void check() {
|
||||
for (Piece p1 : pieces) {
|
||||
System.out.println(p1.toString());
|
||||
for (Piece p2 : pieces)
|
||||
if (p1 != p2)
|
||||
if (p1.canCapture(p2))
|
||||
System.out.println(" can capture " + p2.toString());
|
||||
else
|
||||
System.out.println(" cannot capture " + p2.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return pieces.toString();
|
||||
}
|
||||
}
|
17
src/oop/ch03/chess/Chess.java
Normal file
17
src/oop/ch03/chess/Chess.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package oop.ch03.chess;
|
||||
|
||||
public class Chess {
|
||||
public static void main(String[] args) {
|
||||
final Board board = new Board();
|
||||
final Piece p1 = new Queen(Color.black, board, 1, 4);
|
||||
final Piece p2 = new Queen(Color.white, board, 8, 4);
|
||||
final Piece p3 = new Knight(Color.white, board, 3, 3);
|
||||
final Piece p4 = new Knight(Color.black, board, 6, 4);
|
||||
final Piece p5 = new Rook(Color.white, board, 7, 1);
|
||||
final Piece p6 = new Rook(Color.black, board, 4, 4);
|
||||
System.out.println(board);
|
||||
System.out.println(board.toString());
|
||||
board.printBoard();
|
||||
board.check();
|
||||
}
|
||||
}
|
5
src/oop/ch03/chess/Color.java
Normal file
5
src/oop/ch03/chess/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch03.chess;
|
||||
|
||||
public enum Color {
|
||||
black, white
|
||||
}
|
28
src/oop/ch03/chess/Knight.java
Normal file
28
src/oop/ch03/chess/Knight.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package oop.ch03.chess;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class Knight extends Piece {
|
||||
public Knight(Color color, Board board, int row, int col) {
|
||||
super(color, board, row, col);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charRep() {
|
||||
return getColor() == Color.white ? 'n' : 'N';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "" + getColor() + " knight at (" + getRow() + ", " + getCol() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCapture(Piece other) {
|
||||
if (getBoard() != other.getBoard() || getColor() == other.getColor())
|
||||
return false;
|
||||
final int dr = abs(getRow() - other.getRow());
|
||||
final int dc = abs(getCol() - other.getCol());
|
||||
return dr == 2 && dc == 1 || dr == 1 && dc == 2;
|
||||
}
|
||||
}
|
38
src/oop/ch03/chess/Piece.java
Normal file
38
src/oop/ch03/chess/Piece.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package oop.ch03.chess;
|
||||
|
||||
public abstract class Piece {
|
||||
private Color color;
|
||||
private Board board;
|
||||
private int row;
|
||||
private int col;
|
||||
|
||||
protected Piece(Color color, Board board, int row, int col) {
|
||||
if (row < 1 || row > 8 || col < 1 || col > 8)
|
||||
throw new IllegalArgumentException("Invalid pos " + row + "/" + col);
|
||||
this.color = color;
|
||||
this.board = board;
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
board.add(this);
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public Board getBoard() {
|
||||
return board;
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
public int getCol() {
|
||||
return col;
|
||||
}
|
||||
|
||||
public abstract char charRep();
|
||||
|
||||
public abstract boolean canCapture(Piece other);
|
||||
}
|
40
src/oop/ch03/chess/Queen.java
Normal file
40
src/oop/ch03/chess/Queen.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package oop.ch03.chess;
|
||||
|
||||
import static java.lang.Integer.signum;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class Queen extends Piece {
|
||||
public Queen(Color color, Board board, int row, int col) {
|
||||
super(color, board, row, col);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charRep() {
|
||||
return getColor() == Color.white ? 'q' : 'Q';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "" + getColor() + " queen at (" + getRow() + ", " + getCol() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCapture(Piece other) {
|
||||
if (getBoard() != other.getBoard() || getColor() == other.getColor())
|
||||
return false;
|
||||
if (other.getRow() != getRow() &&
|
||||
other.getCol() != getCol() &&
|
||||
abs(other.getRow() - getRow()) != abs(other.getCol() - getCol()))
|
||||
return false;
|
||||
final int dr = signum(other.getRow() - getRow());
|
||||
final int dc = signum(other.getCol() - getCol());
|
||||
int r = getRow() + dr;
|
||||
int c = getCol() + dc;
|
||||
while (r != other.getRow() || c != other.getCol()) {
|
||||
if (getBoard().pieceAt(r, c) != null) return false;
|
||||
r += dr;
|
||||
c += dc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
41
src/oop/ch03/chess/Rook.java
Normal file
41
src/oop/ch03/chess/Rook.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package oop.ch03.chess;
|
||||
|
||||
import static java.lang.Integer.signum;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class Rook extends Piece{
|
||||
|
||||
public Rook(Color color, Board board, int row, int col){
|
||||
super(color, board, row, col);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charRep(){
|
||||
return getColor() == Color.white ? 'r' : 'R';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCapture(Piece other){
|
||||
if (getBoard() != other.getBoard() || getColor() == other.getColor()) {
|
||||
return false;
|
||||
}
|
||||
if(other.getRow() != getRow() && other.getCol() != getCol()){
|
||||
return false;
|
||||
}
|
||||
|
||||
final int dr = signum(other.getRow() - getRow());
|
||||
final int dc = signum(other.getCol() - getCol());
|
||||
int r = getRow() + dr;
|
||||
int c = getCol() + dc;
|
||||
|
||||
while (r != other.getRow() || c != other.getCol()) {
|
||||
if (getBoard().pieceAt(r, c) != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
r += dr;
|
||||
c += dc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
4
src/oop/ch03/chess/package-info.java
Normal file
4
src/oop/ch03/chess/package-info.java
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Using inheritance and dynamic binding in the Java solution of the chess problem.
|
||||
*/
|
||||
package oop.ch03.chess;
|
26
src/oop/ch03/vehicles/AmphibienBsp.java
Normal file
26
src/oop/ch03/vehicles/AmphibienBsp.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AmphibienBsp {
|
||||
public static void main(String[] args) {
|
||||
final Auto golf = new AutoImpl(500);
|
||||
final Schiff titanic = new SchiffImpl(53150E3);
|
||||
final Amphibienfahrzeug alligator = new AmphibienfahrzeugImpl(750, 8000);
|
||||
|
||||
System.out.println("Fahrzeuge:");
|
||||
final List<Fahrzeug> fahrzeuge = List.of(golf, titanic, alligator);
|
||||
for (Fahrzeug fz : fahrzeuge)
|
||||
System.out.println(fz + ", zuladung: " + fz.getMaxZuladung());
|
||||
|
||||
System.out.println("Autos:");
|
||||
final List<Auto> autos = List.of(golf, alligator);
|
||||
for (Auto auto : autos)
|
||||
System.out.println(auto + ", zuladung: " + auto.getMaxZuladung());
|
||||
|
||||
System.out.println("Schiffe:");
|
||||
final List<Schiff> schiffe = List.of(titanic, alligator);
|
||||
for (Schiff schiff : schiffe)
|
||||
System.out.println(schiff + ", zuladung: " + schiff.getMaxZuladung());
|
||||
}
|
||||
}
|
3
src/oop/ch03/vehicles/Amphibienfahrzeug.java
Normal file
3
src/oop/ch03/vehicles/Amphibienfahrzeug.java
Normal file
@@ -0,0 +1,3 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public interface Amphibienfahrzeug extends Auto, Schiff {}
|
27
src/oop/ch03/vehicles/AmphibienfahrzeugImpl.java
Normal file
27
src/oop/ch03/vehicles/AmphibienfahrzeugImpl.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public class AmphibienfahrzeugImpl extends AutoImpl implements Amphibienfahrzeug {
|
||||
private final SchiffImpl schiff;
|
||||
|
||||
public AmphibienfahrzeugImpl(double maxAutoZuladung,
|
||||
double maxSchiffZuladung) {
|
||||
super(maxAutoZuladung);
|
||||
this.schiff = new SchiffImpl(maxSchiffZuladung);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kannHierFahren(double laenge, double breite) {
|
||||
return super.kannHierFahren(laenge, breite) ||
|
||||
schiff.kannHierFahren(laenge, breite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxZuladung() {
|
||||
return Math.max(super.getMaxZuladung(), schiff.getMaxZuladung());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTiefgang() {
|
||||
return schiff.getTiefgang();
|
||||
}
|
||||
}
|
27
src/oop/ch03/vehicles/AmphibienfahrzeugImpl2.java
Normal file
27
src/oop/ch03/vehicles/AmphibienfahrzeugImpl2.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public class AmphibienfahrzeugImpl2 extends SchiffImpl implements Amphibienfahrzeug {
|
||||
private final AutoImpl auto;
|
||||
|
||||
public AmphibienfahrzeugImpl2(double maxAutoZuladung,
|
||||
double maxSchiffZuladung) {
|
||||
super(maxSchiffZuladung);
|
||||
this.auto = new AutoImpl(maxAutoZuladung);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kannHierFahren(double laenge, double breite) {
|
||||
return super.kannHierFahren(laenge, breite) ||
|
||||
auto.kannHierFahren(laenge, breite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxZuladung() {
|
||||
return Math.max(super.getMaxZuladung(), auto.getMaxZuladung());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAchslast() {
|
||||
return auto.getAchslast();
|
||||
}
|
||||
}
|
5
src/oop/ch03/vehicles/Auto.java
Normal file
5
src/oop/ch03/vehicles/Auto.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public interface Auto extends Fahrzeug {
|
||||
double getAchslast();
|
||||
}
|
22
src/oop/ch03/vehicles/AutoImpl.java
Normal file
22
src/oop/ch03/vehicles/AutoImpl.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public class AutoImpl extends FahrzeugImpl implements Auto {
|
||||
public AutoImpl(double maxZuladung) {
|
||||
super(maxZuladung);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAchslast() {
|
||||
return maxZuladung;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kannHierFahren(double laenge, double breite) {
|
||||
return aufStrasse(laenge, breite) && getGewicht() < maxZuladung;
|
||||
}
|
||||
|
||||
private boolean aufStrasse(double laenge, double breite) {
|
||||
// TODO implement
|
||||
return false;
|
||||
}
|
||||
}
|
9
src/oop/ch03/vehicles/Fahrzeug.java
Normal file
9
src/oop/ch03/vehicles/Fahrzeug.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public interface Fahrzeug {
|
||||
double getGewicht();
|
||||
|
||||
double getMaxZuladung();
|
||||
|
||||
boolean kannHierFahren(double laenge, double breite);
|
||||
}
|
20
src/oop/ch03/vehicles/FahrzeugImpl.java
Normal file
20
src/oop/ch03/vehicles/FahrzeugImpl.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public abstract class FahrzeugImpl implements Fahrzeug {
|
||||
protected final double maxZuladung;
|
||||
|
||||
protected FahrzeugImpl(double maxZuladung) {
|
||||
this.maxZuladung = maxZuladung;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getGewicht() {
|
||||
// TODO implement
|
||||
return 1000.;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxZuladung() {
|
||||
return maxZuladung;
|
||||
}
|
||||
}
|
5
src/oop/ch03/vehicles/Schiff.java
Normal file
5
src/oop/ch03/vehicles/Schiff.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public interface Schiff extends Fahrzeug {
|
||||
double getTiefgang();
|
||||
}
|
23
src/oop/ch03/vehicles/SchiffImpl.java
Normal file
23
src/oop/ch03/vehicles/SchiffImpl.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package oop.ch03.vehicles;
|
||||
|
||||
public class SchiffImpl extends FahrzeugImpl implements Schiff {
|
||||
public SchiffImpl(double maxZuladung) {
|
||||
super(maxZuladung);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTiefgang() {
|
||||
// TODO implement
|
||||
return 1.;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kannHierFahren(double laenge, double breite) {
|
||||
return aufWasser(laenge, breite) && getGewicht() < maxZuladung;
|
||||
}
|
||||
|
||||
private boolean aufWasser(double laenge, double breite) {
|
||||
// TODO implement
|
||||
return false;
|
||||
}
|
||||
}
|
27
src/oop/ch04/equality/Example.java
Normal file
27
src/oop/ch04/equality/Example.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package oop.ch04.equality;
|
||||
|
||||
import oop.ch04.equality.card1.Card;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
Card c1 = new Card("foo");
|
||||
Card c2 = new Card("foo");
|
||||
System.out.println(c1 == c2);
|
||||
|
||||
int i1 = 42;
|
||||
int i2 = 2 * 21;
|
||||
System.out.println(i1 == i2);
|
||||
|
||||
double f1 = 0.5;
|
||||
double f2 = 1.0 / 2.0;
|
||||
System.out.println(f1 == f2);
|
||||
|
||||
String s1 = "OOP";
|
||||
String s2 = "O" + "OP";
|
||||
System.out.println(s1 == s2);
|
||||
|
||||
String s3 = "OOP".substring(1);
|
||||
String s4 = "OP";
|
||||
System.out.println(s3 == s4);
|
||||
}
|
||||
}
|
89
src/oop/ch04/equality/card1/Card.java
Normal file
89
src/oop/ch04/equality/card1/Card.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package oop.ch04.equality.card1;
|
||||
|
||||
/**
|
||||
* Represents any card with a name and a unique serial number.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class Card {
|
||||
/**
|
||||
* The name of this card.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Counts the number of instantiations of this class.
|
||||
*/
|
||||
private static int counter = 0;
|
||||
|
||||
/**
|
||||
* The unique serial number of this card.
|
||||
*/
|
||||
private final int number;
|
||||
|
||||
/**
|
||||
* Creates a new card with the specified name.
|
||||
*
|
||||
* @param name the name of this card
|
||||
*/
|
||||
public Card(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException("name is null");
|
||||
this.name = name;
|
||||
this.number = ++counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new card for a student with the specified number.
|
||||
*
|
||||
* @param num the student's number
|
||||
*/
|
||||
public Card(int num) {
|
||||
this("MatrNr. " + num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this card.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serial number of this card.
|
||||
*
|
||||
* @return the serial number
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of instantiations of this class.
|
||||
*
|
||||
* @return the number of instantiations.
|
||||
*/
|
||||
public static int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this card.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Card " + name + " (no " + number + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof Card) {
|
||||
final Card that = (Card) o;
|
||||
return this.name.equals(that.name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
5
src/oop/ch04/equality/card1/Color.java
Normal file
5
src/oop/ch04/equality/card1/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch04.equality.card1;
|
||||
|
||||
public enum Color {
|
||||
red, green, blue
|
||||
}
|
26
src/oop/ch04/equality/card1/ColoredCard.java
Normal file
26
src/oop/ch04/equality/card1/ColoredCard.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package oop.ch04.equality.card1;
|
||||
|
||||
public class ColoredCard extends Card {
|
||||
public final Color color;
|
||||
|
||||
public ColoredCard(String key, Color color) {
|
||||
super(key);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return color + " " + super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof ColoredCard) {
|
||||
final ColoredCard that = (ColoredCard) o;
|
||||
return this.color == that.color &&
|
||||
super.equals(that);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
11
src/oop/ch04/equality/card1/Example.java
Normal file
11
src/oop/ch04/equality/card1/Example.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package oop.ch04.equality.card1;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
Card k1 = new Card("foo");
|
||||
Card c1 = new ColoredCard("foo", Color.green);
|
||||
|
||||
System.out.println(c1.equals(k1));
|
||||
System.out.println(k1.equals(c1));
|
||||
}
|
||||
}
|
89
src/oop/ch04/equality/card2/Card.java
Normal file
89
src/oop/ch04/equality/card2/Card.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package oop.ch04.equality.card2;
|
||||
|
||||
/**
|
||||
* Represents any card with a name and a unique serial number.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class Card {
|
||||
/**
|
||||
* The name of this card.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Counts the number of instantiations of this class.
|
||||
*/
|
||||
private static int counter = 0;
|
||||
|
||||
/**
|
||||
* The unique serial number of this card.
|
||||
*/
|
||||
private final int number;
|
||||
|
||||
/**
|
||||
* Creates a new card with the specified name.
|
||||
*
|
||||
* @param name the name of this card
|
||||
*/
|
||||
public Card(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException("name is null");
|
||||
this.name = name;
|
||||
this.number = ++counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new card for a student with the specified number.
|
||||
*
|
||||
* @param num the student's number
|
||||
*/
|
||||
public Card(int num) {
|
||||
this("MatrNr. " + num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this card.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serial number of this card.
|
||||
*
|
||||
* @return the serial number
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of instantiations of this class.
|
||||
*
|
||||
* @return the number of instantiations.
|
||||
*/
|
||||
public static int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this card.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Card " + name + " (no " + number + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof Card) {
|
||||
final Card that = (Card) o;
|
||||
return this.name.equals(that.name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
5
src/oop/ch04/equality/card2/Color.java
Normal file
5
src/oop/ch04/equality/card2/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch04.equality.card2;
|
||||
|
||||
public enum Color {
|
||||
red, green, blue
|
||||
}
|
28
src/oop/ch04/equality/card2/ColoredCard.java
Normal file
28
src/oop/ch04/equality/card2/ColoredCard.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package oop.ch04.equality.card2;
|
||||
|
||||
public class ColoredCard extends Card {
|
||||
public final Color color;
|
||||
|
||||
public ColoredCard(String key, Color color) {
|
||||
super(key);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return color + " " + super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof ColoredCard) {
|
||||
final ColoredCard that = (ColoredCard) o;
|
||||
return this.color == that.color &&
|
||||
super.equals(that);
|
||||
}
|
||||
if (o instanceof Card)
|
||||
return o.equals(this);
|
||||
return false;
|
||||
}
|
||||
}
|
15
src/oop/ch04/equality/card2/Example.java
Normal file
15
src/oop/ch04/equality/card2/Example.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch04.equality.card2;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
Card k1 = new Card("foo");
|
||||
Card c1 = new ColoredCard("foo", Color.green);
|
||||
Card c2 = new ColoredCard("foo", Color.red);
|
||||
|
||||
System.out.println(c1.equals(k1));
|
||||
System.out.println(k1.equals(c1));
|
||||
System.out.println(c2.equals(k1));
|
||||
System.out.println(k1.equals(c2));
|
||||
System.out.println(c1.equals(c2));
|
||||
}
|
||||
}
|
89
src/oop/ch04/equality/card3/Card.java
Normal file
89
src/oop/ch04/equality/card3/Card.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package oop.ch04.equality.card3;
|
||||
|
||||
/**
|
||||
* Represents any card with a name and a unique serial number.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class Card {
|
||||
/**
|
||||
* The name of this card.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Counts the number of instantiations of this class.
|
||||
*/
|
||||
private static int counter = 0;
|
||||
|
||||
/**
|
||||
* The unique serial number of this card.
|
||||
*/
|
||||
private final int number;
|
||||
|
||||
/**
|
||||
* Creates a new card with the specified name.
|
||||
*
|
||||
* @param name the name of this card
|
||||
*/
|
||||
public Card(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException("name is null");
|
||||
this.name = name;
|
||||
this.number = ++counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new card for a student with the specified number.
|
||||
*
|
||||
* @param num the student's number
|
||||
*/
|
||||
public Card(int num) {
|
||||
this("MatrNr. " + num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this card.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serial number of this card.
|
||||
*
|
||||
* @return the serial number
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of instantiations of this class.
|
||||
*
|
||||
* @return the number of instantiations.
|
||||
*/
|
||||
public static int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this card.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Card " + name + " (no " + number + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof Card) {
|
||||
final Card that = (Card) o;
|
||||
return this.name.equals(that.name) && this.getClass() == that.getClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
5
src/oop/ch04/equality/card3/Color.java
Normal file
5
src/oop/ch04/equality/card3/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch04.equality.card3;
|
||||
|
||||
public enum Color {
|
||||
red, green, blue
|
||||
}
|
25
src/oop/ch04/equality/card3/ColoredCard.java
Normal file
25
src/oop/ch04/equality/card3/ColoredCard.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package oop.ch04.equality.card3;
|
||||
|
||||
public class ColoredCard extends Card {
|
||||
public final Color color;
|
||||
|
||||
public ColoredCard(String key, Color color) {
|
||||
super(key);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return color + " " + super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof ColoredCard) {
|
||||
final ColoredCard that = (ColoredCard) o;
|
||||
return this.color == that.color && super.equals(that);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
15
src/oop/ch04/equality/card3/Example.java
Normal file
15
src/oop/ch04/equality/card3/Example.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch04.equality.card3;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
Card k1 = new Card("foo");
|
||||
Card c1 = new ColoredCard("foo", Color.green);
|
||||
Card c2 = new ColoredCard("foo", Color.red);
|
||||
|
||||
System.out.println(c1.equals(k1));
|
||||
System.out.println(k1.equals(c1));
|
||||
System.out.println(c2.equals(k1));
|
||||
System.out.println(k1.equals(c2));
|
||||
System.out.println(c1.equals(c2));
|
||||
}
|
||||
}
|
93
src/oop/ch04/equality/card4/Card.java
Normal file
93
src/oop/ch04/equality/card4/Card.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package oop.ch04.equality.card4;
|
||||
|
||||
/**
|
||||
* Represents any card with a name and a unique serial number.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class Card {
|
||||
/**
|
||||
* The name of this card.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Counts the number of instantiations of this class.
|
||||
*/
|
||||
private static int counter = 0;
|
||||
|
||||
/**
|
||||
* The unique serial number of this card.
|
||||
*/
|
||||
private final int number;
|
||||
|
||||
/**
|
||||
* Creates a new card with the specified name.
|
||||
*
|
||||
* @param name the name of this card
|
||||
*/
|
||||
public Card(String name) {
|
||||
if (name == null)
|
||||
throw new NullPointerException("name is null");
|
||||
this.name = name;
|
||||
this.number = ++counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new card for a student with the specified number.
|
||||
*
|
||||
* @param num the student's number
|
||||
*/
|
||||
public Card(int num) {
|
||||
this("MatrNr. " + num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this card.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serial number of this card.
|
||||
*
|
||||
* @return the serial number
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of instantiations of this class.
|
||||
*
|
||||
* @return the number of instantiations.
|
||||
*/
|
||||
public static int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this card.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Card " + name + " (no " + number + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof Card) {
|
||||
final Card that = (Card) o;
|
||||
return that.canEqual(this) && this.name.equals(that.name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canEqual(Object other) {
|
||||
return other instanceof Card;
|
||||
}
|
||||
}
|
5
src/oop/ch04/equality/card4/Color.java
Normal file
5
src/oop/ch04/equality/card4/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch04.equality.card4;
|
||||
|
||||
public enum Color {
|
||||
red, green, blue
|
||||
}
|
32
src/oop/ch04/equality/card4/ColoredCard.java
Normal file
32
src/oop/ch04/equality/card4/ColoredCard.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package oop.ch04.equality.card4;
|
||||
|
||||
public class ColoredCard extends Card {
|
||||
public final Color color;
|
||||
|
||||
public ColoredCard(String key, Color color) {
|
||||
super(key);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return color + " " + super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o instanceof ColoredCard) {
|
||||
final ColoredCard that = (ColoredCard) o;
|
||||
return that.canEqual(this) &&
|
||||
this.color == that.color &&
|
||||
super.equals(that);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEqual(Object other) {
|
||||
return other instanceof ColoredCard;
|
||||
}
|
||||
}
|
29
src/oop/ch04/equality/card4/Example.java
Normal file
29
src/oop/ch04/equality/card4/Example.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package oop.ch04.equality.card4;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static oop.ch04.equality.card4.Color.green;
|
||||
import static oop.ch04.equality.card4.Color.red;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
final Card k1 = new Card("foo");
|
||||
final Card k2 = new Card("foo");
|
||||
final Card k3 = new Card("gnat");
|
||||
final Card c1 = new ColoredCard("foo", green);
|
||||
final Card c2 = new ColoredCard("foo", red);
|
||||
final Card c3 = new ColoredCard("foo", red);
|
||||
final Card c4 = new ColoredCard("gnat", red);
|
||||
|
||||
List<Card> cards = List.of(k1, k2, k3, c1, c2, c3, c4);
|
||||
|
||||
for (Card x1 : cards) {
|
||||
System.out.println(x1);
|
||||
for (Card x2 : cards)
|
||||
if (x1.equals(x2))
|
||||
System.out.println(" equal to " + x2);
|
||||
else
|
||||
System.out.println(" NOT equal to " + x2);
|
||||
}
|
||||
}
|
||||
}
|
23
src/oop/ch04/equality/rational1/Example.java
Normal file
23
src/oop/ch04/equality/rational1/Example.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package oop.ch04.equality.rational1;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
Rational r1 = new Rational(1, 2);
|
||||
Rational r2 = new Rational(2, 4);
|
||||
System.out.println(r1 == r2);
|
||||
System.out.println(r1.equals(r2));
|
||||
|
||||
Set<Rational> s1 = new HashSet<>();
|
||||
s1.add(new Rational(1, 2));
|
||||
s1.add(new Rational(1, 2));
|
||||
System.out.println(s1);
|
||||
|
||||
Set<Rational> s2 = new HashSet<>();
|
||||
s2.add(new Rational(1, 2));
|
||||
s2.add(new Rational(1, 3));
|
||||
System.out.println(s2.contains(new Rational(1, 3)));
|
||||
}
|
||||
}
|
117
src/oop/ch04/equality/rational1/Rational.java
Normal file
117
src/oop/ch04/equality/rational1/Rational.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package oop.ch04.equality.rational1;
|
||||
|
||||
public class Rational {
|
||||
private final int num;
|
||||
private final int denom;
|
||||
|
||||
public Rational(int num, int denom) {
|
||||
int gcd = gcDivider(Math.abs(num), Math.abs(denom));
|
||||
if (denom < 0) {
|
||||
this.num = -num / gcd;
|
||||
this.denom = -denom / gcd;
|
||||
}
|
||||
else {
|
||||
this.num = num / gcd;
|
||||
this.denom = denom / gcd;
|
||||
}
|
||||
}
|
||||
|
||||
public Rational(int num) {
|
||||
this(num, 1);
|
||||
}
|
||||
|
||||
private int gcDivider(int x, int y) {
|
||||
return x == 0 ? y : gcDivider(y % x, x);
|
||||
}
|
||||
|
||||
public int getNum() {
|
||||
return num;
|
||||
}
|
||||
|
||||
public int getDenom() {
|
||||
return denom;
|
||||
}
|
||||
|
||||
public Rational add(Rational r) {
|
||||
return new Rational(num * r.denom + denom * r.num, denom * r.denom);
|
||||
}
|
||||
|
||||
public Rational add(int i) {
|
||||
return this.add(new Rational(i));
|
||||
}
|
||||
|
||||
public Rational sub(Rational r) {
|
||||
return new Rational(num * r.denom - denom * r.num, denom * r.denom);
|
||||
}
|
||||
|
||||
public Rational sub(int i) {
|
||||
return this.sub(new Rational(i));
|
||||
}
|
||||
|
||||
public Rational mult(Rational r) {
|
||||
return new Rational(num * r.num, denom * r.denom);
|
||||
}
|
||||
|
||||
public Rational mult(int i) {
|
||||
return this.mult(new Rational(i));
|
||||
}
|
||||
|
||||
public Rational div(Rational r) {
|
||||
return new Rational(num * r.denom, denom * r.num);
|
||||
}
|
||||
|
||||
public Rational div(int i) {
|
||||
return this.div(new Rational(i));
|
||||
}
|
||||
|
||||
public boolean lessThan(Rational r) {
|
||||
return (this.sub(r).num < 0);
|
||||
}
|
||||
|
||||
public boolean lessThan(int i) {
|
||||
return (this.sub(i).num < 0);
|
||||
}
|
||||
|
||||
public boolean greaterThan(Rational r) {
|
||||
return (this.sub(r).num > 0);
|
||||
}
|
||||
|
||||
public boolean greaterThan(int i) {
|
||||
return (this.sub(i).num > 0);
|
||||
}
|
||||
|
||||
public boolean lessThanOrEqual(Rational r) {
|
||||
return (this.sub(r).num <= 0);
|
||||
}
|
||||
|
||||
public boolean lessThanOrEqual(int i) {
|
||||
return (this.sub(i).num <= 0);
|
||||
}
|
||||
|
||||
public boolean greaterThanOrEqual(Rational r) {
|
||||
return (this.sub(r).num <= 0);
|
||||
}
|
||||
|
||||
public boolean greaterThanOrEqual(int i) {
|
||||
return (this.sub(i).num <= 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (o instanceof Rational) {
|
||||
final Rational that = (Rational) o;
|
||||
return this.denom == that.denom && this.num == that.num;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean equals(int i) {
|
||||
return this.equals(new Rational(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return denom == 1 ? "" + num : num + "/" + denom;
|
||||
}
|
||||
}
|
23
src/oop/ch04/equality/rational2/Example.java
Normal file
23
src/oop/ch04/equality/rational2/Example.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package oop.ch04.equality.rational2;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
Rational r1 = new Rational(1, 2);
|
||||
Rational r2 = new Rational(2, 4);
|
||||
System.out.println(r1 == r2);
|
||||
System.out.println(r1.equals(r2));
|
||||
|
||||
Set<Rational> s1 = new HashSet<>();
|
||||
s1.add(new Rational(1, 2));
|
||||
s1.add(new Rational(1, 2));
|
||||
System.out.println(s1);
|
||||
|
||||
Set<Rational> s2 = new HashSet<>();
|
||||
s2.add(new Rational(1, 2));
|
||||
s2.add(new Rational(1, 3));
|
||||
System.out.println(s2.contains(new Rational(1, 3)));
|
||||
}
|
||||
}
|
122
src/oop/ch04/equality/rational2/Rational.java
Normal file
122
src/oop/ch04/equality/rational2/Rational.java
Normal file
@@ -0,0 +1,122 @@
|
||||
package oop.ch04.equality.rational2;
|
||||
|
||||
public class Rational {
|
||||
private final int num;
|
||||
private final int denom;
|
||||
|
||||
public Rational(int num, int denom) {
|
||||
int gcd = gcDivider(Math.abs(num), Math.abs(denom));
|
||||
if (denom < 0) {
|
||||
this.num = -num / gcd;
|
||||
this.denom = -denom / gcd;
|
||||
}
|
||||
else {
|
||||
this.num = num / gcd;
|
||||
this.denom = denom / gcd;
|
||||
}
|
||||
}
|
||||
|
||||
public Rational(int num) {
|
||||
this(num, 1);
|
||||
}
|
||||
|
||||
private int gcDivider(int x, int y) {
|
||||
return x == 0 ? y : gcDivider(y % x, x);
|
||||
}
|
||||
|
||||
public int getNum() {
|
||||
return num;
|
||||
}
|
||||
|
||||
public int getDenom() {
|
||||
return denom;
|
||||
}
|
||||
|
||||
public Rational add(Rational r) {
|
||||
return new Rational(num * r.denom + denom * r.num, denom * r.denom);
|
||||
}
|
||||
|
||||
public Rational add(int i) {
|
||||
return this.add(new Rational(i));
|
||||
}
|
||||
|
||||
public Rational sub(Rational r) {
|
||||
return new Rational(num * r.denom - denom * r.num, denom * r.denom);
|
||||
}
|
||||
|
||||
public Rational sub(int i) {
|
||||
return this.sub(new Rational(i));
|
||||
}
|
||||
|
||||
public Rational mult(Rational r) {
|
||||
return new Rational(num * r.num, denom * r.denom);
|
||||
}
|
||||
|
||||
public Rational mult(int i) {
|
||||
return this.mult(new Rational(i));
|
||||
}
|
||||
|
||||
public Rational div(Rational r) {
|
||||
return new Rational(num * r.denom, denom * r.num);
|
||||
}
|
||||
|
||||
public Rational div(int i) {
|
||||
return this.div(new Rational(i));
|
||||
}
|
||||
|
||||
public boolean lessThan(Rational r) {
|
||||
return (this.sub(r).num < 0);
|
||||
}
|
||||
|
||||
public boolean lessThan(int i) {
|
||||
return (this.sub(i).num < 0);
|
||||
}
|
||||
|
||||
public boolean greaterThan(Rational r) {
|
||||
return (this.sub(r).num > 0);
|
||||
}
|
||||
|
||||
public boolean greaterThan(int i) {
|
||||
return (this.sub(i).num > 0);
|
||||
}
|
||||
|
||||
public boolean lessThanOrEqual(Rational r) {
|
||||
return (this.sub(r).num <= 0);
|
||||
}
|
||||
|
||||
public boolean lessThanOrEqual(int i) {
|
||||
return (this.sub(i).num <= 0);
|
||||
}
|
||||
|
||||
public boolean greaterThanOrEqual(Rational r) {
|
||||
return (this.sub(r).num <= 0);
|
||||
}
|
||||
|
||||
public boolean greaterThanOrEqual(int i) {
|
||||
return (this.sub(i).num <= 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (o instanceof Rational) {
|
||||
final Rational that = (Rational) o;
|
||||
return this.denom == that.denom && this.num == that.num;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return num + denom;
|
||||
}
|
||||
|
||||
public boolean equals(int i) {
|
||||
return this.equals(new Rational(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return denom == 1 ? "" + num : num + "/" + denom;
|
||||
}
|
||||
}
|
22
src/oop/ch05/generic/example/AutoContainer.java
Normal file
22
src/oop/ch05/generic/example/AutoContainer.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package oop.ch05.generic.example;
|
||||
|
||||
import oop.ch03.vehicles.Auto;
|
||||
|
||||
public class AutoContainer {
|
||||
private final double maxAchsLast;
|
||||
private Auto contained;
|
||||
|
||||
public AutoContainer(double maxAchsLast) {
|
||||
this.maxAchsLast = maxAchsLast;
|
||||
}
|
||||
|
||||
public Auto getContained() {
|
||||
return contained;
|
||||
}
|
||||
|
||||
public void setContained(Auto auto) {
|
||||
if (auto.getAchslast() > maxAchsLast)
|
||||
throw new IllegalArgumentException("Too heavy");
|
||||
this.contained = auto;
|
||||
}
|
||||
}
|
54
src/oop/ch05/generic/example/Example.java
Normal file
54
src/oop/ch05/generic/example/Example.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package oop.ch05.generic.example;
|
||||
|
||||
import oop.ch03.vehicles.Amphibienfahrzeug;
|
||||
import oop.ch03.vehicles.AmphibienfahrzeugImpl;
|
||||
import oop.ch03.vehicles.Auto;
|
||||
import oop.ch03.vehicles.AutoImpl;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
plainTest();
|
||||
genericTest();
|
||||
}
|
||||
|
||||
public static void plainTest() {
|
||||
final Amphibienfahrzeug alligator = new AmphibienfahrzeugImpl(750, 8000);
|
||||
final Auto golf = new AutoImpl(500);
|
||||
|
||||
final AutoContainer c = new AutoContainer(1000);
|
||||
|
||||
c.setContained(alligator);
|
||||
System.out.println("Tiefgang: " + getTiefgang(c));
|
||||
|
||||
c.setContained(golf);
|
||||
System.out.println("Tiefgang: " + getTiefgang(c));
|
||||
}
|
||||
|
||||
public static void genericTest() {
|
||||
final Amphibienfahrzeug alligator = new AmphibienfahrzeugImpl(750, 8000);
|
||||
final Auto golf = new AutoImpl(500);
|
||||
|
||||
final GenericContainer<Amphibienfahrzeug> c1 = new GenericContainer<>(1000);
|
||||
|
||||
c1.setContained(alligator);
|
||||
System.out.println("Tiefgang: " + getTiefgang(c1));
|
||||
|
||||
// incompatible types: oop.ch04.vehicles.Auto cannot be converted to oop.ch04.vehicles.Amphibienfahrzeug
|
||||
// c1.setContained(golf);
|
||||
System.out.println("Tiefgang: " + getTiefgang(c1));
|
||||
|
||||
final GenericContainer<Auto> c2 = new GenericContainer<>(1000);
|
||||
c2.setContained(golf);
|
||||
// no suitable method found for getTiefgang(oop.ch05.generic.example.GenericContainer<oop.ch04.vehicles.Auto>)
|
||||
// System.out.println("Tiefgang: " + getTiefgang(c2));
|
||||
}
|
||||
|
||||
public static double getTiefgang(AutoContainer container) {
|
||||
final Amphibienfahrzeug contained = (Amphibienfahrzeug) container.getContained();
|
||||
return contained.getTiefgang();
|
||||
}
|
||||
|
||||
public static double getTiefgang(GenericContainer<Amphibienfahrzeug> container) {
|
||||
return container.getContained().getTiefgang();
|
||||
}
|
||||
}
|
22
src/oop/ch05/generic/example/GenericContainer.java
Normal file
22
src/oop/ch05/generic/example/GenericContainer.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package oop.ch05.generic.example;
|
||||
|
||||
import oop.ch03.vehicles.Auto;
|
||||
|
||||
public class GenericContainer<A extends Auto> {
|
||||
private final double maxAchsLast;
|
||||
private A contained;
|
||||
|
||||
public GenericContainer(double maxAchsLast) {
|
||||
this.maxAchsLast = maxAchsLast;
|
||||
}
|
||||
|
||||
public A getContained() {
|
||||
return contained;
|
||||
}
|
||||
|
||||
public void setContained(A auto) {
|
||||
if (auto.getAchslast() > maxAchsLast)
|
||||
throw new IllegalArgumentException("Too heavy");
|
||||
this.contained = auto;
|
||||
}
|
||||
}
|
34
src/oop/ch05/generic/mensa/AccountCard.java
Normal file
34
src/oop/ch05/generic/mensa/AccountCard.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
import oop.ch05.generic.secured.AuthorizationException;
|
||||
import oop.ch05.generic.secured.SecuredContent;
|
||||
import oop.ch05.generic.secured.SecurityClient;
|
||||
|
||||
public class AccountCard extends MensaCard {
|
||||
private final SecuredContent<String> account;
|
||||
|
||||
public AccountCard(String key, String account, int password) {
|
||||
super(key, Color.white);
|
||||
this.account = new SecuredContent<>(password, account);
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return account.getContent();
|
||||
}
|
||||
|
||||
public void setAccount(SecurityClient client, String account) throws AuthorizationException {
|
||||
if (account == null || account.trim().length() == 0)
|
||||
throw new IllegalArgumentException("Invalid account " + account);
|
||||
this.account.setContent(client, account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " for account " + account.getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pass(CashPoint cashPoint) {
|
||||
cashPoint.charge(this);
|
||||
}
|
||||
}
|
43
src/oop/ch05/generic/mensa/CashCard.java
Normal file
43
src/oop/ch05/generic/mensa/CashCard.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
import oop.ch05.generic.secured.AuthorizationException;
|
||||
import oop.ch05.generic.secured.SecuredContent;
|
||||
|
||||
public class CashCard extends MensaCard {
|
||||
private final SecuredContent<Integer> balance;
|
||||
|
||||
public CashCard(String key, Color color, int password) {
|
||||
super(key, color);
|
||||
balance = new SecuredContent<>(password, 0);
|
||||
if (color != Color.blue && color != Color.green)
|
||||
throw new IllegalArgumentException("Invalid CashCard color " + color);
|
||||
}
|
||||
|
||||
public int getBalance() {
|
||||
return balance.getContent();
|
||||
}
|
||||
|
||||
void deposit(VendingMachine client, int cents)
|
||||
throws AuthorizationException {
|
||||
if (cents <= 0)
|
||||
throw new IllegalArgumentException("Non-positive deposit");
|
||||
final int newBalance = getBalance() + cents;
|
||||
balance.setContent(client, newBalance);
|
||||
}
|
||||
|
||||
void charge(CashPoint client, int cents) throws AuthorizationException {
|
||||
if (cents < 0)
|
||||
throw new IllegalArgumentException("Negative charge");
|
||||
balance.setContent(client, getBalance() - cents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " with " + balance.getContent() + " cents";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pass(CashPoint cashPoint) throws AuthorizationException, RejectedException {
|
||||
cashPoint.charge(this);
|
||||
}
|
||||
}
|
64
src/oop/ch05/generic/mensa/CashPoint.java
Normal file
64
src/oop/ch05/generic/mensa/CashPoint.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
import oop.ch05.generic.secured.AuthorizationException;
|
||||
import oop.ch05.generic.secured.SecurityClient;
|
||||
|
||||
public class CashPoint implements SecurityClient {
|
||||
private final int password;
|
||||
public final String name;
|
||||
private int counter;
|
||||
private int cents;
|
||||
|
||||
public CashPoint(String name, int password) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.counter = 0;
|
||||
this.cents = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int challengeResponse(int challenge) {
|
||||
return challenge ^ password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Cash point " + name + " (" + getCounter() + " meals, " + getCents() + " cents charged)";
|
||||
}
|
||||
|
||||
public int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
public int getCents() {
|
||||
return cents;
|
||||
}
|
||||
|
||||
private int getPrice(Color color) {
|
||||
return switch (color) {
|
||||
case green -> 267;
|
||||
case blue -> 357;
|
||||
case white -> 495;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
void count(MensaCard card) {
|
||||
counter++;
|
||||
}
|
||||
|
||||
void charge(CashCard cashCard) throws AuthorizationException, RejectedException {
|
||||
final int price = getPrice(cashCard.color);
|
||||
if (cashCard.getBalance() < price)
|
||||
throw new RejectedException("insufficient payment");
|
||||
cashCard.charge(this, price);
|
||||
count(cashCard);
|
||||
cents += price;
|
||||
}
|
||||
|
||||
void charge(AccountCard accountCard) {
|
||||
final int price = getPrice(accountCard.color);
|
||||
System.out.println("Charging " + price + " cents on account " + accountCard.getAccount());
|
||||
cents += price;
|
||||
}
|
||||
}
|
5
src/oop/ch05/generic/mensa/Color.java
Normal file
5
src/oop/ch05/generic/mensa/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
public enum Color {
|
||||
green, red, blue, white, gray
|
||||
}
|
15
src/oop/ch05/generic/mensa/CountCard.java
Normal file
15
src/oop/ch05/generic/mensa/CountCard.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
public class CountCard extends MensaCard {
|
||||
|
||||
public CountCard(String key, Color color) {
|
||||
super(key, color);
|
||||
if (color != Color.red && color != Color.gray)
|
||||
throw new IllegalArgumentException("Invalid CountCard color " + color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pass(CashPoint cashPoint) {
|
||||
cashPoint.count(this);
|
||||
}
|
||||
}
|
20
src/oop/ch05/generic/mensa/MensaCard.java
Normal file
20
src/oop/ch05/generic/mensa/MensaCard.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
import oop.ch02.cards.Card;
|
||||
import oop.ch05.generic.secured.AuthorizationException;
|
||||
|
||||
public abstract class MensaCard extends Card {
|
||||
public final Color color;
|
||||
|
||||
protected MensaCard(String name, Color color) {
|
||||
super(name);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return color + " card " + getNumber() + " (" + getName() + ")";
|
||||
}
|
||||
|
||||
public abstract void pass(CashPoint cashPoint) throws RejectedException, AuthorizationException;
|
||||
}
|
68
src/oop/ch05/generic/mensa/MensaExample.java
Normal file
68
src/oop/ch05/generic/mensa/MensaExample.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
import oop.ch05.generic.secured.AuthorizationException;
|
||||
|
||||
public class MensaExample {
|
||||
public static void main(String[] args) {
|
||||
VendingMachine vm1 = new VendingMachine("left", 4711);
|
||||
VendingMachine vm2 = new VendingMachine("right", 4711);
|
||||
VendingMachine tumVM = new VendingMachine("TUM Mensa", 3141);
|
||||
CashPoint unibwMensa = new CashPoint("UniBw Mensa", 4711);
|
||||
|
||||
AccountCard conf = new AccountCard("conference", "33-1298", 42);
|
||||
MensaCard frankSmith = new CountCard("Frank Smith", Color.gray);
|
||||
CashCard hansMueller = new CashCard("Hans Müller", Color.green, 4711);
|
||||
CashCard peterSchmidt = new CashCard("Peter Schmidt", Color.green, 4711);
|
||||
CashCard thomasMayer = new CashCard("Thomas Mayer", Color.blue, 4711);
|
||||
|
||||
deposit(vm1, hansMueller, 10);
|
||||
deposit(vm1, peterSchmidt, 5);
|
||||
deposit(vm2, thomasMayer, 2);
|
||||
deposit(tumVM, hansMueller, 10);
|
||||
|
||||
System.out.println(vm1);
|
||||
System.out.println(vm2);
|
||||
System.out.println(tumVM);
|
||||
System.out.println(hansMueller);
|
||||
System.out.println(peterSchmidt);
|
||||
System.out.println(thomasMayer);
|
||||
System.out.println();
|
||||
|
||||
pass(hansMueller, unibwMensa);
|
||||
System.out.println(hansMueller);
|
||||
System.out.println(unibwMensa);
|
||||
|
||||
pass(frankSmith, unibwMensa);
|
||||
pass(conf, unibwMensa);
|
||||
pass(thomasMayer, unibwMensa);
|
||||
pass(hansMueller, unibwMensa);
|
||||
pass(hansMueller, unibwMensa);
|
||||
pass(hansMueller, unibwMensa);
|
||||
|
||||
System.out.println(unibwMensa);
|
||||
System.out.println(hansMueller);
|
||||
System.out.println(peterSchmidt);
|
||||
System.out.println(thomasMayer);
|
||||
}
|
||||
|
||||
private static void pass(MensaCard mensaCard, CashPoint cashPoint) {
|
||||
try {
|
||||
mensaCard.pass(cashPoint);
|
||||
}
|
||||
catch (RejectedException e) {
|
||||
System.out.println("rejected: " + e.getMessage());
|
||||
}
|
||||
catch (AuthorizationException e) {
|
||||
System.out.println("authrozation failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void deposit(VendingMachine vm, CashCard cashCard, int euros) {
|
||||
try {
|
||||
vm.deposit(cashCard, euros);
|
||||
}
|
||||
catch (AuthorizationException e) {
|
||||
System.out.println("authorization failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
7
src/oop/ch05/generic/mensa/RejectedException.java
Normal file
7
src/oop/ch05/generic/mensa/RejectedException.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
public class RejectedException extends Exception {
|
||||
public RejectedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
37
src/oop/ch05/generic/mensa/VendingMachine.java
Normal file
37
src/oop/ch05/generic/mensa/VendingMachine.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package oop.ch05.generic.mensa;
|
||||
|
||||
import oop.ch05.generic.secured.AuthorizationException;
|
||||
import oop.ch05.generic.secured.SecurityClient;
|
||||
|
||||
public class VendingMachine implements SecurityClient {
|
||||
private final int password;
|
||||
public final String name;
|
||||
private int euros;
|
||||
|
||||
public VendingMachine(String name, int password) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.euros = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int challengeResponse(int challenge) {
|
||||
return challenge ^ password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Vending machine " + name + " (contains EUR " + euros + ")";
|
||||
}
|
||||
|
||||
public int getEuros() {
|
||||
return euros;
|
||||
}
|
||||
|
||||
public void deposit(CashCard card, int euros) throws AuthorizationException {
|
||||
if (euros <= 0)
|
||||
throw new IllegalArgumentException("Non-positive deposit");
|
||||
card.deposit(this, euros * 100);
|
||||
this.euros += euros;
|
||||
}
|
||||
}
|
20
src/oop/ch05/generic/secured/AuthorizationException.java
Normal file
20
src/oop/ch05/generic/secured/AuthorizationException.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package oop.ch05.generic.secured;
|
||||
|
||||
/**
|
||||
* This class represents exceptions that are thrown whenever an authorization
|
||||
* fails.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class AuthorizationException extends Exception {
|
||||
/**
|
||||
* Constructs a new authorization exception with the specified detail message
|
||||
* and cause.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval by the
|
||||
* {@link #getMessage()} method).
|
||||
*/
|
||||
public AuthorizationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
80
src/oop/ch05/generic/secured/SecuredContent.java
Normal file
80
src/oop/ch05/generic/secured/SecuredContent.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package oop.ch05.generic.secured;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Represents containers for some content that is secured against modifications
|
||||
* by a challenge-response approach. The content may be read at any time, but
|
||||
* only authorized clients are allowed to modify the contents.
|
||||
*
|
||||
* @param <E> the type of the actual secured content
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class SecuredContent<E> {
|
||||
/**
|
||||
* The actual, secured content
|
||||
*/
|
||||
private E content;
|
||||
/**
|
||||
* A random number generator used for generating challenges.
|
||||
*/
|
||||
private final Random random = new Random();
|
||||
/**
|
||||
* The password used for encryption.
|
||||
*/
|
||||
private final int password;
|
||||
|
||||
/**
|
||||
* Creates a new container containing the specified contents.
|
||||
*
|
||||
* @param password this password is used for computing the expected response for a
|
||||
* challenge.
|
||||
* @param content the contained content
|
||||
*/
|
||||
public SecuredContent(int password, E content) {
|
||||
this.password = password;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contained contents. There is no authorization necessary for
|
||||
* reading the contents.
|
||||
*/
|
||||
public E getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new contained contents. Only authorized clients are allowed to do
|
||||
* so.
|
||||
*
|
||||
* @param client The accessing client. Authorization is checked prior to really
|
||||
* modifying he contained content.
|
||||
* @param content The new contained contents
|
||||
* @throws AuthorizationException if the specified client cannot authorize himself
|
||||
*/
|
||||
public void setContent(SecurityClient client, E content)
|
||||
throws AuthorizationException {
|
||||
final int challenge = nextChallenge();
|
||||
if (client.challengeResponse(challenge) != requiredResponse(challenge))
|
||||
throw new AuthorizationException(client
|
||||
+ " is not authorized to access contents.");
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the next random challenge.
|
||||
*/
|
||||
private int nextChallenge() {
|
||||
return random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expected response for the specified challenge.
|
||||
*
|
||||
* @param challenge an arbitrary integer used as a challenge
|
||||
*/
|
||||
private int requiredResponse(int challenge) {
|
||||
return challenge ^ password;
|
||||
}
|
||||
}
|
18
src/oop/ch05/generic/secured/SecurityClient.java
Normal file
18
src/oop/ch05/generic/secured/SecurityClient.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package oop.ch05.generic.secured;
|
||||
|
||||
/**
|
||||
* This interface must be implemented by any client that is going to be
|
||||
* authorized by a challenge-response approach.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public interface SecurityClient {
|
||||
/**
|
||||
* Returns the response for the specified challenge. Authorization succeeds
|
||||
* if this response is the same as the one expected by the server.
|
||||
*
|
||||
* @param challenge the integer number for which the correct response has to be
|
||||
* computed.
|
||||
*/
|
||||
int challengeResponse(int challenge);
|
||||
}
|
34
src/oop/ch05/mensa/AccountCard.java
Normal file
34
src/oop/ch05/mensa/AccountCard.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
import oop.ch05.secured.AuthorizationException;
|
||||
import oop.ch05.secured.SecuredContent;
|
||||
import oop.ch05.secured.SecurityClient;
|
||||
|
||||
public class AccountCard extends MensaCard {
|
||||
private final SecuredContent account;
|
||||
|
||||
public AccountCard(String key, String account, int password) {
|
||||
super(key, Color.white);
|
||||
this.account = new SecuredContent(password, account);
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return (String) account.getContent();
|
||||
}
|
||||
|
||||
public void setAccount(SecurityClient client, String account) throws AuthorizationException {
|
||||
if (account == null || account.trim().length() == 0)
|
||||
throw new IllegalArgumentException("Invalid account " + account);
|
||||
this.account.setContent(client, account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " for account " + account.getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pass(CashPoint cashPoint) {
|
||||
cashPoint.charge(this);
|
||||
}
|
||||
}
|
43
src/oop/ch05/mensa/CashCard.java
Normal file
43
src/oop/ch05/mensa/CashCard.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
import oop.ch05.secured.AuthorizationException;
|
||||
import oop.ch05.secured.SecuredContent;
|
||||
|
||||
public class CashCard extends MensaCard {
|
||||
private final SecuredContent balance;
|
||||
|
||||
public CashCard(String key, Color color, int password) {
|
||||
super(key, color);
|
||||
balance = new SecuredContent(password, 0);
|
||||
if (color != Color.blue && color != Color.green)
|
||||
throw new IllegalArgumentException("Invalid CashCard color " + color);
|
||||
}
|
||||
|
||||
public int getBalance() {
|
||||
return (Integer) balance.getContent();
|
||||
}
|
||||
|
||||
void deposit(VendingMachine client, int cents)
|
||||
throws AuthorizationException {
|
||||
if (cents <= 0)
|
||||
throw new IllegalArgumentException("Non-positive deposit");
|
||||
final int newBalance = getBalance() + cents;
|
||||
balance.setContent(client, newBalance);
|
||||
}
|
||||
|
||||
void charge(CashPoint client, int cents) throws AuthorizationException {
|
||||
if (cents < 0)
|
||||
throw new IllegalArgumentException("Negative charge");
|
||||
balance.setContent(client, getBalance() - cents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " with " + balance.getContent() + " cents";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pass(CashPoint cashPoint) throws AuthorizationException, RejectedException {
|
||||
cashPoint.charge(this);
|
||||
}
|
||||
}
|
64
src/oop/ch05/mensa/CashPoint.java
Normal file
64
src/oop/ch05/mensa/CashPoint.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
import oop.ch05.secured.AuthorizationException;
|
||||
import oop.ch05.secured.SecurityClient;
|
||||
|
||||
public class CashPoint implements SecurityClient {
|
||||
private final int password;
|
||||
public final String name;
|
||||
private int counter;
|
||||
private int cents;
|
||||
|
||||
public CashPoint(String name, int password) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.counter = 0;
|
||||
this.cents = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int challengeResponse(int challenge) {
|
||||
return challenge ^ password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Cash point " + name + " (" + getCounter() + " meals, " + getCents() + " cents charged)";
|
||||
}
|
||||
|
||||
public int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
public int getCents() {
|
||||
return cents;
|
||||
}
|
||||
|
||||
private int getPrice(Color color) {
|
||||
return switch (color) {
|
||||
case green -> 267;
|
||||
case blue -> 357;
|
||||
case white -> 495;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
void count(MensaCard card) {
|
||||
counter++;
|
||||
}
|
||||
|
||||
void charge(CashCard cashCard) throws AuthorizationException, RejectedException {
|
||||
final int price = getPrice(cashCard.color);
|
||||
if (cashCard.getBalance() < price)
|
||||
throw new RejectedException("insufficient payment");
|
||||
cashCard.charge(this, price);
|
||||
count(cashCard);
|
||||
cents += price;
|
||||
}
|
||||
|
||||
void charge(AccountCard accountCard) {
|
||||
final int price = getPrice(accountCard.color);
|
||||
System.out.println("Charging " + price + " cents on account " + accountCard.getAccount());
|
||||
cents += price;
|
||||
}
|
||||
}
|
5
src/oop/ch05/mensa/Color.java
Normal file
5
src/oop/ch05/mensa/Color.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
public enum Color {
|
||||
green, red, blue, white, gray
|
||||
}
|
15
src/oop/ch05/mensa/CountCard.java
Normal file
15
src/oop/ch05/mensa/CountCard.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
public class CountCard extends MensaCard {
|
||||
|
||||
public CountCard(String key, Color color) {
|
||||
super(key, color);
|
||||
if (color != Color.red && color != Color.gray)
|
||||
throw new IllegalArgumentException("Invalid CountCard color " + color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pass(CashPoint cashPoint) {
|
||||
cashPoint.count(this);
|
||||
}
|
||||
}
|
20
src/oop/ch05/mensa/MensaCard.java
Normal file
20
src/oop/ch05/mensa/MensaCard.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
import oop.ch02.cards.Card;
|
||||
import oop.ch05.secured.AuthorizationException;
|
||||
|
||||
public abstract class MensaCard extends Card {
|
||||
public final Color color;
|
||||
|
||||
protected MensaCard(String name, Color color) {
|
||||
super(name);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return color + " card " + getNumber() + " (" + getName() + ")";
|
||||
}
|
||||
|
||||
public abstract void pass(CashPoint cashPoint) throws RejectedException, AuthorizationException;
|
||||
}
|
68
src/oop/ch05/mensa/MensaExample.java
Normal file
68
src/oop/ch05/mensa/MensaExample.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
import oop.ch05.secured.AuthorizationException;
|
||||
|
||||
public class MensaExample {
|
||||
public static void main(String[] args) {
|
||||
VendingMachine vm1 = new VendingMachine("left", 4711);
|
||||
VendingMachine vm2 = new VendingMachine("right", 4711);
|
||||
VendingMachine tumVM = new VendingMachine("TUM Mensa", 3141);
|
||||
CashPoint unibwMensa = new CashPoint("UniBw Mensa", 4711);
|
||||
|
||||
AccountCard conf = new AccountCard("conference", "33-1298", 42);
|
||||
MensaCard frankSmith = new CountCard("Frank Smith", Color.gray);
|
||||
CashCard hansMueller = new CashCard("Hans Müller", Color.green, 4711);
|
||||
CashCard peterSchmidt = new CashCard("Peter Schmidt", Color.green, 4711);
|
||||
CashCard thomasMayer = new CashCard("Thomas Mayer", Color.blue, 4711);
|
||||
|
||||
deposit(vm1, hansMueller, 10);
|
||||
deposit(vm1, peterSchmidt, 5);
|
||||
deposit(vm2, thomasMayer, 2);
|
||||
deposit(tumVM, hansMueller, 10);
|
||||
|
||||
System.out.println(vm1);
|
||||
System.out.println(vm2);
|
||||
System.out.println(tumVM);
|
||||
System.out.println(hansMueller);
|
||||
System.out.println(peterSchmidt);
|
||||
System.out.println(thomasMayer);
|
||||
System.out.println();
|
||||
|
||||
pass(hansMueller, unibwMensa);
|
||||
System.out.println(hansMueller);
|
||||
System.out.println(unibwMensa);
|
||||
|
||||
pass(frankSmith, unibwMensa);
|
||||
pass(conf, unibwMensa);
|
||||
pass(thomasMayer, unibwMensa);
|
||||
pass(hansMueller, unibwMensa);
|
||||
pass(hansMueller, unibwMensa);
|
||||
pass(hansMueller, unibwMensa);
|
||||
|
||||
System.out.println(unibwMensa);
|
||||
System.out.println(hansMueller);
|
||||
System.out.println(peterSchmidt);
|
||||
System.out.println(thomasMayer);
|
||||
}
|
||||
|
||||
private static void pass(MensaCard mensaCard, CashPoint cashPoint) {
|
||||
try {
|
||||
mensaCard.pass(cashPoint);
|
||||
}
|
||||
catch (RejectedException e) {
|
||||
System.out.println("rejected: " + e.getMessage());
|
||||
}
|
||||
catch (AuthorizationException e) {
|
||||
System.out.println("authrozation failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void deposit(VendingMachine vm, CashCard cashCard, int euros) {
|
||||
try {
|
||||
vm.deposit(cashCard, euros);
|
||||
}
|
||||
catch (AuthorizationException e) {
|
||||
System.out.println("authorization failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
7
src/oop/ch05/mensa/RejectedException.java
Normal file
7
src/oop/ch05/mensa/RejectedException.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
public class RejectedException extends Exception {
|
||||
public RejectedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
37
src/oop/ch05/mensa/VendingMachine.java
Normal file
37
src/oop/ch05/mensa/VendingMachine.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package oop.ch05.mensa;
|
||||
|
||||
import oop.ch05.secured.AuthorizationException;
|
||||
import oop.ch05.secured.SecurityClient;
|
||||
|
||||
public class VendingMachine implements SecurityClient {
|
||||
private final int password;
|
||||
public final String name;
|
||||
private int euros;
|
||||
|
||||
public VendingMachine(String name, int password) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.euros = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int challengeResponse(int challenge) {
|
||||
return challenge ^ password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Vending machine " + name + " (contains EUR " + euros + ")";
|
||||
}
|
||||
|
||||
public int getEuros() {
|
||||
return euros;
|
||||
}
|
||||
|
||||
public void deposit(CashCard card, int euros) throws AuthorizationException {
|
||||
if (euros <= 0)
|
||||
throw new IllegalArgumentException("Non-positive deposit");
|
||||
card.deposit(this, euros * 100);
|
||||
this.euros += euros;
|
||||
}
|
||||
}
|
20
src/oop/ch05/secured/AuthorizationException.java
Normal file
20
src/oop/ch05/secured/AuthorizationException.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package oop.ch05.secured;
|
||||
|
||||
/**
|
||||
* This class represents exceptions that are thrown whenever an authorization
|
||||
* fails.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class AuthorizationException extends Exception {
|
||||
/**
|
||||
* Constructs a new authorization exception with the specified detail message
|
||||
* and cause.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval by the
|
||||
* {@link #getMessage()} method).
|
||||
*/
|
||||
public AuthorizationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
79
src/oop/ch05/secured/SecuredContent.java
Normal file
79
src/oop/ch05/secured/SecuredContent.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package oop.ch05.secured;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Represents containers for some content that is secured against modifications
|
||||
* by a challenge-response approach. The content may be read at any time, but
|
||||
* only authorized clients are allowed to modify the contents.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public class SecuredContent {
|
||||
/**
|
||||
* The actual, secured content
|
||||
*/
|
||||
private Object content;
|
||||
/**
|
||||
* A random number generator used for generating challenges.
|
||||
*/
|
||||
private final Random random = new Random();
|
||||
/**
|
||||
* The password used for encryption.
|
||||
*/
|
||||
private final int password;
|
||||
|
||||
/**
|
||||
* Creates a new container containing the specified contents.
|
||||
*
|
||||
* @param password this password is used for computing the expected response for a
|
||||
* challenge.
|
||||
* @param content the contained content
|
||||
*/
|
||||
public SecuredContent(int password, Object content) {
|
||||
this.password = password;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contained contents. There is no authorization necessary for
|
||||
* reading the contents.
|
||||
*/
|
||||
public Object getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new contained contents. Only authorized clients are allowed to do
|
||||
* so.
|
||||
*
|
||||
* @param client The accessing client. Authorization is checked prior to really
|
||||
* modifying he contained content.
|
||||
* @param content The new contained contents
|
||||
* @throws AuthorizationException if the specified client cannot authorize himself
|
||||
*/
|
||||
public void setContent(SecurityClient client, Object content)
|
||||
throws AuthorizationException {
|
||||
final int challenge = nextChallenge();
|
||||
if (client.challengeResponse(challenge) != requiredResponse(challenge))
|
||||
throw new AuthorizationException(client
|
||||
+ " is not authorized to access contents.");
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the next random challenge.
|
||||
*/
|
||||
private int nextChallenge() {
|
||||
return random.nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expected response for the specified challenge.
|
||||
*
|
||||
* @param challenge an arbitrary integer used as a challenge
|
||||
*/
|
||||
private int requiredResponse(int challenge) {
|
||||
return challenge ^ password;
|
||||
}
|
||||
}
|
18
src/oop/ch05/secured/SecurityClient.java
Normal file
18
src/oop/ch05/secured/SecurityClient.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package oop.ch05.secured;
|
||||
|
||||
/**
|
||||
* This interface must be implemented by any client that is going to be
|
||||
* authorized by a challenge-response approach.
|
||||
*
|
||||
* @author Mark Minas
|
||||
*/
|
||||
public interface SecurityClient {
|
||||
/**
|
||||
* Returns the response for the specified challenge. Authorization succeeds
|
||||
* if this response is the same as the one expected by the server.
|
||||
*
|
||||
* @param challenge the integer number for which the correct response has to be
|
||||
* computed.
|
||||
*/
|
||||
int challengeResponse(int challenge);
|
||||
}
|
113
src/oop/ch06/calc/AdHocCalculator.java
Normal file
113
src/oop/ch06/calc/AdHocCalculator.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package oop.ch06.calc;
|
||||
|
||||
import oop.ch06.observer.ObserverSupport;
|
||||
|
||||
public class AdHocCalculator extends ObserverSupport {
|
||||
private double value;
|
||||
private double opnd1;
|
||||
private BinaryOp lastOp;
|
||||
private double factor;
|
||||
private boolean startedNumTyping;
|
||||
private boolean hasSecondOpnd;
|
||||
|
||||
public double getValue() {return value;}
|
||||
|
||||
private void setValue(double n) {
|
||||
value = n;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public void digit(int d) {
|
||||
if (!Double.isNaN(value)) {
|
||||
if (!startedNumTyping) {
|
||||
startedNumTyping = true;
|
||||
setValue(d);
|
||||
factor = 1.;
|
||||
}
|
||||
else if (factor < 1.) {
|
||||
setValue(value + factor * d);
|
||||
factor *= 0.1;
|
||||
}
|
||||
else
|
||||
setValue(10. * value + d);
|
||||
if (lastOp != null)
|
||||
hasSecondOpnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void dot() {
|
||||
if (!Double.isNaN(value)) {
|
||||
if (!startedNumTyping) {
|
||||
startedNumTyping = true;
|
||||
setValue(0);
|
||||
factor = 0.1;
|
||||
}
|
||||
else if (factor > 0.1)
|
||||
factor = 0.1;
|
||||
if (lastOp != null)
|
||||
hasSecondOpnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void unOp(UnaryOp op) {
|
||||
try {
|
||||
if (!Double.isNaN(value)) {
|
||||
startedNumTyping = false;
|
||||
setValue(op.eval(value));
|
||||
if (lastOp != null)
|
||||
hasSecondOpnd = true;
|
||||
}
|
||||
}
|
||||
catch (CalculatorError ex) {
|
||||
setValue(Double.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
public void binOp(BinaryOp op) {
|
||||
try {
|
||||
if (!Double.isNaN(value)) {
|
||||
startedNumTyping = false;
|
||||
if (lastOp == null) {
|
||||
opnd1 = value;
|
||||
hasSecondOpnd = false;
|
||||
}
|
||||
else if (hasSecondOpnd) {
|
||||
setValue(lastOp.eval(opnd1, value));
|
||||
opnd1 = value;
|
||||
}
|
||||
lastOp = op;
|
||||
}
|
||||
}
|
||||
catch (CalculatorError ex) {
|
||||
setValue(Double.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
public void eval() {
|
||||
try {
|
||||
if (!Double.isNaN(value) && lastOp != null) {
|
||||
startedNumTyping = false;
|
||||
setValue(lastOp.eval(opnd1, value));
|
||||
lastOp = null;
|
||||
}
|
||||
}
|
||||
catch (CalculatorError ex) {
|
||||
setValue(Double.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (!Double.isNaN(value)) {
|
||||
setValue(0);
|
||||
startedNumTyping = false;
|
||||
hasSecondOpnd = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void allClear() {
|
||||
setValue(0);
|
||||
startedNumTyping = false;
|
||||
hasSecondOpnd = false;
|
||||
lastOp = null;
|
||||
}
|
||||
}
|
9
src/oop/ch06/calc/BinaryOp.java
Normal file
9
src/oop/ch06/calc/BinaryOp.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package oop.ch06.calc;
|
||||
|
||||
public abstract class BinaryOp extends Op {
|
||||
protected BinaryOp(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public abstract double eval(double opnd1, double opnd2);
|
||||
}
|
7
src/oop/ch06/calc/CalculatorError.java
Normal file
7
src/oop/ch06/calc/CalculatorError.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package oop.ch06.calc;
|
||||
|
||||
public class CalculatorError extends RuntimeException {
|
||||
public CalculatorError(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user