Introdução aos Objectos/Exercício 02: Energia: Difference between revisions
From Wiki**3
| (35 intermediate revisions by the same user not shown) | |||
| Line 18: | Line 18: | ||
Considere que a energia disponível inicialmente para os cães, gatos, pássaros e ratos é, respectivamente, de 1000, 500, 20 e 50 unidades. Quando os animais correm, gastam, respectivamente, 50, 25, 5 e 2 unidades. Um pássaro, quando voa, gasta apenas 2 unidades. Um cão que ataque um gato gasta 100 unidades e faz com que o gato perca 25. | Considere que a energia disponível inicialmente para os cães, gatos, pássaros e ratos é, respectivamente, de 1000, 500, 20 e 50 unidades. Quando os animais correm, gastam, respectivamente, 50, 25, 5 e 2 unidades. Um pássaro, quando voa, gasta apenas 2 unidades. Um cão que ataque um gato gasta 100 unidades e faz com que o gato perca 25. | ||
Para um predador comer uma presa tem de a perseguir para a capturar (podendo a perseguição ser ou não bem sucedida). Um cão consegue capturar um rato em cada 25 tentativas. Para os gatos, o rácio é 1 em 5 (ratos) e 1 em 10 (pássaros). A perseguição consome a mesma energia que correr (para cada interveniente), mas a presa recebe um bónus de 5 unidades se escapar. Se a presa estiver a dormir, é apanhada 1 em cada 2 tentativas. | Para um predador comer uma presa tem de a perseguir para a capturar (podendo a perseguição ser ou não bem sucedida). Um cão consegue capturar um rato em cada 25 tentativas. Para os gatos, o rácio é 1 em 5 (ratos) e 1 em 10 (pássaros). A perseguição consome a mesma energia que correr (para cada interveniente), mas a presa recebe um bónus de 5 unidades se escapar. <!--Se a presa estiver a dormir, é apanhada 1 em cada 2 tentativas.--> | ||
Construa uma aplicação onde existem 2 cães ("Piloto" e "Átila"), 3 gatos ("Tareco", "Pantufa" e "Kitty"), 20 pássaros e 50 ratos (os pássaros e ratos podem ser organizados em arrays). | Construa uma aplicação onde existem 2 cães ("Piloto" e "Átila"), 3 gatos ("Tareco", "Pantufa" e "Kitty"), 20 pássaros e 50 ratos (os pássaros e ratos podem ser organizados em arrays). | ||
| Line 36: | Line 36: | ||
Neste caso, como se escolheu (dada a fase introdutória) não representar os conceitos hierarquizados, apenas existem relações de dependência entre as classes (representadas pelas setas a tracejado). | Neste caso, como se escolheu (dada a fase introdutória) não representar os conceitos hierarquizados, apenas existem relações de dependência entre as classes (representadas pelas setas a tracejado). | ||
Existem opções de desenho sub-óptimas. Consegue detectá-las? | |||
BUG: o método "escaped" deveria ter como tipo de retorno "void" e não "boolean". | |||
{{CollapsedCode|Diagrama de classes| | |||
[[Image:PO-dog-cat-mouse-bird-energy-noinheritance.png]] | [[Image:PO-dog-cat-mouse-bird-energy-noinheritance.png]] | ||
}} | |||
== Conceito de Cão == | |||
= | {{CollapsedCode|Ficheiro '''Dog.java'''| | ||
<source lang="java"> | |||
public class Dog { | |||
/** | |||
* We define the base energy as a constant, but it does not have to be this | |||
* way. It could be defined differently for each dog (but this requirement | |||
* does not exist in this case). | |||
*/ | |||
private static final int BASE_ENERGY = 1000; | |||
/** | |||
* The dog's name. | |||
*/ | |||
private String _name; | |||
/** | |||
* The dog's current energy value. | |||
*/ | |||
private int _energy = BASE_ENERGY; | |||
/** | |||
* Initialize a dog with a name. Default energy levels are used. | |||
* | |||
* @param name | |||
*/ | |||
public Dog(String name) { | |||
_name = name; | |||
} | |||
/** | |||
* @return dog's current energy level. | |||
*/ | |||
public int getEnergy() { | |||
return _energy; | |||
} | |||
/** | |||
* @return dog's name | |||
*/ | |||
public String getName() { | |||
return _name; | |||
} | |||
/** | |||
* Set the dog's name | |||
* | |||
* @param name | |||
* the dog's name | |||
*/ | |||
public void setName(String name) { | |||
_name = name; | |||
} | |||
/** | |||
* When a dog runs, the energy decreases by 50 units. This value could be | |||
* defined as an attribute or as a constant. | |||
* | |||
* @return whether the dog was able to run. | |||
*/ | |||
public boolean run() { | |||
if (_energy < 50) | |||
return false; | |||
_energy -= 50; | |||
return true; | |||
} | |||
/** | |||
* Call "run" to account for spent energy. | |||
* | |||
* @param mouse | |||
* the mouse to be chased. | |||
* @return whether the dog was able to catch the mouse. If the mouse | |||
* escapes, its energy increases. | |||
*/ | |||
public boolean caughtMouse(Mouse mouse) { | |||
run(); | |||
mouse.run(); | |||
if (0 == (int) (25 * Math.random())) { | |||
return true; | |||
} | |||
mouse.escaped(); | |||
return false; | |||
} | } | ||
/** | |||
* Eating is more or less like a vampire feeding... | |||
* | |||
* @param mouse | |||
* the mouse to eat. | |||
*/ | |||
public void eatMouse(Mouse mouse) { | |||
if (caughtMouse(mouse)) | |||
_energy += mouse.drain(); | |||
} | |||
/** | |||
* We assume that the dog is always able to attack the cat. The parameter to | |||
* ''attacked'' is used to specify the amount of energy lost by the cat. | |||
* Note that we are assuming that the degree of loss depends on the attacker | |||
* (hence the value being defined in the dog class). | |||
* | |||
* The energy values could be defined as attributes or as constants. | |||
* | |||
* @param cat | |||
* the cat the dog attacks | |||
*/ | |||
public void attackCat(Cat cat) { | |||
_energy -= 100; | |||
cat.attacked(25); | |||
} | |||
/** | |||
* Energy is recovered when sleeping. | |||
*/ | |||
public void sleep() { | |||
_energy = BASE_ENERGY; | |||
} | |||
/** | |||
* @see java.lang.Object#equals(java.lang.Object) | |||
*/ | |||
@Override | |||
public boolean equals(Object o) { | |||
if (o instanceof Dog) { | |||
Dog dog = (Dog) o; | |||
return _name.equals(dog.getName()) && _energy == dog.getEnergy(); | |||
} | |||
return false; | |||
} | } | ||
/** | |||
* @see java.lang.Object#toString() | |||
*/ | |||
@Override | |||
public String toString() { | |||
return _name + " (dog) (" + _energy + ")"; | |||
} | |||
} | } | ||
</ | </source> | ||
}} | |||
== Conceito de Gato | == Conceito de Gato == | ||
< | {{CollapsedCode|Ficheiro '''Cat.java'''| | ||
<source lang="java"> | |||
public class Cat { | public class Cat { | ||
/** | |||
* We define the base energy as a constant, but it does not have to be this | |||
* way. It could be defined differently for each dog (but this requirement | |||
* does not exist in this case). | |||
*/ | |||
private static final int BASE_ENERGY = 500; | |||
/** | |||
* The cat's name. | |||
*/ | |||
private String _name; | |||
/** | |||
* The cat's current energy value. | |||
*/ | |||
private int _energy = BASE_ENERGY; | |||
/** | |||
* Initialize a cat with a name. Default energy levels are used. | |||
* | |||
* @param name | |||
*/ | |||
public Cat(String name) { | |||
_name = name; | |||
} | |||
/** | |||
* @return cat's current energy level. | |||
*/ | |||
public int getEnergy() { | |||
return _energy; | |||
} | |||
/** | |||
* @return cat's name | |||
*/ | |||
public String getName() { | |||
return _name; | |||
} | |||
/** | |||
* Set the cat's name | |||
* | |||
* @param name | |||
* the cat's name | |||
*/ | |||
public void setName(String name) { | |||
_name = name; | |||
} | |||
/** | |||
* When a cat runs, the energy decreases by 25 units. This value could be | |||
* defined as an attribute or as a constant. | |||
* | |||
* @return whether the cat was able to run. | |||
*/ | |||
public boolean run() { | |||
if (_energy < 25) | |||
return false; | |||
_energy -= 25; | |||
return true; | |||
} | |||
/** | |||
* Call "run" to account for spent energy. | |||
* | |||
* @param mouse | |||
* the mouse to be caught. | |||
* @return whether the cat was able to catch the mouse. If the mouse | |||
* escapes, its energy increases. | |||
*/ | |||
public boolean caughtMouse(Mouse mouse) { | |||
run(); | |||
mouse.run(); | |||
if (0 == (int) (5 * Math.random())) { | |||
return true; | |||
} | |||
mouse.escaped(); | |||
return false; | |||
} | } | ||
/** | |||
* Call "run" ("fly"??) to account for spent energy. | |||
* | |||
* @param bird | |||
* the bird to be caught. | |||
* @return whether the cat was able to catch the bird. If the bird escapes, | |||
* its energy increases. | |||
*/ | |||
public boolean caughtBird(Bird bird) { | |||
run(); | |||
bird.fly(); // run?? | |||
if (0 == (int) (10 * Math.random())) { | |||
return true; | |||
} | |||
bird.escaped(); | |||
return false; | |||
} | } | ||
/** | |||
* Eating is more or less like a vampire feeding... | |||
* | |||
* @param mouse | |||
* the mouse to eat. | |||
*/ | |||
public void eatMouse(Mouse mouse) { | |||
if (caughtMouse(mouse)) | |||
_energy += mouse.drain(); | |||
} | |||
/** | |||
* Eating is more or less like a vampire feeding... | |||
* | |||
* @param bird | |||
* the mouse to eat. | |||
*/ | |||
public void eatBird(Bird bird) { | |||
if (caughtBird(bird)) | |||
_energy += bird.drain(); | |||
} | |||
/** | |||
* We should probably check for large decrease values. Nevertheless, in this | |||
* case, for simplicity, we will let the energy go negative and, later on, | |||
* the cat can recover after a nap. | |||
* | |||
* @param energyDecrease | |||
*/ | |||
public void attacked(int energyDecrease) { | |||
_energy -= energyDecrease; | |||
} | |||
/** | |||
* Energy is recovered when sleeping. | |||
*/ | |||
public void sleep() { | |||
_energy = BASE_ENERGY; | |||
} | |||
/** | |||
* @see java.lang.Object#equals(java.lang.Object) | |||
*/ | |||
@Override | |||
public boolean equals(Object o) { | |||
if (o instanceof Cat) { | |||
Cat cat = (Cat) o; | |||
return _name.equals(cat.getName()) && _energy == cat.getEnergy(); | |||
} | |||
return false; | |||
} | } | ||
/** | |||
* @see java.lang.Object#toString() | |||
*/ | |||
@Override | |||
public String toString() { | |||
return _name + " (cat) (" + _energy + ")"; | |||
} | |||
} | } | ||
</ | </source> | ||
}} | |||
== Conceito de Rato | == Conceito de Rato == | ||
< | {{CollapsedCode|Ficheiro '''Mouse.java'''| | ||
<source lang="java"> | |||
public class Mouse { | public class Mouse { | ||
| Line 343: | Line 370: | ||
/** | /** | ||
* | * The mouse's current energy value. | ||
*/ | */ | ||
private int _energy = BASE_ENERGY; | private int _energy = BASE_ENERGY; | ||
| Line 350: | Line 377: | ||
* @return mouse's current energy level. | * @return mouse's current energy level. | ||
*/ | */ | ||
public int getEnergy() { | |||
return _energy; | return _energy; | ||
} | } | ||
| Line 357: | Line 384: | ||
* When a mouse runs, the energy decreases by 2 units. This value could be | * When a mouse runs, the energy decreases by 2 units. This value could be | ||
* defined as an attribute or as a constant. | * defined as an attribute or as a constant. | ||
* | * | ||
* @return whether the mouse was able to run. | * @return whether the mouse was able to run. | ||
*/ | */ | ||
| Line 410: | Line 437: | ||
} | } | ||
} | } | ||
</ | </source> | ||
}} | |||
== Conceito de Pássaro | == Conceito de Pássaro == | ||
< | {{CollapsedCode|Ficheiro '''Bird.java'''| | ||
<source lang="java"> | |||
public class Bird { | public class Bird { | ||
| Line 425: | Line 454: | ||
/** | /** | ||
* | * The bird's current energy value. | ||
*/ | */ | ||
private int _energy = BASE_ENERGY; | private int _energy = BASE_ENERGY; | ||
| Line 432: | Line 461: | ||
* @return mouse's current energy level. | * @return mouse's current energy level. | ||
*/ | */ | ||
public int getEnergy() { | |||
return _energy; | return _energy; | ||
} | } | ||
| Line 439: | Line 468: | ||
* When a bird runs, the energy decreases by 5 units. This value could be | * When a bird runs, the energy decreases by 5 units. This value could be | ||
* defined as an attribute or as a constant. | * defined as an attribute or as a constant. | ||
* | * | ||
* @return whether the bird was able to run. | * @return whether the bird was able to run. | ||
*/ | */ | ||
| Line 452: | Line 481: | ||
* When a bird flies, the energy decreases by 2 units. This value could be | * When a bird flies, the energy decreases by 2 units. This value could be | ||
* defined as an attribute or as a constant. | * defined as an attribute or as a constant. | ||
* | * | ||
* @return whether the bird was able to fly. | * @return whether the bird was able to fly. | ||
*/ | */ | ||
| Line 505: | Line 534: | ||
} | } | ||
} | } | ||
</ | </source> | ||
}} | |||
== Programa Principal == | == Programa Principal == | ||
< | Este programa implementa o cenário descrito no enunciado do problema. | ||
{{CollapsedCode|Ficheiro '''Application.java'''| | |||
<source lang="java"> | |||
public class Application { | public class Application { | ||
/** | |||
* @param args | |||
*/ | |||
public static void main(String[] args) { | |||
Dog d1 = new Dog("Piloto"); | |||
Dog d2 = new Dog("Átila"); | |||
Cat c1 = new Cat("Tareco"); | |||
Cat c2 = new Cat("Pantufa"); | |||
Cat c3 = new Cat("Kitty"); | |||
Bird[] birds = new Bird[20]; | |||
for (int ix = 0; ix < birds.length; ix++) | |||
birds[ix] = new Bird(); | |||
Mouse[] mice = new Mouse[50]; | |||
for (int ix = 0; ix < mice.length; ix++) | |||
mice[ix] = new Mouse(); | |||
// snapshot: present everything | |||
System.out.println("BEFORE"); | |||
System.out.println(d1); | |||
System.out.println(d2); | |||
System.out.println(c1); | |||
System.out.println(c2); | |||
System.out.println(c3); | |||
for (int ix = 0; ix < birds.length; ix++) | |||
System.out.println(birds[ix]); | |||
for (int ix = 0; ix < mice.length; ix++) | |||
System.out.println(mice[ix]); | |||
// run, chase, eat, sleep, etc. | |||
for (int ix = 0; ix < birds.length; ix++) | |||
birds[ix].fly(); | |||
d1.run(); | |||
d2.attackCat(c1); | |||
c2.eatBird(birds[2]); | |||
c3.eatBird(birds[9]); | |||
c3.eatMouse(mice[0]); | |||
d2.eatMouse(mice[1]); | |||
mice[3].run(); | |||
// snapshot: present everything | |||
System.out.println("AFTER"); | |||
System.out.println(d1); | |||
System.out.println(d2); | |||
System.out.println(c1); | |||
System.out.println(c2); | |||
System.out.println(c3); | |||
for (int ix = 0; ix < birds.length; ix++) | |||
System.out.println(birds[ix]); | |||
for (int ix = 0; ix < mice.length; ix++) | |||
System.out.println(mice[ix]); | |||
} | |||
} | } | ||
</ | </source> | ||
}} | |||
= | = Compilação e Execução = | ||
== | == Como compilar? == | ||
A compilação processa-se como indicado (poder-se-ia compilar ficheiro a ficheiro): | |||
javac Dog.java | javac Dog.java Cat.java Mouse.java Bird.java | ||
javac Application.java | javac Application.java | ||
De facto, a compilação do ficheiro '''Application.java''' seria suficiente para causar a compilação de todos os outros, já que são referidos a partir dele (o compilador de Java é capaz de seguir dependências explícitas entre classes). | |||
== Execução == | |||
O programa começa a sua execução na função '''main''' da classe escolhida para iniciar a aplicação (neste caso, '''Application'''): | |||
java Application | java Application | ||
[[category:PO]] | [[category:PO]] | ||
[[category:PO Exemplos]] | |||
[[category:Java]] | |||
[[category:Ensino]] | |||
Latest revision as of 23:30, 14 September 2023
Problema
Numa casa de campo existem vários animais.
Alguns animais são domésticos: cães, gatos e pássaros (canários, etc.). Os donos acreditam em dar liberdade completa aos animais, o que causa alguns problemas de interacção nem sempre do agrado geral.
Outros animais, embora vivam na casa ou perto dela, não são oficialmente considerados animais domésticos: ratos, cobras, insectos, aranhas, etc. Estes animais também se deslocam pela propriedade, livre mas nem sempre impunemente.
Todos os animais podem correr (e os pássaros voar), consumindo energia para o efeito. Quando a energia termina, não podem correr mais e têm de dormir para recuperar forças.
Além do repouso, os cães e os gatos podem recuperar energia comendo ratos. Um rato devorado perde, claro está, toda a energia (é transferida para o predador). Os gatos, por serem ágeis, também conseguem comer pássaros (com efeitos muito semelhantes aos da relação gato-rato).
Por vezes, os cães perdem a paciência e atacam os gatos. Ambos perdem energia no processo.
Modele os conceitos "cão", "gato", "pássaro" e "rato". Além da energia, os cães e os gatos têm nome (uma cadeia de caracteres).
Considere que a energia disponível inicialmente para os cães, gatos, pássaros e ratos é, respectivamente, de 1000, 500, 20 e 50 unidades. Quando os animais correm, gastam, respectivamente, 50, 25, 5 e 2 unidades. Um pássaro, quando voa, gasta apenas 2 unidades. Um cão que ataque um gato gasta 100 unidades e faz com que o gato perca 25.
Para um predador comer uma presa tem de a perseguir para a capturar (podendo a perseguição ser ou não bem sucedida). Um cão consegue capturar um rato em cada 25 tentativas. Para os gatos, o rácio é 1 em 5 (ratos) e 1 em 10 (pássaros). A perseguição consome a mesma energia que correr (para cada interveniente), mas a presa recebe um bónus de 5 unidades se escapar.
Construa uma aplicação onde existem 2 cães ("Piloto" e "Átila"), 3 gatos ("Tareco", "Pantufa" e "Kitty"), 20 pássaros e 50 ratos (os pássaros e ratos podem ser organizados em arrays).
Neste cenário, os gatos correm, perseguem pássaros e ratos e são atacados pelos cães, que também podem correr e perseguir e comer ratos. Os animais dormem automaticamente se ficam sem energia (excepto quando são devorados: nesse caso devem ser considerados mortos).
Apresente o estado inicial dos animais (métodos toString) e o estado final (depois de algumas interacções).
(Pode utilizar parte do resultado do Exercício 01 na resolução deste exercicio.)
Solução
A solução apresentada procura manter-se simples e a um nível que ainda não implica utilizar abstracção de propriedade comuns, como por exemplo, a energia, ou de conceitos mais básicos (o de Animal, por exemplo). Estes aspectos, necessários numa boa definição de solução, são objecto de estudo em fases mais adiantadas da exposição da matéria.
UML: Diagrama de Classes
Neste caso, como se escolheu (dada a fase introdutória) não representar os conceitos hierarquizados, apenas existem relações de dependência entre as classes (representadas pelas setas a tracejado).
Existem opções de desenho sub-óptimas. Consegue detectá-las?
BUG: o método "escaped" deveria ter como tipo de retorno "void" e não "boolean".
| Diagrama de classes |
|---|
Conceito de Cão
| 'Ficheiro Dog.java' |
|---|
public class Dog {
/**
* We define the base energy as a constant, but it does not have to be this
* way. It could be defined differently for each dog (but this requirement
* does not exist in this case).
*/
private static final int BASE_ENERGY = 1000;
/**
* The dog's name.
*/
private String _name;
/**
* The dog's current energy value.
*/
private int _energy = BASE_ENERGY;
/**
* Initialize a dog with a name. Default energy levels are used.
*
* @param name
*/
public Dog(String name) {
_name = name;
}
/**
* @return dog's current energy level.
*/
public int getEnergy() {
return _energy;
}
/**
* @return dog's name
*/
public String getName() {
return _name;
}
/**
* Set the dog's name
*
* @param name
* the dog's name
*/
public void setName(String name) {
_name = name;
}
/**
* When a dog runs, the energy decreases by 50 units. This value could be
* defined as an attribute or as a constant.
*
* @return whether the dog was able to run.
*/
public boolean run() {
if (_energy < 50)
return false;
_energy -= 50;
return true;
}
/**
* Call "run" to account for spent energy.
*
* @param mouse
* the mouse to be chased.
* @return whether the dog was able to catch the mouse. If the mouse
* escapes, its energy increases.
*/
public boolean caughtMouse(Mouse mouse) {
run();
mouse.run();
if (0 == (int) (25 * Math.random())) {
return true;
}
mouse.escaped();
return false;
}
/**
* Eating is more or less like a vampire feeding...
*
* @param mouse
* the mouse to eat.
*/
public void eatMouse(Mouse mouse) {
if (caughtMouse(mouse))
_energy += mouse.drain();
}
/**
* We assume that the dog is always able to attack the cat. The parameter to
* ''attacked'' is used to specify the amount of energy lost by the cat.
* Note that we are assuming that the degree of loss depends on the attacker
* (hence the value being defined in the dog class).
*
* The energy values could be defined as attributes or as constants.
*
* @param cat
* the cat the dog attacks
*/
public void attackCat(Cat cat) {
_energy -= 100;
cat.attacked(25);
}
/**
* Energy is recovered when sleeping.
*/
public void sleep() {
_energy = BASE_ENERGY;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
if (o instanceof Dog) {
Dog dog = (Dog) o;
return _name.equals(dog.getName()) && _energy == dog.getEnergy();
}
return false;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return _name + " (dog) (" + _energy + ")";
}
}
|
Conceito de Gato
| 'Ficheiro Cat.java' |
|---|
public class Cat {
/**
* We define the base energy as a constant, but it does not have to be this
* way. It could be defined differently for each dog (but this requirement
* does not exist in this case).
*/
private static final int BASE_ENERGY = 500;
/**
* The cat's name.
*/
private String _name;
/**
* The cat's current energy value.
*/
private int _energy = BASE_ENERGY;
/**
* Initialize a cat with a name. Default energy levels are used.
*
* @param name
*/
public Cat(String name) {
_name = name;
}
/**
* @return cat's current energy level.
*/
public int getEnergy() {
return _energy;
}
/**
* @return cat's name
*/
public String getName() {
return _name;
}
/**
* Set the cat's name
*
* @param name
* the cat's name
*/
public void setName(String name) {
_name = name;
}
/**
* When a cat runs, the energy decreases by 25 units. This value could be
* defined as an attribute or as a constant.
*
* @return whether the cat was able to run.
*/
public boolean run() {
if (_energy < 25)
return false;
_energy -= 25;
return true;
}
/**
* Call "run" to account for spent energy.
*
* @param mouse
* the mouse to be caught.
* @return whether the cat was able to catch the mouse. If the mouse
* escapes, its energy increases.
*/
public boolean caughtMouse(Mouse mouse) {
run();
mouse.run();
if (0 == (int) (5 * Math.random())) {
return true;
}
mouse.escaped();
return false;
}
/**
* Call "run" ("fly"??) to account for spent energy.
*
* @param bird
* the bird to be caught.
* @return whether the cat was able to catch the bird. If the bird escapes,
* its energy increases.
*/
public boolean caughtBird(Bird bird) {
run();
bird.fly(); // run??
if (0 == (int) (10 * Math.random())) {
return true;
}
bird.escaped();
return false;
}
/**
* Eating is more or less like a vampire feeding...
*
* @param mouse
* the mouse to eat.
*/
public void eatMouse(Mouse mouse) {
if (caughtMouse(mouse))
_energy += mouse.drain();
}
/**
* Eating is more or less like a vampire feeding...
*
* @param bird
* the mouse to eat.
*/
public void eatBird(Bird bird) {
if (caughtBird(bird))
_energy += bird.drain();
}
/**
* We should probably check for large decrease values. Nevertheless, in this
* case, for simplicity, we will let the energy go negative and, later on,
* the cat can recover after a nap.
*
* @param energyDecrease
*/
public void attacked(int energyDecrease) {
_energy -= energyDecrease;
}
/**
* Energy is recovered when sleeping.
*/
public void sleep() {
_energy = BASE_ENERGY;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
if (o instanceof Cat) {
Cat cat = (Cat) o;
return _name.equals(cat.getName()) && _energy == cat.getEnergy();
}
return false;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return _name + " (cat) (" + _energy + ")";
}
}
|
Conceito de Rato
| 'Ficheiro Mouse.java' |
|---|
public class Mouse {
/**
* We define the base energy as a constant, but it does not have to be this
* way. It could be defined differently for each dog (but this requirement
* does not exist in this case).
*/
private static final int BASE_ENERGY = 50;
/**
* The mouse's current energy value.
*/
private int _energy = BASE_ENERGY;
/**
* @return mouse's current energy level.
*/
public int getEnergy() {
return _energy;
}
/**
* When a mouse runs, the energy decreases by 2 units. This value could be
* defined as an attribute or as a constant.
*
* @return whether the mouse was able to run.
*/
public boolean run() {
if (_energy < 2)
return false;
_energy -= 2;
return true;
}
/**
* Energy goes up 5 points in a narrow escape.
*/
public void escaped() {
_energy += 5;
}
/**
* @return the energy level in this mouse
*/
public int drain() {
int energy = _energy;
_energy = 0;
return energy;
}
/**
* Energy is recovered when sleeping.
*/
public void sleep() {
_energy = BASE_ENERGY;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
if (o instanceof Mouse) {
Mouse mouse = (Mouse) o;
return _energy == mouse.getEnergy();
}
return false;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "mouse (" + _energy + ")";
}
}
|
Conceito de Pássaro
| 'Ficheiro Bird.java' |
|---|
public class Bird {
/**
* We define the base energy as a constant, but it does not have to be this
* way. It could be defined differently for each dog (but this requirement
* does not exist in this case).
*/
private static final int BASE_ENERGY = 20;
/**
* The bird's current energy value.
*/
private int _energy = BASE_ENERGY;
/**
* @return mouse's current energy level.
*/
public int getEnergy() {
return _energy;
}
/**
* When a bird runs, the energy decreases by 5 units. This value could be
* defined as an attribute or as a constant.
*
* @return whether the bird was able to run.
*/
public boolean run() {
if (_energy < 5)
return false;
_energy -= 5;
return true;
}
/**
* When a bird flies, the energy decreases by 2 units. This value could be
* defined as an attribute or as a constant.
*
* @return whether the bird was able to fly.
*/
public boolean fly() {
if (_energy < 2)
return false;
_energy -= 2;
return true;
}
/**
* Energy goes up 5 points in a narrow escape.
*/
public void escaped() {
_energy += 5;
}
/**
* @return the energy level in this mouse
*/
public int drain() {
int energy = _energy;
_energy = 0;
return energy;
}
/**
* Energy is recovered when sleeping.
*/
public void sleep() {
_energy = BASE_ENERGY;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
if (o instanceof Bird) {
Bird bird = (Bird) o;
return _energy == bird.getEnergy();
}
return false;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "bird (" + _energy + ")";
}
}
|
Programa Principal
Este programa implementa o cenário descrito no enunciado do problema.
| 'Ficheiro Application.java' |
|---|
public class Application {
/**
* @param args
*/
public static void main(String[] args) {
Dog d1 = new Dog("Piloto");
Dog d2 = new Dog("Átila");
Cat c1 = new Cat("Tareco");
Cat c2 = new Cat("Pantufa");
Cat c3 = new Cat("Kitty");
Bird[] birds = new Bird[20];
for (int ix = 0; ix < birds.length; ix++)
birds[ix] = new Bird();
Mouse[] mice = new Mouse[50];
for (int ix = 0; ix < mice.length; ix++)
mice[ix] = new Mouse();
// snapshot: present everything
System.out.println("BEFORE");
System.out.println(d1);
System.out.println(d2);
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
for (int ix = 0; ix < birds.length; ix++)
System.out.println(birds[ix]);
for (int ix = 0; ix < mice.length; ix++)
System.out.println(mice[ix]);
// run, chase, eat, sleep, etc.
for (int ix = 0; ix < birds.length; ix++)
birds[ix].fly();
d1.run();
d2.attackCat(c1);
c2.eatBird(birds[2]);
c3.eatBird(birds[9]);
c3.eatMouse(mice[0]);
d2.eatMouse(mice[1]);
mice[3].run();
// snapshot: present everything
System.out.println("AFTER");
System.out.println(d1);
System.out.println(d2);
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
for (int ix = 0; ix < birds.length; ix++)
System.out.println(birds[ix]);
for (int ix = 0; ix < mice.length; ix++)
System.out.println(mice[ix]);
}
}
|
Compilação e Execução
Como compilar?
A compilação processa-se como indicado (poder-se-ia compilar ficheiro a ficheiro):
javac Dog.java Cat.java Mouse.java Bird.java javac Application.java
De facto, a compilação do ficheiro Application.java seria suficiente para causar a compilação de todos os outros, já que são referidos a partir dele (o compilador de Java é capaz de seguir dependências explícitas entre classes).
Execução
O programa começa a sua execução na função main da classe escolhida para iniciar a aplicação (neste caso, Application):
java Application
