Pythonでオブジェクト指向のサンプルを見る

2023年2月22日

基本的なオブジェクト指向プログラミングの概念を実証するPythonの単純なクラスの例です。

この例では、クラスの新しいインスタンスが作成されたときに呼び出されるコンストラクタメソッド(__init__)でDogクラスを定義します。コンストラクタは、オブジェクトの初期状態を設定するために使用されるnameageの2つの引数を取ります。クラスには、barkbirthday2つの方法があり、それぞれ「Woof woof!」を印刷します。そして、犬の年齢に1つを追加します。また、オブジェクトの文字列表現、この場合は犬の名前と年齢を返すために使用される__str__メソッドも定義します。

コードの最後の部分では、Dogクラスのdog1dog2の2つのインスタンスを作成し、その情報を印刷してメソッドを実行します

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print("ワンワン")

    def birthday(self):
        self.age += 1

    def __str__(self):
        return f"名前: {self.name}, 年齢: {self.age}"


dog1 = Dog("ポチ", 3)
dog2 = Dog("ペス", 5)

print(dog1)
print(dog2)

dog1.bark()
dog1.birthday()
print(dog1)

実行結果

名前: ポチ, 年齢: 3
名前: ペス, 年齢: 5
ワンワン
名前: ポチ, 年齢: 4

C#で置き換えると

C#では、クラスはキーワードclassで定義され、そのプロパティとメソッドはクラスの内部で定義されます。
コンストラクタはキーワードpublicで定義され、その名前はクラス名と同じになります。
print文はConsole.WriteLine()に置き換わります。
C#ではselfキーワードは使用されず、このキーワードはクラスの現在のインスタンスを参照するために使用されます。
__str__メソッドは、オーバーライドされたToString()メソッドに置き換えられ、オブジェクトの文字列表現を返します。
C#では、変数のインクリメントに++、加算に+=を使用します

Dog dog1 = new Dog("ポチ", 3);
Dog dog2 = new Dog("ペス", 5);

Console.WriteLine(dog1.ToString());
Console.WriteLine(dog2.ToString());

dog1.bark();
dog1.birthday();
Console.WriteLine(dog1.ToString());

class Dog
{
    public string name { get; set; }
    public int age { get; set; }

    public Dog(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public void bark()
    {
        Console.WriteLine("ワンワン");
    }

    public void birthday()
    {
        this.age++;
    }

    public override string ToString()
    {
        return $"名前: {name}, 年齢: {age}";
    }
}

JavaScriptで置き換えると

JavaScriptでは、クラスはキーワードclassで定義され、そのプロパティとメソッドはクラスの内部で定義されます。
コンストラクタはキーワードconstructorで定義され、その名前はクラス名と同じになります。
print文はconsole.log()に置き換えられる。
JavaScript では self キーワードは使用されず、このキーワードはクラスの現在のインスタンスを参照するために使用されます。
__str__ メソッドは toString() メソッドに置き換えられ、オブジェクトの文字列表現を返すようになりました。
JavaScript では、変数のインクリメントに ++ を、加算に += を使用します。

let キーワードは変数 dog1 と dog2 を定義するのに使われていますが、必要に応じて var や const に置き換えることができます

class Dog {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  bark() {
    console.log("ワンワン");
  }

  birthday() {
    this.age++;
  }

  toString() {
    return `名前: ${this.name}, 年齢: ${this.age}`;
  }
}

let dog1 = new Dog("ポチ", 3);
let dog2 = new Dog("ペス", 5);

console.log(dog1.toString());
console.log(dog2.toString());

dog1.bark();
dog1.birthday();
console.log(dog1.toString());

Javaで置き換えると

Javaでは、クラスはキーワードclassで定義され、そのプロパティとメソッドはクラスの内部で定義されます。
コンストラクタはキーワードpublicで定義され、その名前はクラス名と同じになります。
print文はSystem.out.println()に置き換えます。
Java では self キーワードは使用されず、このキーワードはクラスの現在のインスタンスを参照するために使用されます。
__str__メソッドは、オーバーライドされたtoString()メソッドに置き換えられ、オブジェクトの文字列表現を返します。
Java では、変数のインクリメントには ++ を、加算には += を使用します。

Javaでは、プロパティは最初に宣言し、コンストラクタで初期化する必要があることに注意してください。
また、変数 dog1 と dog2 はクラスの外部で定義されており、クラスのコンストラクタを使って新しいオブジェクトをインスタンス化することで生成されます。

class Dog {
  String name;
  int age;

  public Dog(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public void bark() {
    System.out.println("ワンワン");
  }

  public void birthday() {
    age++;
  }

  public String toString() {
    return "名前: " + name + ", 年齢: " + age;
  }
}

Dog dog1 = new Dog("ポチ", 3);
Dog dog2 = new Dog("ペス", 5);

System.out.println(dog1.toString());
System.out.println(dog2.toString());

dog1.bark();
dog1.birthday();
System.out.println(dog1.toString());

C++で置き換えると

C++では、クラスはキーワードclassで定義され、そのプロパティとメソッドはクラスの内部で定義されます。
コンストラクタはクラス内部でキーワードpublicで定義され、その名前はクラス名と同じになります。
print文は、cout << と endl; に置き換えられます。
C++ではselfキーワードは使用されず、代わりにthis->がクラスの現在のインスタンスを参照するために使用されます。
__str__ メソッドは、オブジェクトの文字列表現を返す toString() メソッドに置き換えられました。
C++では、変数のインクリメントには++を、加算には+=を使用します。

C++では、文字列と入出力操作を使用するために、それぞれstringライブラリとiostreamライブラリをインクルードする必要があることに注意してください。また、整数値から文字列への変換にはto_string()という関数が使われます。

また、変数dog1とdog2はクラスの外で定義されており、クラスのコンストラクタを使って新しいオブジェクトをインスタンス化することで生成されます。

class Dog {
  public:
    string name;
    int age;

    Dog(string name, int age) {
        this->name = name;
        this->age = age;
    }

    void bark() {
        cout << "ワンワン" << endl;
    }

    void birthday() {
        age++;
    }

    string toString() {
        return "名前: " + name + ", 年齢: " + to_string(age);
    }
};

Dog dog1("ポチ", 3);
Dog dog2("ペス", 5);

cout << dog1.toString() << endl;
cout << dog2.toString() << endl;

dog1.bark();
dog1.birthday();
cout << dog1.toString() << endl;

PHPで置き換えると

PHPでは、クラスはキーワードclassで定義され、そのプロパティとメソッドはクラスの内部で定義されます。
コンストラクタはキーワード public function __construct() で定義され、その名前は __construct となります。
print 文は echo で置き換えられ、PHP_EOL で改行が追加されます。
PHP では self キーワードは使用されず、代わりに $this キーワードが現在のクラスのインスタンスを参照するために使用されます。
__str__ メソッドの代わりに __toString() メソッドがオーバーライドされ、 オブジェクトの文字列表現を返します。
PHP では、変数のインクリメントに ++ を、加算に += を使用します。

PHPでは、変数は$記号で示され、クラスのコンストラクタを使用して新しいオブジェクトをインスタンス化することによって作成されることに注意してください。
また、__toString()関数は、オブジェクトの文字列表現を返すために使用され、 echoやprintと一緒に使用されるべきものです

class Dog {
    public $name;
    public $age;

    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }

    public function bark() {
        echo "ワンワン" . PHP_EOL;
    }

    public function birthday() {
        $this->age++;
    }

    public function __toString() {
        return "名前: " . $this->name . ", 年齢: " . $this->age;
    }
}

$dog1 = new Dog("ポチ", 3);
$dog2 = new Dog("ペス", 5);

echo $dog1 . PHP_EOL;
echo $dog2 . PHP_EOL;

$dog1->bark();
$dog1->birthday();
echo $dog1 . PHP_EOL;

Basicで置き換えると

Pythonはオブジェクト指向プログラミング言語であり、BASICはOOPをネイティブにサポートしていないため、与えられたPythonのコードをBASICに直接翻訳することは困難です。しかし、BASICではプロシージャや関数を用いて同様の機能を実現することができます。以下は、BASICでPythonコードの動作をシミュレートする例です

' define a subroutine to handle the dog's bark
SUB bark(dogName AS STRING)
    PRINT dogName; " says Woof woof!"
END SUB

' define a subroutine to handle the dog's birthday
SUB birthday(dogAge AS INTEGER)
    dogAge = dogAge + 1
END SUB

' create a dog
DIM dog1 AS STRING, dog1Age AS INTEGER
dog1 = "Fido"
dog1Age = 3

' create another dog
DIM dog2 AS STRING, dog2Age AS INTEGER
dog2 = "Buddy"
dog2Age = 5

' print the dogs' information
PRINT "Dog 1: "; dog1; ", "; dog1Age
PRINT "Dog 2: "; dog2; ", "; dog2Age

' make the dogs bark
bark(dog1)
bark(dog2)

' give the dogs a birthday
birthday(dog1Age)
birthday(dog2Age)

' print the dogs' updated information
PRINT "Dog 1: "; dog1; ", "; dog1Age
PRINT "Dog 2: "; dog2; ", "; dog2Age

この例では、犬のプロパティは別の変数として定義され、動作はサブルーチン(SUB)と関数でシミュレートされている。
吠えるサブルーチンは犬の名前を引数として受け取り、メッセージを表示する。
誕生日サブルーチンは犬の年齢を引数にとり、1つずつ増やしていく。
dog1 と dog2 という変数が犬の名前を格納するのに使われ、dog1Age と dog2Age という変数が犬の年齢を格納するのに使われます。
DIM文は、変数の宣言と初期化に使用します。
PRINT文は、変数の値を表示するために使用されます。

これは、BASICにおけるOOP動作の非常に基本的なシミュレーションであり、実際のOOP言語の機能や利点の多くが欠けていることに留意する必要があります。

Cで置き換えると

ここでは、与えられたPythonのコードをC言語に翻訳する例を示します

#include <stdio.h>

struct Dog {
    char name[50];
    int age;
};

void bark(struct Dog *dog) {
    printf("%s says Woof woof!\n", dog->name);
}

void birthday(struct Dog *dog) {
    dog->age += 1;
}

int main() {
    struct Dog dog1 = {"Fido", 3};
    struct Dog dog2 = {"Buddy", 5};

    printf("Dog 1: %s, %d\n", dog1.name, dog1.age);
    printf("Dog 2: %s, %d\n", dog2.name, dog2.age);

    bark(&dog1);
    bark(&dog2);

    birthday(&dog1);
    birthday(&dog2);

    printf("Dog 1: %s, %d\n", dog1.name, dog1.age);
    printf("Dog 2: %s, %d\n", dog2.name, dog2.age);

    return 0;
}

この例では、nameとageのフィールドを持つDog構造体が定義されています。
bark 関数は、Dog 構造体へのポインタを受け取り、犬の名前を使用してメッセージを表示します。
birthday 関数は、Dog 構造体へのポインタを受け取り、犬の年齢をインクリメントします。
dog1、dog2構造体を作成し、それぞれの名前と年齢の値で初期化します。
printf関数は、犬の情報とbirthday関数が呼ばれた後に更新された情報を表示するために使用されます。
なお、C言語では、構造体変数を変更する関数に構造体変数のアドレスを渡す必要があるため、変数名の前に&演算子を付けています。
また、name フィールドは文字列ではなく文字配列として定義されていますが、これは C 言語に文字列データ型が組み込まれていないためです

Rで置き換えると

Rはpythonのようなオブジェクト指向言語ではないので、pythonと同じ構造でRのコードを書くことはできません。しかし、Rでは関数とデータ構造、例えばリストやデータフレームを使って同様の機能を実現することができます。ここでは、Pythonのコードの動作をRでシミュレートする例を紹介します。

bark <- function(dogName){
    cat(paste(dogName, "says Woof woof!"))
}

birthday <- function(dogAge){
    dogAge <- dogAge + 1
}

dog1 <- list(name = "Fido", age = 3)
dog2 <- list(name = "Buddy", age = 5)

cat(paste("Dog 1: ", dog1$name, ", ", dog1$age))
cat("\n")
cat(paste("Dog 2: ", dog2$name, ", ", dog2$age))
cat("\n")

bark(dog1$name)
bark(dog2$name)

dog1$age <- birthday(dog1$age)
dog2$age <- birthday(dog2$age)

cat(paste("Dog 1: ", dog1$name, ", ", dog1$age))
cat("\n")
cat(paste("Dog 2: ", dog2$name, ", ", dog2$age))
cat("\n")

この例では、bark関数は犬の名前を引数に取り、cat関数とpaste関数を用いてメッセージを表示します。
birthday関数は犬の年齢を引数にとり、年齢を 1 つ増やします。 リストdog1dog2が作成され、それぞれの名前と年齢の値で初期化されます。 cat 関数は犬の情報と、birthday 関数が呼ばれた後に更新された情報を表示するために使用されます。
そして、文字列と変数を連結するために paste 関数が使われている。
R では、リスト変数を変更する関数にリストの変数名を渡す必要があるため、変数名の前に $ 演算子をつけていることに注意してください。
また、これはRにおけるOOPの動作の非常に基本的なシミュレーションであり、実際のOOP言語の機能や利点の多くを欠いていることに留意する必要があります。

Rubyで置き換えると

ここでは、与えられたPythonのコードをRubyに翻訳する例を示します

class Dog
    attr_accessor :name, :age
    def initialize(name, age)
        @name = name
        @age = age
    end
    def bark
        puts "ワンワン"
    end
    def birthday
        @age += 1
    end
    def to_s
        "名前: #{@name}, 年齢: #{@age}"
    end
end

dog1 = Dog.new("ポチ", 3)
dog2 = Dog.new("ペス", 5)

puts dog1
puts dog2

dog1.bark
dog1.birthday
puts dog1

Rubyでは、クラスはキーワードclassで定義し、そのプロパティはattr_accessorメソッドで定義します。
コンストラクタはinitializeメソッドで定義され、その名前はクラス名と同じである。
print文はputsに置き換えられる。
self キーワードは Ruby では使用されず、クラスの現在のインスタンスを暗黙的に参照します。
__str__ メソッドは to_s メソッドに置き換えられ、オーバーライドされてオブジェクトの文字列表現を返します。
Ruby では加算に += を使用します。

なお、Rubyでは、変数はクラスのコンストラクタを使って新しいオブジェクトをインスタンス化することで生成されます。これは、クラス名の後に.newを付けて呼び出し、必要な引数を与えることで行われます。また、attr_accessorメソッドを使ってプロパティにゲッターメソッドとセッターメソッドを定義し、直接アクセスしたり変更したりすることができるようにしています。

なお、上記の例では、putsを使用する際に、オブジェクトを文字列表現に変換するためにto_sメソッドを自動的に呼び出していることに注意してください。
また、rubyではメソッドの呼び出しに()を使用する必要はありません

VB.NETで置き換えると

ここでは、与えられたPythonのコードをVB.NETに変換する例を示します

Public Class Dog
    Public Property Name As String
    Public Property Age As Integer

    Public Sub New(name As String, age As Integer)
        Me.Name = name
        Me.Age = age
    End Sub

    Public Sub Bark()
        Console.WriteLine("ワンワン")
    End Sub

    Public Sub Birthday()
        Age += 1
    End Sub

    Public Overrides Function ToString() As String
        Return "名前: " & Name & ", 年齢: " & Age
    End Function
End Class

Dim dog1 As New Dog("ポチ", 3)
Dim dog2 As New Dog("ペス", 5)

Console.WriteLine(dog1.ToString())
Console.WriteLine(dog2.ToString())

dog1.Bark()
dog1.Birthday()
Console.WriteLine(dog1.ToString())

VB.NETでは、クラスはキーワードClassで定義され、プロパティはキーワードPublic Propertyで定義されます。
コンストラクタは、Sub New()メソッドで定義し、その名前はクラス名と同じにします。
文字列の出力には、Console.WriteLine() メソッドを使用しています。
クラスの現在のインスタンスを参照するために、selfの代わりにMeキーワードが使用されています。
__str__メソッドは、オーバーライドされたToString()メソッドに置き換えられ、オブジェクトの文字列表現が返されます。
VB.NETでは、加算のために+=を使用します。

Parlで置き換えると

PerlはPythonのようなオブジェクト指向言語ではないので、Pythonと同じ構造でPerlのコードを記述することはできません。しかし、サブルーチンやデータ構造、例えばハッシュなどを使って、Perlで同様の機能を実現することは可能です。以下にPythonのコードの動作をPerlでシミュレートする例を示します

sub bark {
    my $dog_name = shift;
    print "$dog_name says Woof woof!\n";
}

sub birthday {
    my $dog_age = shift;
    $dog_age++;
}

my %dog1 = (
    name => "Fido",
    age => 3
);

my %dog2 = (
    name => "Buddy",
    age => 5
);

print "Dog 1: $dog1{name}, $dog1{age}\n";
print "Dog 2: $dog2{name}, $dog2{age}\n";

bark($dog1{name});
bark($dog2{name});

birthday($dog1{age});
birthday($dog2{age});

print "Dog 1: $dog1{name}, $dog1{age}\n";
print "Dog 2: $dog2{name}, $dog2{age}\n";

この例では、barkサブルーチンは犬の名前を引数に取り、メッセージを表示する。
誕生日サブルーチンは犬の年齢を引数として取り、1つずつ増やしている。
犬の名前の保存には%dog1と%dog2のハッシュが、犬の年齢の保存には%dog1と%dog2のハッシュが使われる。
print文は犬の情報と誕生日サブルーチン呼び出し後の更新情報を表示するために使用されます。
shift関数は、サブルーチンの引数として渡された値を取得するために使用される。

これはPerlにおけるOOPの動作の非常に基本的なシミュレーションであり、実際のOOP言語の機能や利点の多くが欠けていることに留意する必要があります

学習,設計

Posted by hidepon