様々なプログラミング言語でクラス (あるいはクラスもどき) を書く

## 概要

- 様々なプログラミング言語でクラス (あるいはクラスもどき) を書く

## C++

MyCounter.hpp

```c++
#ifndef MYCOUNTER_H
#define MYCOUNTER_H

#include <string>

class MyCounter {

public:
  MyCounter(int initValue);
  MyCounter(const MyCounter& other);
  MyCounter& operator=(const MyCounter& other);
  virtual ~MyCounter();

  std::string getName();
  void setName(const std::string& name);
  int addCount(int number);
  void print();

  static MyCounter globalCounter;
  static void createGlobalCounter(const std::string& name, int initValue);

private:
  std::string name;
  int count;

  std::string format();
};

#endif /* MYCOUNTER_H */
```

MyCounter.cpp

```c++
#include "MyCounter.hpp"

#include <iostream>
#include <sstream>
#include <string>

MyCounter::MyCounter(int initValue) : name("No Name"), count(initValue) {
}

MyCounter::MyCounter(const MyCounter& other) : name(other.name), count(other.count) {
}

MyCounter& MyCounter::operator=(const MyCounter& other) {
  if (this != &other) {
    this->name = other.name;
	this->count = other.count;
  }
  return *this;
}

MyCounter::~MyCounter() {
}

std::string MyCounter::getName() {
  return this->name;
}

void MyCounter::setName(const std::string& name) {
  this->name = name;
}

int MyCounter::addCount(int number) {
  this->count += number;
  return this->count;
}

void MyCounter::print() {
  std::cout << this->format() << std::endl; 
}

std::string MyCounter::format() {
  std::stringstream ss;
  ss << this->name << ": " << this->count;
  return ss.str();
}

MyCounter MyCounter::globalCounter(0);

void MyCounter::createGlobalCounter(const std::string& name, int initValue) {
  MyCounter newCounter = MyCounter(initValue);
  newCounter.setName(name);
  MyCounter::globalCounter = newCounter;
}
```

MyMain.cpp

```c++
#include "MyCounter.hpp"

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {

  MyCounter counter(0);
  counter.print();

  string name = "John Doe";
  counter.setName(name);
  string currentName = counter.getName();
  cout << "Current Name=" << currentName << endl; 
 
  int currentValue = counter.addCount(10);
  cout << "Current Value=" << currentValue << endl; 

  counter.print();

  string gname = "C with Classes";
  MyCounter::createGlobalCounter(gname, 256);
  MyCounter::globalCounter.print();

  return 0;
}
```

実行結果

```
$ c++ -o mymain MyMain.cpp MyCounter.cpp

$ ./mymain 
No Name: 0
Current Name=John Doe
Current Value=10
John Doe: 10
C with Classes: 256
```

## Java

MyCounter.java

```java
public class MyCounter {

  public static MyCounter globalCounter = null;

  private String name = "No Name";
  private int count;

  public MyCounter(int initValue) {
    count = initValue;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int addCount(int number) {
    count += number;
    return count;
  }

  public void print() {
    System.out.println(format());
  }

  private String format() {
    return name + ": " + count;
  }

  public static void createGlobalCounter(String name, int initValue) {
    globalCounter = new MyCounter(initValue);
    globalCounter.setName(name);
  }
}
```

MyMain.java

```java
public class MyMain {

  public static void main(String[] args) {

    MyCounter counter = new MyCounter(0);
    counter.print();

    counter.setName("John Doe");
    String currentName = counter.getName();
    System.out.println("Current Name=" + currentName);

    int currentValue = counter.addCount(10);
    System.out.println("Current Value=" + currentValue);

    counter.print();

    MyCounter.createGlobalCounter("CafeBabe! Write once, run anywhere", 256);
    MyCounter.globalCounter.print();
  }
}
```

実行結果

```
No Name: 0
Current Name=John Doe
Current Value=10
John Doe: 10
CafeBabe! Write once, run anywhere: 256
```

## JavaScript

my_counter.js

```javascript
class MyCounter {

  constructor(initValue) {
    this._name = 'No Name';
    this.count = initValue;
  }

  get name() {
    return this._name;
  }

  set name(name) {
    this._name = name;
  }

  addCount(number) {
    this.count += number;
    return this.count;
  }

  print() {
    console.log(this._format());
  }

  _format() {
    return this._name + ': ' + this.count;
  }

  static createGlobalCounter(name, init_value) {
    MyCounter.global_counter = new MyCounter(init_value);
    MyCounter.global_counter.name = name;
  }
}

module.exports = MyCounter;
```

my_main.js

```javascript
const MyCounter = require('./my_counter');

counter = new MyCounter(0);
counter.print();

counter.name = 'John Doe';
const currentName = counter.name;
console.log('Current Name=' + currentName);

const currentValue = counter.addCount(10);
console.log('Current Value=' + currentValue);

counter.print();

MyCounter.createGlobalCounter('JavaScript was born from Netscape Navigator 2.0', 256);
MyCounter.global_counter.print();
```

実行結果

```
$ node my_main.js
No Name: 0
Current Name=John Doe
Current Value=10
John Doe: 10
JavaScript was born from Netscape Navigator 2.0: 256
```

参考資料

- [クラス \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes)

## Python

my_counter.py

```python
class MyCounter:

  global_counter = None

  def __init__(self, init_value):
    self.__name = "No Name"
    self.__count = init_value

  @property
  def name(self):
    return self.__name

  @name.setter
  def name(self, name):
    self.__name = name

  def add_count(self, number):
    self.__count += number
    return self.__count

  def print(self):
    print(self.__format())

  def __format(self):
    return "{0}: {1}".format(self.__name, self.__count)

  @classmethod
  def create_global_counter(cls, name, init_value):
    cls.global_counter = MyCounter(init_value)
    cls.global_counter.name = name
```

my_main.py

```python
from my_counter import MyCounter

counter = MyCounter(0)
counter.print()

counter.name = "John Doe"
current_name = counter.name
print("Current Name={}".format(current_name))

current_value = counter.add_count(10)
print("Current Value={}".format(current_value))

counter.print()

MyCounter.create_global_counter("Batteries included. Beautiful is better than ugly.", 256)
MyCounter.global_counter.print()
```

実行結果

```
$ python my_main.py
No Name: 0
Current Name=John Doe
Current Value=10
John Doe: 10
Batteries included. Beautiful is better than ugly.: 256
```

## Ruby

my_counter.rb

```ruby
class MyCounter
  attr_accessor :name

  @@global_counter = nil

  def initialize(init_value)
    @name = 'No Name'
    @count = init_value
  end

  def add_count(number)
    @count += number
  end

  def print
    puts format
  end

  private

  def format
    "#{@name}: #{@count}"
  end

  def self.create_global_counter(name, init_value)
    @@global_counter = self.new(init_value)
    @@global_counter.name = name
  end

  def self.global_counter
    @@global_counter
  end
end
```
my_main.rb

```ruby
require './my_counter'

counter = MyCounter.new(0)
counter.print

counter.name = 'John Doe'
current_name = counter.name
puts "Current Name=#{current_name}"

current_value = counter.add_count(10)
puts "Current Value=#{current_value}"

counter.print

MyCounter.create_global_counter('Everything is an object in Ruby', 256)
MyCounter.global_counter.print
```

```
$ ruby my_main.rb
No Name: 0
Current Name=John Doe
Current Value=10
John Doe: 10
Everything is an object in Ruby: 256
```