C プログラマーのための Python の OOP 概念 98
ここでは、C 98 プログラマー向けの Python での OOP 概念の包括的なデモンストレーションを示します。
クラス定義とオブジェクトの作成
パイソン
# Privado por convenção: _underscore_simples # "Realmente privado": __underscore_duplo (name mangling) # Público: sem underscore from abc import abstractmethod class Animal(ABC): # Em python, variáveis declaradas no escopo da classe e não dentro de um # método específico, são automaticamente compartilhadas por todas instâncias. species_count = 0 # além disso, elas podem ser inicializadas diretamente dentro da classe. # Construtor def __init__(self, name): # Variáveis de instância self.name = name # público self._age = 0 # protegido por convenção self.__id = id(self) # privado (mas você consegue acessar com name mangling) Animal.species_count += 1 # Destrutor def __del__(self): Animal.species_count -= 1 # Método regular @abstractmethod def make_sound(self): pass # Equivalente a um método abstrato/virtual (deve ser implementado apenas nas classes filhas) # Método estático (não precisa da instância para ser utilizado, nem utiliza seus atributos) @staticmethod def get_kingdom(): return "Animalia" # Método de classe (recebe a classe como primeiro argumento, pode acessar atributos da classe) @classmethod def get_species_count(cls): return cls.species_count # Decorador de propriedade (getter) @property def age(self): return self._age # Decorador de propriedade (setter) @age.setter def age(self, value): if value >= 0: self._age = value # Métodos especiais (sobrecarga de operadores) def __str__(self): # Como toString() - para string legível return f"Animal named {self.name}" def __repr__(self): # Para debugging return f"Animal(name='{self.name}')" def __eq__(self, other): # Operador de comparação == return isinstance(other, Animal) and self.name == other.name def __len__(self): # Função len() return self._age def __getitem__(self, key): # Operador de acesso [] if key == 'name': return self.name raise KeyError(key)
C98
#include <iostream> #include <string> #include <sstream> class Animal { public: static int species_count; Animal(const std::string& name) : name(name), _age(0), __id(++id_counter) { // construtor ++species_count; } ~Animal() { // destrutor --species_count; } virtual void make_sound() = 0; // Método não implementável na classe base (virtual/abstrato) static std::string get_kingdom() { // Não existe distinção entre // @classmethod e @staticmethod em cpp, apenas static methods. return "Animalia"; } // static methods podem ser utilizados sem instanciar uma classe e têm // acesso às propriedades estáticas da classe: static int get_species_count() { return species_count; } // getter: int get_age() const { return _age; } // setter: void set_age(int age) { if (age >= 0) { _age = age; } } // Implementação dos métodos especiais que vimos em python: std::string to_string() const { return "Animal named " + name; } std::string repr() const { std::ostringstream oss; oss << "Animal(name='" << name << "', age=" << _age << ",> <h2> Herança </h2> <h3> Python </h3> <pre class="brush:php;toolbar:false">class Dog(Animal): def __init__(self, name, breed): # Chama o construtor da classe pai super().__init__(name) self.breed = breed # Sobrescreve o método da classe pai def make_sound(self): return "Woof!"
C98
class Dog : public Animal { public: Dog(const std::string& name, const std::string& breed) : Animal(name), breed(breed) {} void make_sound() override { std::cout << "Woof!" << std::endl; } private: std::string breed; };
多重継承
パイソン
class Pet: def is_vaccinated(self): return True class DomesticDog(Dog, Pet): pass
C98
class Pet { public: bool is_vaccinated() const { return true; } }; class DomesticDog : public Dog, public Pet { public: DomesticDog(const std::string& name, const std::string& breed) : Dog(name, breed) {} };
抽象クラス
パイソン
from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): pass
C98
class Shape { public: virtual ~Shape() {} virtual double area() const = 0; };
使用例
パイソン
if __name__ == "__main__": # Cria objetos dog = Dog("Rex", "Golden Retriever") # Acessa atributos print(dog.name) # Público print(dog._age) # Protegido (ainda acessível) # print(dog.__id) # Isso falhará print(dog._Animal__id) # Isso funciona (acessando attribute privado com name mangling) # Propriedades dog.age = 5 # Usa setter automaticamente print(dog.age) # Usa getter automaticamente # Métodos estáticos e de classe print(Animal.get_kingdom()) print(Animal.get_species_count()) # Verifica herança print(isinstance(dog, Animal)) # True print(issubclass(Dog, Animal)) # True # Métodos especiais em ação print(str(dog)) # Usa __str__ print(repr(dog)) # Usa __repr__ print(len(dog)) # Usa __len__ print(dog['name']) # Usa __getitem__
C98
int main() { // Cria objetos Dog dog("Rex", "Golden Retriever"); // Acessa atributos std::cout << dog.name << std::endl; // Público std::cout << dog.get_age() << std::endl; // Protegido (ainda acessível) // std::cout << dog.__id << std::endl; // Isso falhará (privado) // Propriedades dog.set_age(5); // Usa setter std::cout << dog.get_age() << std::endl; // Usa getter // Métodos estáticos e de classe std::cout << Animal::get_kingdom() << std::endl; std::cout << Animal::get_species_count() << std::endl; // Equivalente aos "métodos especiais": // Verifica herança if (dog.isinstance<Animal>()) { std::cout << "dog é uma instância de Animal" << std::endl; } std::cout << dog.to_string() << std::endl; // Usa to_string std::cout << dog.repr() << std::endl; // Usa repr std::cout << dog["name"] << std::endl; // Usa operador [] }
Python と C 98 の主な違い
- パブリック/プライベート/保護されたキーワードなし (命名規則を使用)
- 多重継承は次のように異なります。
- Python は C3 線形化で Method Resolution Order (MRO) を使用します
- C のような仮想継承は必要ありません
- super() は自動的に MRO に従います
- Python では基本クラスの順序が重要です
- __mro__ を使用して解決順序を検査できます。
- すべてのメソッドはデフォルトで仮想です
- ポインタと参照の間に区別はありません
- メモリ管理 (ガベージコレクター) が不要
- 静的型付けではなく動的型付け
- ゲッター/セッター メソッドの代わりのプロパティ デコレーター
- 特別なメソッドは、operator キーワードの代わりに __name__ 形式を使用します
- 演算子のオーバーロードのためのその他の Python 構文 (例: __eq__ と Operator==)
オブジェクトの属性とメソッドをすべて表示するには dir(object) を使用し、ドキュメントについては help(object) を使用します。
特別なトピック:
ダイヤモンドの相続問題
Animal . ' , _______ _ .`_|___|_`. _ Pet \ \ / / WorkingAnimal \ ' ' / \ " / \./ DomesticDog
C 98 におけるダイヤモンドの継承に関する問題
ダイヤモンドの継承は、クラスが 2 つのクラスから継承し、さらにそのクラスが共通の基本クラスから継承するときに発生します。これにより、いくつかの問題が発生する可能性があります:
- 曖昧さ: 共通基本クラスのメソッドと属性があいまいになる可能性があります。
- データの重複: 各派生クラスは、共通の基本クラスのメンバーの独自のコピーを持つことができ、データの重複が発生します。
C 98 におけるダイヤモンドの継承の例
class Animal { public: Animal() { std::cout << "Animal constructor" << std::endl; } virtual void make_sound() { std::cout << "Some generic animal sound" << std::endl; } }; class Pet : public Animal { public: Pet() : Animal() { std::cout << "Pet constructor" << std::endl; } void make_sound() override { std::cout << "Pet sound" << std::endl; } }; class WorkingAnimal : public Animal { public: WorkingAnimal() : Animal() { std::cout << "WorkingAnimal constructor" << std::endl; } void make_sound() override { std::cout << "Working animal sound" << std::endl; } }; class DomesticDog : public Pet, public WorkingAnimal { public: DomesticDog() : Animal(), Pet(), WorkingAnimal() { std::cout << "DomesticDog constructor" << std::endl; } void make_sound() override { Pet::make_sound(); // Ou WorkingAnimal::make_sound(), dependendo do comportamento desejado } }; int main() { DomesticDog dog; dog.make_sound(); return 0; }
期待される動作
Animal constructor Pet constructor WorkingAnimal constructor DomesticDog constructor Pet sound
この例では、domesticDog は Pet と WorkingAnimal を継承しており、どちらも Animal を継承しています。これにより家宝のダイヤモンドが生まれます。仮想継承は、データの重複と曖昧さを回避するために使用されます。
Python がダイヤモンドの継承を自動的に防ぐ方法
Python は C3 線形化による Method Resolution Order (MRO) を使用して、ダイヤモンド継承の問題を自動的に解決します。 MRO は、メソッドまたは属性を検索するときにクラスがチェックされる順序を決定します。
Python でのダイヤモンド継承の例
# Privado por convenção: _underscore_simples # "Realmente privado": __underscore_duplo (name mangling) # Público: sem underscore from abc import abstractmethod class Animal(ABC): # Em python, variáveis declaradas no escopo da classe e não dentro de um # método específico, são automaticamente compartilhadas por todas instâncias. species_count = 0 # além disso, elas podem ser inicializadas diretamente dentro da classe. # Construtor def __init__(self, name): # Variáveis de instância self.name = name # público self._age = 0 # protegido por convenção self.__id = id(self) # privado (mas você consegue acessar com name mangling) Animal.species_count += 1 # Destrutor def __del__(self): Animal.species_count -= 1 # Método regular @abstractmethod def make_sound(self): pass # Equivalente a um método abstrato/virtual (deve ser implementado apenas nas classes filhas) # Método estático (não precisa da instância para ser utilizado, nem utiliza seus atributos) @staticmethod def get_kingdom(): return "Animalia" # Método de classe (recebe a classe como primeiro argumento, pode acessar atributos da classe) @classmethod def get_species_count(cls): return cls.species_count # Decorador de propriedade (getter) @property def age(self): return self._age # Decorador de propriedade (setter) @age.setter def age(self, value): if value >= 0: self._age = value # Métodos especiais (sobrecarga de operadores) def __str__(self): # Como toString() - para string legível return f"Animal named {self.name}" def __repr__(self): # Para debugging return f"Animal(name='{self.name}')" def __eq__(self, other): # Operador de comparação == return isinstance(other, Animal) and self.name == other.name def __len__(self): # Função len() return self._age def __getitem__(self, key): # Operador de acesso [] if key == 'name': return self.name raise KeyError(key)
期待される動作
#include <iostream> #include <string> #include <sstream> class Animal { public: static int species_count; Animal(const std::string& name) : name(name), _age(0), __id(++id_counter) { // construtor ++species_count; } ~Animal() { // destrutor --species_count; } virtual void make_sound() = 0; // Método não implementável na classe base (virtual/abstrato) static std::string get_kingdom() { // Não existe distinção entre // @classmethod e @staticmethod em cpp, apenas static methods. return "Animalia"; } // static methods podem ser utilizados sem instanciar uma classe e têm // acesso às propriedades estáticas da classe: static int get_species_count() { return species_count; } // getter: int get_age() const { return _age; } // setter: void set_age(int age) { if (age >= 0) { _age = age; } } // Implementação dos métodos especiais que vimos em python: std::string to_string() const { return "Animal named " + name; } std::string repr() const { std::ostringstream oss; oss << "Animal(name='" << name << "', age=" << _age << ",> <h2> Herança </h2> <h3> Python </h3> <pre class="brush:php;toolbar:false">class Dog(Animal): def __init__(self, name, breed): # Chama o construtor da classe pai super().__init__(name) self.breed = breed # Sobrescreve o método da classe pai def make_sound(self): return "Woof!"
この例では、Python は MRO を使用してダイヤモンドの継承を自動的に解決します。 __mro__:
属性を使用して MRO を確認できます
class Dog : public Animal { public: Dog(const std::string& name, const std::string& breed) : Animal(name), breed(breed) {} void make_sound() override { std::cout << "Woof!" << std::endl; } private: std::string breed; };
Python の MRO は、domesticDog が Pet および WorkingAnimal から正しく継承され、Animal がオブジェクトの前に解決されることを保証します。したがって、宣言順序は MRO に影響しますが、C3 線形化により階層が確実に尊重されます。
説明:
- 宣言順序: MRO は最も派生したクラスから始まり、基本クラスが宣言された順序に従います。
- C3 線形化: 各クラスがそのスーパークラスの前に表示され、継承の順序が維持されるようにします。
データ構造: スタック、キュー、マップ
スタック
パイソン
class Pet: def is_vaccinated(self): return True class DomesticDog(Dog, Pet): pass
C98
class Pet { public: bool is_vaccinated() const { return true; } }; class DomesticDog : public Dog, public Pet { public: DomesticDog(const std::string& name, const std::string& breed) : Dog(name, breed) {} };
列
パイソン
from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): pass
C98
class Shape { public: virtual ~Shape() {} virtual double area() const = 0; };
地図
パイソン
if __name__ == "__main__": # Cria objetos dog = Dog("Rex", "Golden Retriever") # Acessa atributos print(dog.name) # Público print(dog._age) # Protegido (ainda acessível) # print(dog.__id) # Isso falhará print(dog._Animal__id) # Isso funciona (acessando attribute privado com name mangling) # Propriedades dog.age = 5 # Usa setter automaticamente print(dog.age) # Usa getter automaticamente # Métodos estáticos e de classe print(Animal.get_kingdom()) print(Animal.get_species_count()) # Verifica herança print(isinstance(dog, Animal)) # True print(issubclass(Dog, Animal)) # True # Métodos especiais em ação print(str(dog)) # Usa __str__ print(repr(dog)) # Usa __repr__ print(len(dog)) # Usa __len__ print(dog['name']) # Usa __getitem__
C98
int main() { // Cria objetos Dog dog("Rex", "Golden Retriever"); // Acessa atributos std::cout << dog.name << std::endl; // Público std::cout << dog.get_age() << std::endl; // Protegido (ainda acessível) // std::cout << dog.__id << std::endl; // Isso falhará (privado) // Propriedades dog.set_age(5); // Usa setter std::cout << dog.get_age() << std::endl; // Usa getter // Métodos estáticos e de classe std::cout << Animal::get_kingdom() << std::endl; std::cout << Animal::get_species_count() << std::endl; // Equivalente aos "métodos especiais": // Verifica herança if (dog.isinstance<Animal>()) { std::cout << "dog é uma instância de Animal" << std::endl; } std::cout << dog.to_string() << std::endl; // Usa to_string std::cout << dog.repr() << std::endl; // Usa repr std::cout << dog["name"] << std::endl; // Usa operador [] }
Python と C 98 の OOP 概念に関するこのガイドに従っていただきありがとうございます。このガイドがあなたの学習の旅にお役に立てば幸いです。コンテンツが気に入ったら、コメントを残して、「いいね!」をして、友達や同僚と共有してください。間違いを見つけた場合は、コメントを残してください。修正します。次回まで!
以上がC プログラマーのための Python の OOP 概念 98の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

PythonのPandasライブラリを使用する場合、異なる構造を持つ2つのデータフレーム間で列全体をコピーする方法は一般的な問題です。 2つのデータがあるとします...

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

UvicornはどのようにしてHTTPリクエストを継続的に聞きますか? Uvicornは、ASGIに基づく軽量のWebサーバーです。そのコア機能の1つは、HTTPリクエストを聞いて続行することです...

正規表現は、プログラミングにおけるパターンマッチングとテキスト操作のための強力なツールであり、さまざまなアプリケーションにわたるテキスト処理の効率を高めます。

Pythonでは、文字列を介してオブジェクトを動的に作成し、そのメソッドを呼び出す方法は?これは一般的なプログラミング要件です。特に構成または実行する必要がある場合は...

この記事では、numpy、pandas、matplotlib、scikit-learn、tensorflow、django、flask、and requestsなどの人気のあるPythonライブラリについて説明し、科学的コンピューティング、データ分析、視覚化、機械学習、Web開発、Hの使用について説明します。
