Решения на языках Ruby и Java
Завершая рассмотрение задания OOP1Creat1, приведем его решения еще
на двух языках, для которых предусмотрено создание заготовок: это языки
Ruby и Java. Язык Ruby имеет много общего с языком Python; это тоже язык
с динамической типизацией, в котором не требуется описывать полностью
абстрактные классы и абстрактные методы. Язык Javа имеет объектную
модель, близкую к модели языка C#. В ней объекты тоже всегда размещаются
в динамической памяти и автоматически освобождают ее благодаря наличию
сборщика мусора. Кроме того, в языке Java все методы классов по умолчанию
являются виртуальными, поэтому модификатор virtual для них указывать не
требуется (хотя можно использовать модификатор @Override, который,
подобно аналогичному модификатору для языка C++, не является
обязательным, но делает программу более наглядной).
Заметим, что программы, выполняющие задания на языках Ruby и Java,
тоже можно разрабатывать в среде Visual Studio Code. Кроме этой среды
задачник поддерживает среду RubyMine для языка Ruby и среду Eclipse для
языка Java.
Вначале приведем заготовку программы для языка Ruby. Сравнивая ее с
ранее приведенной заготовкой для языка Python, нетрудно заметить,
насколько близки эти языки.
# coding: utf-8
require "./PT"
class ConcreteProduct1
def initialize(info)
# Implement the constructor
end
def getInfo
# Implement the method
end
def transform
# Implement the method
end
end
# Implement the ConcreteProduct2 class
class Creator
def anOperation(info)
p = factoryMethod(info)
p.transform
p.transform
return p.getInfo
end
end
class ConcreteCreator1 < Creator
def factoryMethod(info)
# Implement the method
end
end
# Implement the ConcreteCreator2 descendant class;
# the anOperation method should not be
# overridden in this class
def solve()
task "OOP1Creat1"
end
start_solve
Теперь приведем решение задачи на языке Ruby.
# coding: utf-8
require "./PT"
class ConcreteProduct1
def initialize(info)
@info = info.downcase
end
def getInfo
return @info
end
def transform
(@info.length-2).downto(0) do |i|
if @info[i] != " "
@info.insert(i+1, " ")
end
end
end
end
class ConcreteProduct2
def initialize(info)
@info = info.upcase
end
def getInfo
return @info
end
def transform
(@info.length-2).downto(0) do |i|
if @info[i] != "*"
@info.insert(i+1, "**")
end
end
end
end
class Creator
def anOperation(info)
p = factoryMethod(info)
p.transform
p.transform
return p.getInfo
end
end
class ConcreteCreator1 < Creator
def factoryMethod(info)
return ConcreteProduct1.new(info)
end
end
class ConcreteCreator2 < Creator
def factoryMethod(info)
return ConcreteProduct2.new(info)
end
end
def solve()
task "OOP1Creat1"
c1 = ConcreteCreator1.new
c2 = ConcreteCreator2.new
5.times do
s = get
put c1.anOperation(s), c2.anOperation(s)
end
end
start_solve
Заготовка для языка Java очень похожа на заготовку для языка C#.
Основным ее отличием является то, что в данном случае дополнительные
классы описываются не внутри основного класса MyTask, содержащего метод
solve, а перед ним. Кроме того, в конце класса MyTask содержится описание
стартового метода main (это описание не требуется изменять, поэтому здесь
оно не приводится). В начале заготовки содержится директива import
java.util.ArrayList, поскольку структура данных ArrayList может оказаться
полезной при решении многих задач.
import java.util.ArrayList;
abstract class Product {
public abstract String getInfo();
public abstract void transform();
}
// Implement the ConcreteProduct1
// and ConcreteProduct2 descendant classes
abstract class Creator {
protected abstract Product factoryMethod(String info);
public String anOperation(String info) {
Product p = factoryMethod(info);
p.transform();
p.transform();
String s = p.getInfo();
return s;
}
}
// Implement the ConcreteCreator1
// and ConcreteCreator2 descendant classes;
// the anOperation method should not be
// overridden in these classes
public class MyTask extends PT
{
public static void solve() throws Exception
{
task("OOP1Creat1");
}
<Здесь содержится описание метода main>
}
Приведем реализацию классов ConcreteProduct1, ConcreteProduct2,
ConcreteCreator1, ConcreteCreator2 и метода solve. Эти реализации также
очень похожи на соответствующие реализации для языка C# (обратите
внимание на модификаторы @Override):
class ConcreteProduct1 extends Product {
private String info;
public ConcreteProduct1(String info) {
this.info = info.toLowerCase();
}
@Override
public String getInfo() {
return info;
}
@Override
public void transform() {
StringBuffer s = new StringBuffer(info);
for (int i = s.length() - 2; i >= 0; i--)
if (s.charAt(i) != ' ')
s.insert(i+1, ' ');
this.info = s.toString();
}
}
class ConcreteProduct2 extends Product {
private String info;
public ConcreteProduct2(String info) {
this.info = info.toUpperCase();
}
@Override
public String getInfo() {
return info;
}
@Override
public void transform() {
StringBuffer s = new StringBuffer(info);
for (int i = s.length() - 2; i >= 0; i--)
if (s.charAt(i) != '*')
s.insert(i+1, "**");
this.info = s.toString();
}
}
class ConcreteCreator1 extends Creator {
@Override
protected Product factoryMethod(String info) {
return new ConcreteProduct1(info);
}
}
class ConcreteCreator2 extends Creator {
@Override
protected Product factoryMethod(String info) {
return new ConcreteProduct2(info);
}
}
public static void solve() throws Exception
{
task("OOP1Creat1");
ConcreteCreator1 c1 = new ConcreteCreator1();
ConcreteCreator2 c2 = new ConcreteCreator2();
for (int i = 0; i < 5; i++) {
String info = getString();
put(c1.anOperation(info), c2.anOperation(info));
}
}
Подобно тому как в языке C# мы использовали вспомогательный класс
StringBuilder для эффективного преобразования поля info в методе
Transform, в языке Java мы для этих же целей используем класс StringBuffer,
обладающий аналогичными свойствами.
|