演習問題1(ショッピングカート 合計金額)
演習問題1-3 (Decorator)
演習問題1-2 では、商品ごとに割引が行なわれ、その割引も一度に利用できるのは1つだけでした。
よって、今度は合計金額 に対して、複数の割引を組み合わせて対応できるように変更します。
TotalDiscount のサブクラスとして、合計金額を5%割り引く TotalDiscount5percent や合計金額から100円値引きする TotalDiscount100yen などを作成してください。
また、割引の種類が増えても、Cart クラス、TotalDiscount クラスやそのサブクラスを変更しなくてもよいようにしなさい。
実行結果
現在の合計金額は 548 円です。
現在の合計金額は 520 円です。
現在の合計金額は 420 円です。
現在の合計金額は 425 円です。
コード
Enshu103.java
public class Enshu103 {
public static void main(String[] args ) {
Cart cart = new Cart ();
cart .add(new Vegetable ("大根", 125, 1));
cart .add(new Vegetable ("レタス", 147, 1));
cart .add(new Vegetable ("トマト", 69, 4));
TotalDiscount discount ;
discount = new TotalNoDiscount (cart .getTotalPrice());
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。");
// 5%割引
discount = new TotalDiscount5percent (discount );
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。");
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount );
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。");
// 100円引きでさらに5%割引
discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount (cart .getTotalPrice())));
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。");
}
}
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.java
public abstract class TotalDiscount {
public abstract int getPrice();
}
解答
TotalDiscount.java
public abstract class TotalDiscount {
public abstract int getPrice();
}
TotalNoDiscount.java
public class TotalNoDiscount extends TotalDiscount {
protected int price ;
public TotalNoDiscount (int price ) {
this.price = price ;
}
public int getPrice() {
return price ;
}
}
TotalDiscount5percent.java
public class TotalDiscount5percent extends TotalDiscount {
private TotalDiscount discount ;
public TotalDiscount5percent (TotalDiscount discount ) {
this.discount = discount ;
}
public int getPrice() {
return (int)(discount .getPrice() * 0.95);
}
}
TotalDiscount100yen.java
public class TotalDiscount100yen extends TotalDiscount {
private TotalDiscount discount ;
public TotalDiscount100yen (TotalDiscount discount ) {
this.discount = discount ;
}
public int getPrice() {
return discount .getPrice() - 100;
}
}
Enshu103.cpp
#include "StdAfx.h"
#include <iostream>
using namespace std;
#include "Cart.h"
#include "Vegetable.h"
#include "TotalDiscount.h"
#include "TotalNoDiscount.h"
#include "TotalDiscount5percent.h"
#include "TotalDiscount100yen.h"
int main()
{
Cart * cart = new Cart ();
cart ->add(new Vegetable ("大根", 125, 1));
cart ->add(new Vegetable ("レタス", 147, 1));
cart ->add(new Vegetable ("トマト", 69, 4));
// 割引なし
TotalDiscount * discount = TotalNoDiscount (cart ->getTotalPrice());
TotalDiscount * discount0 = discount ;
cout << "現在の合計金額は " << discount ->getPrice() << " 円です。" << endl;
// 5%割引
discount = new TotalDiscount5percent (discount );
cout << "現在の合計金額は " << discount ->getPrice() << " 円です。" << endl;
TotalDiscount * discount1 = discount ;
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount1 );
cout << "現在の合計金額は " << discount ->getPrice() << " 円です。" << endl;
delete discount1 ;
delete discount ;
// 100円引きでさらに5%割引
TotalDiscount * discount2 = new TotalDiscount100yen(discount0 );
discount = new TotalDiscount5percent (discount2 );
cout << "現在の合計金額は " << discount ->getPrice() << " 円です。" << endl;
delete discount2 ;
delete discount0 ;
delete discount ;
delete cart ;
return 0;
}
ヒント(totalDiscount クラス)
基本クラスとして totalDiscount クラスを作ります。そして、getPrice() を作成しますが、totalDiscount クラスでは処理を記述しません。
totalNoDiscount クラス、totalDiscount5percent クラスや totalDiscount100yen クラスは totalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらの派生クラスで実装します。
totalNoDiscount クラス以外の各派生クラスの getPrice()では、コンストラクタで受け取った totalDiscount クラスの派生クラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の totalNoDiscount クラスだけは、コンストラクタで int 型の価格を受け取り、discountPrice() でそのままの価格を返します。この過程を経ることにより、totalNoDiscount クラス以外の totalDiscount クラスの派生クラスの組み合わせや順序が自由になります。
totalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.h
#pragma once
class TotalDiscount
{
public:
TotalDiscount(void);
virtual ~TotalDiscount(void);
virtual int getPrice(void) = 0;
};
TotalDiscount.cpp
#include "StdAfx.h"
#include "TotalDiscount.h"
TotalDiscount ::TotalDiscount(void) {}
TotalDiscount ::~TotalDiscount(void) {}
解答
TotalDiscount.h
#pragma once
class TotalDiscount
{
public:
TotalDiscount(void);
virtual ~TotalDiscount(void);
virtual int getPrice(void) = 0;
};
TotalDiscount.cpp
#include "StdAfx.h"
#include "TotalDiscount.h"
TotalDiscount ::TotalDiscount(void) {}
TotalDiscount ::~TotalDiscount(void) {}
TotalDiscount5percent.h
#pragma once
#include "TotalDiscount.h"
class TotalDiscount5percent : public TotalDiscount
{
private:
TotalDiscount * discount ;
public:
TotalDiscount5percent (void);
TotalDiscount5percent (TotalDiscount *);
virtual ~TotalDiscount5percent (void);
virtual int getPrice(void);
};
TotalDiscount5percent.cpp
#include "StdAfx.h"
#include "TotalDiscount5percent.h"
TotalDiscount5percent ::TotalDiscount5percent(void) : discount ((TotalDiscount *)0) {}
TotalDiscount5percent ::TotalDiscount5percent(TotalDiscount * d ) : discount (d ) {}
TotalDiscount5percent ::~TotalDiscount5percent(void) {}
int TotalDiscount5percent ::getPrice(void)
{
return (int)(discount ->getPrice() * 0.95);
}
TotalDiscount100yen.h
#pragma once
#include "TotalDiscount.h"
class TotalDiscount100yen : public TotalDiscount
{
private:
TotalDiscount * discount ;
public:
TotalDiscount100yen (void);
TotalDiscount100yen (TotalDiscount *);
virtual ~TotalDiscount100yen (void);
virtual int getPrice(void);
};
TotalDiscount100yen.cpp
#include "StdAfx.h"
#include "TotalDiscount100yen.h"
TotalDiscount100yen ::TotalDiscount100yen(void) : discount ((TotalDiscount *)0) {}
TotalDiscount100yen ::TotalDiscount100yen(TotalDiscount * d ) : discount (d ) {}
TotalDiscount100yen ::~TotalDiscount100yen(void) {}
int TotalDiscount100yen ::getPrice(void)
{
return discount ->getPrice() - 100;
}
Enshu103.cs
class Program
{
static void Main(string[] args )
{
Cart cart = new Cart ();
cart .add(new Vegetable ("大根", 125, 1));
cart .add(new Vegetable ("レタス", 147, 1));
cart .add(new Vegetable ("トマト", 69, 4));
TotalDiscount discount ;
// 割引なし
discount = new TotalNoDiscount (cart .getTotalPrice());
Console .WriteLine("現在の合計金額は " + discount .getPrice() + " 円です。");
// 5%割引
discount = new TotalDiscount5percent (discount );
Console .WriteLine("現在の合計金額は " + discount .getPrice() + " 円です。");
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount );
Console .WriteLine("現在の合計金額は " + discount .getPrice() + " 円です。");
// 100円引きでさらに5%割引
discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount (cart .getTotalPrice())));
Console .WriteLine("現在の合計金額は " + discount .getPrice() + " 円です。");
}
}
ヒント(TotalDiscount クラス)
基本クラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらの派生クラスで実装します。
TotalNoDiscount クラス以外の各派生クラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスの派生クラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスの派生クラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.cs
public abstract class TotalDiscount
{
public abstract int getPrice();
}
解答
TotalDiscount.cs
public abstract class TotalDiscount
{
public abstract int getPrice();
}
TotalNoDiscount.cs
public class TotalNoDiscount : TotalDiscount
{
protected int price ;
public TotalNoDiscount(int price )
{
this.price = price ;
}
public override int getPrice()
{
return price ;
}
}
TotalDiscount5percent.cs
public class TotalDiscount5percent : TotalDiscount
{
private TotalDiscount discount ;
public TotalDiscount5percent(TotalDiscount discount )
{
this.discount = discount ;
}
public override int getPrice()
{
return (int)(discount .getPrice() * 0.95);
}
}
TotalDiscount100yen.cs
public class TotalDiscount100yen : TotalDiscount
{
private TotalDiscount discount ;
public TotalDiscount100yen(TotalDiscount discount )
{
this.discount = discount ;
}
public override int getPrice()
{
return discount .getPrice() - 100;
}
}
Enshu103.vb
Module Enshu103
Sub Main()
Dim cart As Cart = New Cart ()
cart .add(New Vegetable ("大根", 125, 1))
cart .add(New Vegetable ("レタス", 147, 1))
cart .add(New Vegetable ("トマト", 69, 4))
Dim discount As TotalDiscount
' 割引なし
discount = New TotalNoDiscount (c.getTotalPrice())
Console .WriteLine("現在の合計金額は " & discount .getPrice() & " 円です。")
' 5%割引
discount = New TotalDiscount5percent (discount)
Console .WriteLine("現在の合計金額は " & discount .getPrice() & " 円です。")
' 5%割引でさらに100円値引き
discount = New TotalDiscount100yen (discount)
Console .WriteLine("現在の合計金額は " & discount .getPrice() & " 円です。")
' 100円引きでさらに5%割引
discount = New TotalDiscount5percent (New TotalDiscount100yen (New TotalNoDiscount (c.getTotalPrice())))
Console .WriteLine("現在の合計金額は " & discount .getPrice() & " 円です。")
End Sub
End Module
ヒント(TotalDiscount クラス)
基本クラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらの派生クラスで実装します。
TotalNoDiscount クラス以外の各派生クラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスの派生クラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスの派生クラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.vb
Public MustInherit Class TotalDiscount
Public MustOverride Function getPrice() As Integer
End Class
解答
TotalDiscount.vb
Public MustInherit Class TotalDiscount
Public MustOverride Function getPrice() As Integer
End Class
TotalNoDiscount.vb
Public Class TotalNoDiscount : Inherits TotalDiscount
Protected price As Integer
Public Sub New(ByVal price As Integer)
Me.price = price
End Sub
Public Overrides Function getPrice() As Integer
Return price
End Function
End Class
TotalDiscount5percent.vb
Public Class TotalDiscount5percent : Inherits TotalDiscount
Private discount As TotalDiscount
Public Sub New(ByVal discount As TotalDiscount )
Me.discount = discount
End Sub
Public Overrides Function getPrice() As Integer
Return Fix(discount .getPrice() * 0.95)
End Function
End Class
TotalDiscount100yen.vb
Public Class TotalDiscount100yen : Inherits TotalDiscount
Private discount As TotalDiscount
Public Sub New(ByVal discount As TotalDiscount )
Me.discount = discount
End Sub
Public Overrides Function getPrice() As Integer
Return discount .getPrice() - 100
End Function
End Class
Enshu103.js
const Cart = require("./Cart.js");
const Vegetable = require("./Vegetable.js");
const TotalNoDiscount = require("./TotalNoDiscount.js");
const TotalDiscount100yen = require("./TotalDiscount100yen.js");
const TotalDiscount5percent = require("./TotalDiscount5percent.js");
let cart = new Cart ();
cart .add(new Vegetable ("大根", 125, 1));
cart .add(new Vegetable ("レタス", 147, 1));
cart .add(new Vegetable ("トマト", 69, 4));
let discount = new TotalNoDiscount (cart .getTotalPrice());
// 割引なし
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。\n");
// 5%割引
discount = new TotalDiscount5percent (discount );
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。\n");
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount );
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。\n");
// 100円引きでさらに5%割引
discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount (cart .getTotalPrice())));
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。\n");
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.js
module.exports = class TotalDiscount {
getPrice() {}
}
解答
TotalDiscount.js
module.exports = class TotalDiscount {
getPrice() {}
}
TotalNoDiscount.js
const TotalDiscount = require("./TotalDiscount.js");
module.exports = class TotalNoDiscount extends TotalDiscount {
constructor(price ) {
super();
this.price = price ;
}
getPrice() {
return this.price ;
}
}
TotalDiscount5percent.js
const TotalDiscount = require("./TotalDiscount.js");
module.exports = class TotalDiscount5percent extends TotalDiscount {
constructor(discount ) {
super();
this.discount = discount ;
}
getPrice() {
return parseInt(this.discount .getPrice() * 0.95);
}
}
TotalDiscount100yen.js
const TotalDiscount = require("./TotalDiscount.js");
module.exports = class TotalDiscount100yen extends TotalDiscount {
constructor(discount ) {
super();
this.discount = discount ;
}
getPrice() {
return this.discount .getPrice() - 100;
}
}
Enshu103.pl
use lib './';
use Cart;
use Vegetable;
use TotalNoDiscount;
use TotalDiscount100yen;
use TotalDiscount5percent;
my $cart = new Cart ();
$cart ->add(new Vegetable ("大根", 125, 1));
$cart ->add(new Vegetable ("レタス", 147, 1));
$cart ->add(new Vegetable ("トマト", 69, 4));
my $discount = new TotalNoDiscount ($cart ->getTotalPrice());
# 割引なし
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
# 5%割引
$discount = new TotalDiscount5percent ($discount );
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
# 5%割引でさらに100円値引き
$discount = new TotalDiscount100yen ($discount );
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
# 100円引きでさらに5%割引
$discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount ($cart ->getTotalPrice())));
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
IDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.pm
package TotalDiscount {
sub new {
my ($class , $discount ) = @_ ;
my $this = { discount => $discount };
return bless $this , $class ;
}
sub getPrice {}
}
1;
解答
TotalDiscount.pm
package TotalDiscount {
sub getPrice {}
}
1;
TotalNoDiscount.pm
package TotalNoDiscount {
use base qw(TotalDiscount );
sub new {
my ($class , $price ) = @_ ;
my $this = {price => $price };
return bless $this , $class ;
}
sub getPrice {
my ($this ) = @_ ;
return $this ->{price };
}
}
1;
TotalDiscount5percent.pm
package TotalDiscount5percent {
use base qw(TotalDiscount );
sub new {
my ($class , $discount ) = @_ ;
my $this = {discount => $discount };
return bless $this , $class ;
}
sub getPrice {
my ($this ) = @_ ;
return int $this ->{discount }->getPrice() * 0.95;
}
}
1;
TotalDiscount100yen.pm
package TotalDiscount100yen {
use base qw(TotalDiscount );
sub new {
my ($class , $discount ) = @_ ;
my $this = {discount => $discount };
return bless $this , $class ;
}
sub getPrice {
my ($this ) = @_ ;
return $this ->{discount }->getPrice() - 100;
}
}
1;
Enshu103.rb
require './Cart'
require './Vegetable'
require './TotalNoDiscount'
require './TotalDiscount5percent'
require './TotalDiscount100yen'
cart = Cart .new()
cart .add(Vegetable .new("大根", 125, 1))
cart .add(Vegetable .new("レタス", 147, 1))
cart .add(Vegetable .new("トマト", 69, 4))
# 割引なし
discount = TotalNoDiscount .new(cart .getTotalPrice())
puts "現在の合計金額は " + discount .getPrice().to_s + " 円です。"
# 5%割引
discount = TotalDiscount5percent .new(discount )
puts "現在の合計金額は " + discount .getPrice().to_s + " 円です。"
# 5%割引でさらに100円値引き
discount = TotalDiscount100yen .new(discount )
puts "現在の合計金額は " + discount .getPrice().to_s + " 円です。"
# 100円引きでさらに5%割引
discount = TotalDiscount5percent .new(TotalDiscount100yen .new(TotalNoDiscount .new(cart .getTotalPrice())))
puts "現在の合計金額は " + discount .getPrice().to_s + " 円です。"
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.rb
class TotalDiscount
def initialize(price )
@price = price
end
def getPrice()
end
end
解答
TotalDiscount.rb
class TotalDiscount
def getPrice()
end
end
TotalNoDiscount.rb
require './TotalDiscount'
class TotalNoDiscount < TotalDiscount
def initialize(price )
@price = price
end
def getPrice()
return @price
end
end
TotalDiscount5percent.rb
require './TotalDiscount'
class TotalDiscount5percent < TotalDiscount
def initialize(discount )
@discount = discount
end
def getPrice()
return (@discount .getPrice() * 0.95).to_i
end
end
TotalDiscount100yen.rb
require './TotalDiscount'
class TotalDiscount100yen < TotalDiscount
def initialize(discount )
@discount = discount
end
def getPrice()
return @discount .getPrice() - 100
end
end
Enshu103.py
from Cart import Cart
from Vegetable import Vegetable
from TotalNoDiscount import TotalNoDiscount
from TotalDiscount5percent import TotalDiscount5percent
from TotalDiscount100yen import TotalDiscount100yen
cart = Cart ()
cart .add(Vegetable ("大根", 125, 1))
cart .add(Vegetable ("レタス", 147, 1))
cart .add(Vegetable ("トマト", 69, 4))
# 割引なし
discount = TotalNoDiscount (cart .getTotalPrice())
print("現在の合計金額は %d 円です。" % discount .getPrice())
# 5%割引
discount = TotalDiscount5percent (discount )
print("現在の合計金額は %d 円です。" % discount .getPrice())
# 5%割引でさらに100円値引き
discount = TotalDiscount100yen (discount )
print("現在の合計金額は %d 円です。" % discount .getPrice())
# 100円引きでさらに5%割引
discount = TotalDiscount5percent (TotalDiscount100yen (TotalNoDiscount (cart .getTotalPrice())))
print("現在の合計金額は %d 円です。" % discount .getPrice())
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.py
from abc import ABCMeta, abstractmethod
class TotalDiscount (metaclass=ABCMeta):
@abstractmethod
def getPrice(self ):
pass
解答
TotalDiscount.py
from abc import ABCMeta, abstractmethod
class TotalDiscount (metaclass=ABCMeta):
@abstractmethod
def getPrice(self ):
pass
TotalNoDiscount.py
from TotalDiscount import TotalDiscount
class TotalNoDiscount (TotalDiscount ):
def __init__(self , price ):
self .price = price
def getPrice(self ):
return self .price
TotalDiscount5percent.py
from TotalDiscount import TotalDiscount
class TotalDiscount5percent (TotalDiscount ):
def __init__(self , discount ):
self .discount = discount
def getPrice(self ):
return self .discount .getPrice() * 0.95
TotalDiscount100yen.py
from TotalDiscount import TotalDiscount
class TotalDiscount100yen (TotalDiscount ):
def __init__(self , discount ):
self .discount = discount
def getPrice(self ):
return self .discount .getPrice() - 100
Enshu103.php
<?php
require_once('Cart.php');
require_once('Vegetable.php');
require_once('TotalNoDiscount.php');
require_once('TotalDiscount5percent.php');
require_once('TotalDiscount100yen.php');
$cart = new Cart ();
$cart ->add(new Vegetable ("大根", 125, 1));
$cart ->add(new Vegetable ("レタス", 147, 1));
$cart ->add(new Vegetable ("トマト", 69, 4));
// 割引なし
$discount = new TotalNoDiscount ($cart ->getTotalPrice());
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
// 5%割引
$discount = new TotalDiscount5percent ($discount );
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
// 5%割引でさらに100円値引き
$discount = new TotalDiscount100yen ($discount );
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
// 100円引きでさらに5%割引
$discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount ($cart ->getTotalPrice())));
print "現在の合計金額は " . $discount ->getPrice() . " 円です。\n";
?>
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.php
<?php
abstract class TotalDiscount {
public abstract function getPrice();
}
?>
解答
TotalDiscount.php
<?php
abstract class TotalDiscount {
public abstract function getPrice();
}
?>
TotalNoDiscount.php
<?php
require_once('TotalDiscount.php');
class TotalNoDiscount extends TotalDiscount {
private $price ;
public function __construct($price ) {
$this->price = $price ;
}
public function getPrice() {
return $this->price ;
}
}
?>
TotalDiscount5percent.php
<?php
require_once('TotalDiscount.php');
class TotalDiscount5percent extends TotalDiscount {
private $discount ;
public function __construct($discount ) {
$this->discount = $discount ;
}
public function getPrice() {
return (int)($this->discount ->getPrice() * 0.95);
}
}
?>
TotalDiscount100yen.php
<?php
require_once('TotalDiscount.php');
class TotalDiscount100yen extends TotalDiscount {
private $discount ;
public function __construct($discount ) {
$this->discount = $discount ;
}
public function getPrice() {
return $this->discount ->getPrice() - 100;
}
}
?>
Enshu103.ts
import {Cart} from "./Cart";
import {Vegetable} from "./Vegetable";
import {TotalDiscount} from "./TotalDiscount";
import {TotalNoDiscount} from "./TotalNoDiscount";
import {TotalDiscount100yen} from "./TotalDiscount100yen";
import {TotalDiscount5percent} from "./TotalDiscount5percent";
let cart :Cart = new Cart ();
cart .add(new Vegetable ("大根", 125, 1));
cart .add(new Vegetable ("レタス", 147, 1));
cart .add(new Vegetable ("トマト", 69, 4));
let discount :TotalDiscount ;
discount = new TotalNoDiscount (cart .getTotalPrice());
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。");
// 5%割引
discount = new TotalDiscount5percent (discount );
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。");
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount );
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。");
// 100円引きでさらに5%割引
discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount (cart .getTotalPrice())));
process.stdout.write("現在の合計金額は " + discount .getPrice() + " 円です。");
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.ts
export
abstract class TotalDiscount {
public abstract getPrice():number;
}
解答
TotalDiscount.ts
export
abstract class TotalDiscount {
public abstract getPrice():number;
}
TotalNoDiscount.ts
import {TotalDiscount} from "./TotalDiscount";
export
class TotalNoDiscount extends TotalDiscount {
protected price :number;
public constructor(price :number) {
super();
this.price = price ;
}
public getPrice():number {
return this.price ;
}
}
TotalDiscount5percent.ts
import {TotalDiscount} from "./TotalDiscount";
export
class TotalDiscount5percent extends TotalDiscount {
private discount :TotalDiscount ;
public constructor(discount :TotalDiscount ) {
super();
this.discount = discount ;
}
public getPrice():number {
return Math .floor(this.discount .getPrice() * 0.95);
}
}
TotalDiscount100yen.ts
import {TotalDiscount} from "./TotalDiscount";
export
class TotalDiscount100yen extends TotalDiscount {
private discount :TotalDiscount ;
public constructor(discount :TotalDiscount ) {
super();
this.discount = discount ;
}
public getPrice():number {
return this.discount .getPrice() - 100;
}
}
Enshu103.swift
let cart :Cart = Cart ()
cart .add(Vegetable ("大根", 125, 1))
cart .add(Vegetable ("レタス", 147, 1))
cart .add(Vegetable ("トマト", 69, 4))
let discount :TotalDiscount
discount = TotalNoDiscount (cart .getTotalPrice());
print("現在の合計金額は \(discount.getPrice()) 円です。")
// 5%割引
discount = TotalDiscount5percent (discount );
print("現在の合計金額は \(discount.getPrice()) 円です。")
// 5%割引でさらに100円値引き
discount = TotalDiscount100yen (discount );
print("現在の合計金額は \(discount.getPrice()) 円です。")
// 100円引きでさらに5%割引
discount = TotalDiscount5percent (TotalDiscount100yen (TotalNoDiscount (cart .getTotalPrice())))
print("現在の合計金額は \(discount.getPrice()) 円です。")
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.swift
public class TotalDiscount {
public /* abstract */ func getPrice():Int {
fatalError()
}
}
解答
TotalDiscount.swift
public class TotalDiscount {
public /* abstract */ func getPrice() -> Int {
fatalError()
}
}
TotalNoDiscount.swift
public class TotalNoDiscount : TotalDiscount {
internal var price :Int
public init(_ price :Int) {
self.price = price
}
public override func getPrice() -> Int {
return price
}
}
TotalDiscount5percent.swift
public class TotalDiscount5percent : TotalDiscount {
private var discount :TotalDiscount
public init(discount :TotalDiscount ) {
self.discount = discount
}
public override func getPrice() -> Int {
return Int(Double(discount .getPrice()) * 0.95)
}
}
TotalDiscount100yen.swift
public class TotalDiscount100yen : TotalDiscount {
private var discount :TotalDiscount
public init(discount :TotalDiscount ) {
self.discount = discount
}
public override func getPrice() -> Int {
return discount .getPrice() - 100
}
}
Enshu103.kt
fun main() {
val cart = Cart ()
cart .add(Vegetable ("大根", 125, 1))
cart .add(Vegetable ("レタス", 147, 1))
cart .add(Vegetable ("トマト", 69, 4))
var discount : TotalDiscount
discount = TotalNoDiscount (cart .getTotalPrice())
println("現在の合計金額は " + discount .getPrice() + " 円です。")
// 5%割引
discount = TotalDiscount5percent (discount )
println("現在の合計金額は ${discount.getPrice()} 円です。")
// 5%割引でさらに100円値引き
discount = TotalDiscount100yen (discount )
println("現在の合計金額は ${discount.getPrice()} 円です。")
// 100円引きでさらに5%割引
discount = TotalDiscount5percent (TotalDiscount100yen (TotalNoDiscount (cart .getTotalPrice())))
println("現在の合計金額は ${discount.getPrice()} 円です。")
}
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.kt
abstract class TotalDiscount {
abstract fun getPrice() : Int
}
解答
TotalDiscount.kt
abstract class TotalDiscount {
abstract fun getPrice() : Int
}
TotalNoDiscount.kt
class TotalNoDiscount (private var price : Int) : TotalDiscount () {
override fun getPrice() : Int = price
}
TotalDiscount5percent.kt
class TotalDiscount5percent (private val discount : TotalDiscount ) : TotalDiscount {
override fun getPrice(): Int = (discount .getPrice() * 0.95).toInt()
}
TotalDiscount100yen.kt
class TotalDiscount100yen (private val discount : TotalDiscount ) : TotalDiscount {
override fun getPrice(): Int = discount .getPrice() - 100
}
Enshu103.scala
object Main103 {
def main(args : Array [String]) {
val cart = new Cart ()
cart .add(new Vegetable ("大根", 125, 1))
cart .add(new Vegetable ("レタス", 147, 1))
cart .add(new Vegetable ("トマト", 69, 4))
var discount : TotalDiscount = null
discount = new TotalNoDiscount (cart .getTotalPrice())
System.out.println("現在の合計金額は %d 円です。".format(discount .getPrice()))
// 5%割引
discount = new TotalDiscount5percent (discount )
System.out.println("現在の合計金額は %d 円です。".format(discount .getPrice()))
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount )
System.out.println("現在の合計金額は %d 円です。".format(discount .getPrice()))
// 100円引きでさらに5%割引
discount = new TotalDiscount5percent (TotalDiscount100yen (new TotalNoDiscount (cart .getTotalPrice())))
System.out.println("現在の合計金額は %d 円です。".format(discount .getPrice()))
}
}
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.scala
abstract class TotalDiscount {
def getPrice() : Int
}
解答
TotalDiscount.scala
abstract class TotalDiscount {
def getPrice() : Int
}
TotalNoDiscount.scala
class TotalNoDiscount (var price : Int) extends TotalDiscount () {
override def getPrice() : Int = price
}
TotalDiscount5percent.kt
class TotalDiscount5percent (private val discount : TotalDiscount ) extends TotalDiscount {
override def getPrice(): Int = (discount .getPrice() * 0.95).toInt()
}
TotalDiscount100yen.scala
class TotalDiscount100yen (val discount : TotalDiscount ) extends TotalDiscount {
override def getPrice(): Int = discount .getPrice() - 100
}
Enshu103.groovy
class Enshu103 {
static void main(String[] args ) {
Cart cart = new Cart ()
cart .add(new Vegetable ("大根", 125, 1))
cart .add(new Vegetable ("レタス", 147, 1))
cart .add(new Vegetable ("トマト", 69, 4))
TotalDiscount discount
discount = new TotalNoDiscount (cart .getTotalPrice())
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。")
// 5%割引
discount = new TotalDiscount5percent (discount )
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。")
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount )
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。")
// 100円引きでさらに5%割引
discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount (cart .getTotalPrice())))
System.out .println("現在の合計金額は " + discount .getPrice() + " 円です。")
}
}
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.groovy
abstract class TotalDiscount {
public abstract int getPrice()
}
解答
TotalDiscount.groovy
abstract class TotalDiscount {
abstract int getPrice()
}
TotalNoDiscount.groovy
class TotalNoDiscount extends TotalDiscount {
int price
TotalNoDiscount (int price ) {
this.price = price
}
}
TotalDiscount5percent.groovy
class TotalDiscount5percent extends TotalDiscount {
TotalDiscount discount
TotalDiscount5percent (TotalDiscount discount ) {
this.discount = discount
}
int getPrice() {
return (int)(discount .getPrice() * 0.95)
}
}
TotalDiscount100yen.groovy
class TotalDiscount100yen extends TotalDiscount {
TotalDiscount discount
TotalDiscount100yen (TotalDiscount discount ) {
this.discount = discount
}
int getPrice() {
return discount .getPrice() - 100
}
}
Enshu103.go
import "fmt"
func main() {
var cart = NewCart ()
cart .Add (NewVegetable ("大根", 125, 1))
cart .Add (NewVegetable ("レタス", 147, 1))
cart .Add (NewVegetable ("トマト", 69, 4))
// 割引なし
var discount ITotalDiscount = NewTotalNoDiscount (cart .GetTotalPrice ())
fmt.Printf("現在の合計金額は %d 円です。\n", discount .GetPrice ())
// 5%割引
discount = NewTotalDiscount5percent (discount )
fmt.Printf("現在の合計金額は %d 円です。\n", discount .GetPrice ())
// 5%割引でさらに100円値引き
discount = NewTotalDiscount100yen (discount )
fmt.Printf("現在の合計金額は %d 円です。\n", discount .GetPrice ())
// 100円引きでさらに5%割引
discount = NewTotalDiscount5percent (NewTotalDiscount100yen (NewTotalNoDiscount (cart .GetTotalPrice ())))
fmt.Printf("現在の合計金額は %d 円です。\n", discount .GetPrice ())
}
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、GetPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。GetPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、GetPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.go
import "errors"
type ITotalDiscount interface {
GetPrice () int
}
type TotalDiscount struct {}
func (self *TotalDiscount ) GetPrice () int {
panic(errors.New("GetPrice メソッドを定義してください。"))
}
解答
TotalDiscount.go
mport "errors"
type ITotalDiscount interface {
GetPrice () int
}
type TotalDiscount struct {}
func (self *TotalDiscount ) GetPrice () int {
panic(errors.New("GetPrice メソッドを定義してください。"))
}
TotalNoDiscount.go
type TotalNoDiscount struct {
ITotalDiscount
*TotalDiscount
price int
}
func (self *TotalNoDiscount ) GetPrice () int {
return self.price
}
func NewTotalNoDiscount (price int) *TotalNoDiscount {
return &TotalNoDiscount {
TotalDiscount : new(TotalDiscount ),
price : price ,
}
}
TotalDiscount5percent.go
type TotalDiscount5percent struct {
ITotalDiscount
*TotalDiscount
discount ITotalDiscount
}
func (self *TotalDiscount5percent ) GetPrice () int {
return int(float32(self.discount .GetPrice ()) * 0.95)
}
func NewTotalDiscount5percent (discount ITotalDiscount ) *TotalDiscount5percent {
return &TotalDiscount5percent {
TotalDiscount : new(TotalDiscount ),
discount : discount ,
}
}
TotalDiscount100yen.go
type TotalDiscount100yen struct {
ITotalDiscount
*TotalDiscount
discount ITotalDiscount
}
func (self *TotalDiscount100yen ) GetPrice () int {
return self.discount .GetPrice () - 100
}
func NewTotalDiscount100yen (discount ITotalDiscount ) *TotalDiscount100yen {
return &TotalDiscount100yen {
TotalDiscount : new(TotalDiscount ),
discount : discount ,
}
}
enshu103.d
import cart;
import vegetable;
import totaldiscount;
import totalnodiscount;
import totaldiscount5percent;
import totaldiscount100yen;
int main() {
Cart cart = new Cart ();
cart .add(new Vegetable ("大根", 125, 1));
cart .add(new Vegetable ("レタス", 147, 1));
cart .add(new Vegetable ("トマト", 69, 4));
TotalDiscount discount ;
discount = new TotalNoDiscount (cart .getTotalPrice());
printfln("現在の合計金額は %d 円です。", discount .getPrice());
// 5%割引
discount = new TotalDiscount5percent (discount );
printfln("現在の合計金額は %d 円です。", discount .getPrice());
// 5%割引でさらに100円値引き
discount = new TotalDiscount100yen (discount );
printfln("現在の合計金額は %d 円です。", discount .getPrice());
// 100円引きでさらに5%割引
discount = new TotalDiscount5percent (new TotalDiscount100yen (new TotalNoDiscount (cart .getTotalPrice())));
printfln("現在の合計金額は %d 円です。", discount .getPrice());
return 0;
}
private void printfln(T...)(T args ) { // Shift JIS 出力
import std, std.windows.charset, core.vararg;
std.stdio.write(to!(string)(toMBSz(std.format.format(args ))) ~ "\n");
}
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
totaldiscount.d
public abstract class TotalDiscount {
public abstract int getPrice();
}
解答
totaldiscount.d
public abstract class TotalDiscount {
public abstract int getPrice();
}
totalnodiscount.d
import totaldiscount;
public class TotalNoDiscount : TotalDiscount {
protected int price ;
public this(in int price ) {
this.price = price ;
}
public override int getPrice() {
return price ;
}
}
totaldiscount5percent.d
import std.conv;
import totaldiscount;
public class TotalDiscount5percent : TotalDiscount {
private TotalDiscount discount ;
public this(TotalDiscount discount ) {
this.discount = discount ;
}
public override int getPrice() {
return to!(int)(discount .getPrice() * 0.95);
}
}
totaldiscount100yen.d
import totaldiscount;
public class TotalDiscount100yen : TotalDiscount {
private TotalDiscount discount ;
public this(TotalDiscount discount ) {
this.discount = discount ;
}
public override int getPrice() {
return discount .getPrice() - 100;
}
}
Enshu103.dpr
program Enshu103;
uses
System.SysUtils,
UnitVegetable,
UnitMeat,
UnitCart,
UnitTotalDiscount,
UnitTotalNoDiscount,
UnitTotalDiscount5percent,
UnitTotalDiscount100yen;
var _cart :Cart ;
var discount :TotalDiscount ;
begin
_cart := Cart .Create();
_cart .add(Vegetable .Create('大根', 125, 1));
_cart .add(Vegetable .Create('レタス', 147, 1));
_cart .add(Vegetable .Create('トマト', 69, 4));
// 割引なし
discount := TotalNoDiscount .Create(_cart.getTotalPrice());
Writeln(Format('現在の合計金額は %d 円です。', [discount .getPrice()]));
// 5%割引
discount := TotalDiscount5percent .Create(discount );
Writeln(Format('現在の合計金額は %d 円です。', [discount .getPrice()]));
// 5%割引でさらに100円値引き
discount := TotalDiscount100yen .Create(discount );
Writeln(Format('現在の合計金額は %d 円です。', [discount .getPrice()]));
discount .Free;
// 100円引きでさらに5%割引
discount := TotalDiscount5percent .Create(TotalDiscount100yen .Create(TotalNoDiscount .Create(_cart .getTotalPrice())));
Writeln(Format('現在の合計金額は %d 円です。', [discount .getPrice()]));
discount .Free;
_cart .Free;
end.
ヒント(TotalDiscount クラス)
スーパークラスとして TotalDiscount クラスを作ります。そして、getPrice() を作成しますが、実際の処理は TotalDiscount クラスでは記述しません。
TotalNoDiscount クラス、TotalDiscount5percent クラスや TotalDiscount100Yen クラスは TotalDiscount クラスを継承して作ります。getPrice() の実際の処理はこれらのサブクラスで実装します。
TotalNoDiscount クラス以外の各サブクラスの getPrice()では、コンストラクタで受け取った TotalDiscount クラスのサブクラスの getPrice() を呼び出して価格を得て、さらに割引処理を行い割引された価格を返します。
しかし、一番最初の TotalNoDiscount クラスだけは、コンストラクタで Integer 型の価格を受け取り、getPrice() でそのままの価格を返します。この過程を経ることにより、TotalNoDiscount クラス以外の TotalDiscount クラスのサブクラスの組み合わせや順序が自由になります。
TotalDiscount クラスのコードを見ますか? はい いいえ
TotalDiscount.pas
unit UnitTotalDiscount;
interface
type
TotalDiscount = class
public
function getPrice():integer; virtual; abstract;
end;
implementation
end.
解答
TotalDiscount.pas
unit UnitTotalDiscount;
interface
type
TotalDiscount = class
public
function getPrice():integer; virtual; abstract;
end;
implementation
end.
TotalNoDiscount.pas
unit UnitTotalNoDiscount;
interface
uses
UnitTotalDiscount;
type
TotalNoDiscount = class(TotalDiscount )
protected
var price :integer;
public
constructor Create(price :integer);
function getPrice():integer; override;
end;
implementation
constructor TotalNoDiscount.Create(price :integer);
begin
self.price := price ;
end;
function TotalNoDiscount.getPrice():integer;
begin
Result := price ;
end;
end.
TotalDiscount5percent.pas
unit UnitTotalDiscount5percent;
interface
uses
UnitTotalDiscount;
type
TotalDiscount5percent = class(TotalDiscount )
private
var discount :TotalDiscount ;
public
constructor Create(discount:TotalDiscount );
destructor Destroy(); override;
function getPrice():integer; override;
end;
implementation
constructor TotalDiscount5percent .Create(discount :TotalDiscount );
begin
self.discount := discount ;
end;
destructor TotalDiscount5percent .Destroy();
begin
discount .Free;
end;
function TotalDiscount5percent .getPrice():integer;
begin
Result := Trunc(discount .getPrice() * 0.95);
end;
end.
TotalDiscount100yen.pas
unit UnitTotalDiscount100yen;
interface
uses
UnitTotalDiscount;
type
TotalDiscount100yen = class(TotalDiscount )
private
var discount :TotalDiscount ;
public
constructor Create(discount :TotalDiscount );
destructor Destroy(); override;
function getPrice():integer; override;
end;
implementation
constructor TotalDiscount100yen .Create(discount :TotalDiscount );
begin
self.discount := discount ;
end;
destructor TotalDiscount100yen .Destroy();
begin
discount .Free;
end;
function TotalDiscount100yen .getPrice():integer;
begin
Result := discount .getPrice() - 100;
end;
end.
演習問題1-3 (Decorator)