Парадигмы программирования
Реализация ООП
// Pred: element ≠ null // Post: n' = n + 1 ∧ immutable(n) ∧ a'[n'] = element void push(Object element)
// Pred: n > 0 // Post: ℝ = a[n] ∧ n = n' − 1 ∧ immutable(n') Object pop()
// Pred: n > 0 // peek: ℝ = a[n] ∧ n = n' ∧ immutable(n) Object peek()
// Post: ℝ = n ∧ n = n' ∧ immutable(n) int size()
// Post: ℝ = n > 0 ∧ n = n' ∧ immutable(n) boolean isEmpty()
public class ArrayStackModule {
static int size; static Object[] elements = new Object[5];
static void push(Object element) {
Objects.requireNonNull(element);
ensureCapacity(size + 1);
elements[size++] = element;
}
static void ensureCapacity(int capacity) {
if (capacity > elements.length) {
elements =
Arrays.copyOf(elements, 2 * capacity);
}
}
static Object pop() {
assert size > 0;
return elements[--size];
}
static Object peek() {
assert size > 0;
return elements[size - 1];
}
static int size() {
return size;
}
static boolean isEmpty() {
return size == 0;
}
for (int i = 0; i < 10; i++) {
ArrayStackModule.push(i);
}
while (!ArrayStackModule.isEmpty()) {
System.out.println(
ArrayStackModule.size() + " " +
ArrayStackModule.peek() + " " +
ArrayStackModule.pop()
);
}
private static int size private static Object[] elements public push(Object element) public Object pop() public Object peek() public int size() public boolean isEmpty() private void ensureCapacity()
public class ArrayStackADT {
private /*static*/ int size;
private /*static*/ Object[] elements =
new Object[5];
public static void push(ArrayStackADT stack, Object element) {
Objects.requireNonNull(element);
ensureCapacity(stack, stack.size + 1);
stack.elements[stack.size++] = element;
}
private static void ensureCapacity(
ArrayStackADT stack, int capacity
) {
if (stack.elements.length < capacity) {
stack.elements =
Arrays.copyOf(stack.elements, capacity * 2);
}
}
public static Object pop(ArrayStackADT stack) {
assert stack.size > 0;
return stack.elements[--stack.size];
}
public static Object peek(ArrayStackADT stack) {
assert stack.size > 0;
return stack.elements[stack.size - 1];
}
public static int size(ArrayStackADT stack) {
return stack.size;
}
public static boolean isEmpty(
ArrayStackADT stack
) {
return stack.size == 0;
}
public static ArrayStackADT create() {
ArrayStackADT stack = new ArrayStackADT();
stack.elements = new Object[10];
return stack;
}
ArrayStackADT stack = ArrayStackADT.create();
for (int i = 0; i < 10; i++) {
ArrayStackADT.push(stack, i);
}
while (!ArrayStackADT.isEmpty(stack)) {
System.out.println(
ArrayStackADT.size(stack) + " " +
ArrayStackADT.peek(stack) + " " +
ArrayStackADT.pop(stack)
);
}
public class ArrayStack {
private int size; private Object[] elements = new Object[10];
public void push(Object element) {
Objects.requireNonNull(element);
ensureCapacity(size + 1);
elements[size++] = element;
}
private void ensureCapacity(int capacity) {
if (elements.length < capacity) {
elements =
Arrays.copyOf(elements, capacity * 2);
}
}
public Object pop() {
assert size > 0;
return elements[--size];
}
public Object peek() {
assert size > 0;
return elements[size - 1];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
ArrayStack stack = new ArrayStack();
for (int i = 0; i < 10; i++) {
stack.push(i);
}
while (!stack.isEmpty()) {
System.out.println(stack.size() + " " +
stack.peek() + " " + stack.pop());
}
// inv: value != null
public class Node {
Object value;
Node next;
}
public init(Object value, Node next) {
assert value != null;
this.value = value;
this.next = next;
}
value = null; next = null;
assert value != null; this.value = value; this.next = next;
public Node(Object value, Node next) {
assert value != null;
this.value = value;
this.next = next;
}
Node node = new Node(1, null);
public class LinkedStack {
private int size; private Node head;
// Pred: element ≠ null
// Post: n = n' + 1 ∧ ∀i=1..n' : a[i]' = a[i]∧
// ∧ a[n] = element
public void push(Object element) {
assert element != null;
size++;
head = new Node(element, head);
}
// Pred: n > 0
// Post: ℝ = a[n + 1] ∧ n = n' − 1 ∧
// ∧ ∀i=1..n : a[i]' = a[i]
public Object pop() {
assert size > 0;
size--;
Object result = head.value;
head = head.next;
return result;
}
// Pred: n > 0
// Post: ℝ = a[n] ∧ immutable
public Object peek() {
assert size > 0;
return head.value;
}
// Post: ℝ = n ∧ immutable
public int size() {
return size;
}
// Post: ℝ = n > 0 ∧ immutable
public boolean isEmpty() {
return size == 0;
}
LinkedStack stack = new LinkedStack();
for (int i = 0; i < 10; i++) {
stack.push(i);
}
while (!stack.isEmpty()) {
System.out.println(stack.size() + " " +
stack.peek() + " " + stack.pop());
}
public interface Stack {
/*public*/ void push(Object element);
/*public*/ Object pop();
/*public*/ Object peek();
/*public*/ int size();
/*public*/ boolean isEmpty();
}
public class ArrayStack implements Stack { ... }
public class LinkedStack implements Stack { ... }
public static void fill(Stack stack) {
for (int i = 0; i < 10; i++) {
stack.push(i);
}
}
public static void dump(Stack stack) {
while (!stack.isEmpty()) {
System.out.println(stack.size() + " " +
stack.peek() + " " + stack.pop());
}
}
class StackImpl {
public static void pop(Stack this) {
if (this instanceof ArrayStack) {
return ArrayStack.pop(this);
} else if (this instanceof LinkedStack) {
return LinkedStack.pop(this);
} else {
// ?
}
}
…
}

void test(LinkedStack stack) { … }
void test(ArrayStack stack) { … }
…
test(new LinkedList());
test(new ArrayList());
drawWithColor(Shape shape, Color color) {
shape.setColor(color);
shape.draw()
}
void draw(Shape shape) {
if (shape instanceof Rect) …
if (shape instanceof Circle) …
}
public isEmpty() {
return size == 0;
}
public peek() {
assert size > 0;
// Получить элемент
// Зависит от реализации
}
public peek() {
assert size > 0;
doPeek();
}
protected abstract Object doPeek();
protected doPeek() { // ArrayStack
return elements[size - 1];
}
protected doPeek() { // LinkedStack
return head.value;
}
public interface Copiable {
public Copiable makeCopy();
}
public class ArrayStack
implements Stack, Copiable {
public Copiable makeCopy() {
final ArrayStack copy = new ArrayStack();
copy.size = size;
copy.elements = elements;
return copy;
}
public Copiable makeCopy() {
final ArrayStack copy = new ArrayStack();
copy.size = size;
copy.elements = Arrays.copyOf(elements, size);
return copy;
}
public ArrayStack makeCopy() { ... }
public class LinkedStack
implements Stack, Copiable {
public LinkedStack makeCopy() {
final LinkedStack copy = new LinkedStack();
copy.size = size;
copy.head = head;
return copy;
}
public interface Stack extends Copiable { ... }
public interface Stack extends Copiable {
Stack makeCopy();
...
Stack stack = ...; Stack copy = stack.makeCopy();