import java.util.*;
import java.lang.*;
class Main
{
{
new Main().Run();
}
public void Run()
{
Zoo zoo = new Zoo();
CountingVisitor v = new CountingVisitor();
zoo.Accept(v);
v.Summary();
}
interface AnimalVisitor
{
void Visit(Giraffe giraffe); // (1)
void Visit(Zebra zebra); // (2)
void Visit(Lion lion); // (3)
void Visit(Penguin penguin); // (4)
}
interface VisitableAnimal
{
void Accept(AnimalVisitor visitor);
}
class Zoo
{
VisitableAnimal[] animals = new VisitableAnimal[]
{
new Giraffe(),
new Zebra(),
new Lion(),
new Penguin()
};
public void Accept(AnimalVisitor visitor)
{
for (VisitableAnimal a : animals)
a.Accept(visitor);
}
}
class Giraffe implements VisitableAnimal
{
public void Accept(AnimalVisitor visitor)
{
visitor.Visit(this); // calls (1)
}
}
class Zebra implements VisitableAnimal
{
public void Accept(AnimalVisitor visitor)
{
visitor.Visit(this); // calls (2)
}
}
class Lion implements VisitableAnimal
{
public void Accept(AnimalVisitor visitor)
{
visitor.Visit(this); // calls (3)
}
}
class Penguin implements VisitableAnimal
{
public void Accept(AnimalVisitor visitor)
{
visitor.Visit(this); // calls (4)
}
}
class CountingVisitor implements AnimalVisitor
{
int numberOfMammals;
int numberOfBirds;
int numberOfMonochromeAnimals;
public void Summary()
{
System.
out.
printf("Discovered %d mammals, %d birds\n", numberOfMammals, numberOfBirds
); System.
out.
printf("Total %d monochrome animals\n", numberOfMonochromeAnimals
); }
public void Visit(Giraffe giraffe)
{
numberOfMammals++;
}
public void Visit(Zebra zebra)
{
numberOfMammals++;
numberOfMonochromeAnimals++;
}
public void Visit(Lion lion)
{
numberOfMammals++;
System.
out.
println("Lions are NOT scary"); }
public void Visit(Penguin penguin)
{
numberOfBirds++;
numberOfMonochromeAnimals++;
}
}
}