Python3 berorientasikan objek


Python telah menjadi bahasa berorientasikan objek dari awal kerana ini, adalah mudah untuk mencipta kelas dan objek dalam Python. Dalam bab ini kami akan memperkenalkan pengaturcaraan berorientasikan objek dalam Python secara terperinci.

Jika anda belum pernah didedahkan kepada bahasa pengaturcaraan berorientasikan objek sebelum ini, anda mungkin perlu terlebih dahulu memahami beberapa ciri asas bahasa berorientasikan objek dan membentuk konsep asas berorientasikan objek dalam fikiran anda, yang akan membantu anda Mempelajari pengaturcaraan berorientasikan objek dengan mudah dalam Python.

Seterusnya, mari kita fahami secara ringkas beberapa ciri asas berorientasikan objek.


Pengenalan kepada teknologi berorientasikan objek

  • Kelas (Kelas): digunakan untuk menerangkan koleksi objek dengan sifat dan kaedah yang sama. Ia mentakrifkan sifat dan kaedah yang biasa kepada setiap objek dalam koleksi. Objek ialah contoh kelas.

  • Pembolehubah kelas: Pembolehubah kelas adalah perkara biasa di seluruh objek yang di instantiated. Pembolehubah kelas ditakrifkan di dalam kelas dan di luar badan fungsi. Pembolehubah kelas biasanya tidak digunakan sebagai pembolehubah contoh.

  • Ahli data: Pembolehubah kelas atau pembolehubah ins digunakan untuk memproses data yang berkaitan dengan kelas dan objek instancenya.

  • Penulisan semula kaedah: Jika kaedah yang diwarisi daripada kelas induk tidak dapat memenuhi keperluan subkelas, ia boleh ditulis semula. , juga dikenali sebagai kaedah mengatasi.

  • Pembolehubah tika: Pembolehubah yang ditakrifkan dalam kaedah hanya bertindak pada kelas tika semasa.

  • Warisan: Iaitu, kelas terbitan mewarisi medan dan kaedah kelas asas. Warisan juga membenarkan objek kelas terbitan untuk dianggap sebagai objek kelas asas. Sebagai contoh, terdapat reka bentuk sedemikian: objek jenis Anjing berasal daripada kelas Haiwan, yang menyerupai perhubungan "ialah-a" (contohnya, Anjing ialah Haiwan).

  • Instansiasi: Cipta tika kelas, objek khusus kelas.

  • Kaedah: Fungsi yang ditakrifkan dalam kelas.

  • Objek: Contoh struktur data yang ditakrifkan oleh kelas. Objek termasuk dua ahli data (pembolehubah kelas dan pembolehubah contoh) dan kaedah.

Berbanding dengan bahasa pengaturcaraan lain, Python menambah mekanisme kelas tanpa menambah sintaks dan semantik baharu sebanyak mungkin.

Kelas dalam Python menyediakan semua fungsi asas pengaturcaraan berorientasikan objek: mekanisme pewarisan kelas membenarkan berbilang kelas asas, kelas terbitan boleh mengatasi sebarang kaedah dalam kelas asas, dan kaedah boleh memanggil nama yang sama dalam kaedah kelas asas.

Objek boleh mengandungi sebarang jumlah dan jenis data.

Definasi kelas

Format sintaks adalah seperti berikut:

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

Selepas kelas dijadikan instantiated, sifatnya boleh digunakan, sebenarnya, selepas kelas dicipta hartanah boleh diakses melalui nama kelas.

Objek kelas

Objek kelas menyokong dua operasi: rujukan atribut dan instantiasi.

Rujukan harta menggunakan sintaks standard yang sama seperti semua rujukan harta dalam Python: obj.name.

Selepas objek kelas dicipta, semua nama dalam ruang nama kelas adalah nama atribut yang sah. Jadi jika takrif kelas kelihatan seperti ini:

#!/usr/bin/python3

class MyClass:
    """一个简单的类实例"""
    i = 12345
    def f(self):
        return 'hello world'

# 实例化类
x = MyClass()

# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())

Instantiate kelas:

# 实例化类
x = MyClass()
# 访问类的属性和方法

Di atas mencipta contoh kelas baharu dan memberikan objek kepada pembolehubah tempatan x, di mana x ialah objek kosong .

Hasil keluaran melaksanakan program di atas ialah:

MyClass 类的属性 i 为: 12345
MyClass 类的方法 f 输出为: hello world

Banyak kelas cenderung untuk mencipta objek dengan keadaan awal. Oleh itu, kelas boleh mentakrifkan kaedah khas (pembina) bernama __init__(), seperti berikut:

def __init__(self):
    self.data = []

Jika kelas mentakrifkan kaedah __init__(), operasi instantiasi kelas akan dipanggil secara automatik_ _init__( ) kaedah. Jadi dalam contoh berikut, anda boleh mencipta tika baharu seperti ini:

x = MyClass()

Sudah tentu, kaedah __init__() boleh mempunyai parameter, dan parameter dihantar ke operasi instantiasi kelas melalui __init__(). Contohnya:

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

Kaedah kelas

Dalam kelas, anda boleh menggunakan kata kunci def untuk mentakrifkan kaedah untuk kelas Berbeza daripada definisi fungsi umum, kaedah kelas mesti mengandungi parameter diri, dan ia adalah Satu parameter pertama:

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

# 实例化类
p = people('php',10,30)
p.speak()

Hasil output melaksanakan program di atas ialah:

php 说: 我 10 岁。

Warisan

Python juga menyokong warisan kelas . Jika bahasa tidak menyokong warisan, Kelas tidak bermakna. Takrif kelas terbitan adalah seperti berikut:

class DerivedClassName(BaseClassName1):
    <statement-1>
    .
    .
    .
    <statement-N>

Anda perlu memberi perhatian kepada susunan kelas asas dalam kurungan Jika terdapat nama kaedah yang sama dalam kelas asas, tetapi ia tidak dinyatakan apabila menggunakan subkelas, Python mencari dari kiri ke kanan. Iaitu, apabila kaedah tidak ditemui dalam subkelas, ia mencari dari kiri ke kanan untuk melihat sama ada kaedah itu termasuk dalam kelas asas.


BaseClassName (nama kelas asas dalam contoh) mesti ditakrifkan dalam skop yang sama dengan kelas terbitan. Sebagai tambahan kepada kelas, ungkapan juga boleh digunakan, yang sangat berguna apabila kelas asas ditakrifkan dalam modul lain:

class DerivedClassName(modname.BaseClassName):

Instance

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))



s = student('ken',10,60,3)
s.speak()

Hasil output untuk melaksanakan program di atas ialah:

ken 说: 我 10 岁了,我在读 3 年级

Warisan berbilang

Python juga mempunyai sokongan terhad untuk berbilang borang warisan. Takrif kelas bagi warisan berbilang kelihatan seperti contoh berikut:

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

Anda perlu memberi perhatian kepada susunan kelas induk dalam kurungan Jika terdapat nama kaedah yang sama dalam kelas induk dan tidak ditentukan apabila menggunakannya dalam subkelas, Python pergi dari kiri ke kanan Iaitu, apabila kaedah tidak ditemui dalam subkelas, cari dari kiri ke kanan untuk melihat sama ada kelas induk mengandungi kaedah tersebut.

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))

#另一个类,多重继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))

#多重继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)

test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同,默认调用的是在括号中排前地父类的方法

Hasil keluaran untuk melaksanakan program di atas ialah:

我叫 Tim,我是一个演说家,我演讲的主题是 Python

Kaedah penulisan semula

Jika fungsi kaedah kelas induk anda tidak dapat memenuhi keperluan anda, anda boleh Subkelas mengatasi kaedah kelas induk anda Contohnya adalah seperti berikut:

#!/usr/bin/python3

class Parent:        # 定义父类
   def myMethod(self):
      print ('调用父类方法')

class Child(Parent): # 定义子类
   def myMethod(self):
      print ('调用子类方法')

c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法

Hasil keluaran melaksanakan program di atas ialah:

调用子类方法

Atribut dan kaedah kelas

Peribadi kelas Atribut

__private_attrs: Bermula dengan dua garis bawah, ia diisytiharkan bahawa atribut itu peribadi dan tidak boleh digunakan atau diakses terus di luar kelas. Apabila digunakan dalam kaedah di dalam kelas self.__private_attrs.

Kaedah kelas

Dalam kelas, anda boleh menggunakan kata kunci def untuk mentakrifkan kaedah untuk kelas Berbeza daripada definisi fungsi umum, kaedah kelas mesti mengandungi parameter diri, iaitu parameter pertama.

Kaedah peribadi kelas

__kaedah_pribadi: Bermula dengan dua garis bawah, kaedah diisytiharkan sebagai kaedah persendirian dan tidak boleh dipanggil di luar kelas. Panggil slef.__private_methods di dalam kelas. Contoh

adalah seperti berikut:

#!/usr/bin/python3

class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0    # 公开变量

    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print (self.__secretCount)

counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount)  # 报错,实例不能访问私有变量

Hasil keluaran melaksanakan program di atas ialah:

1
2
2
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    print (counter.__secretCount)  # 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount'

Kaedah kelas proprietari:

  • __init__ : Pembina, panggil

  • __del__ : Pemusnah, gunakan

  • <🎜 semasa melepaskan objek >
  • __repr__ : Cetak, tukar

  • __setitem__ : Berikan nilai mengikut indeks

  • __getitem__: Dapatkan nilai mengikut indeks

  • __len__: Dapatkan panjang

  • __cmp__ : Operasi perbandingan

  • __panggilan__: Panggilan fungsi

  • __add__: Operasi tambah

  • __sub__: Operasi tolak

  • __mul__: Operasi pendaraban

  • __div__: Operasi bahagi

  • __mod__: Baki operasi

  • __pow__: Pengiraan segi empat sama

Operator overloading

Python juga menyokong lebihan muatan operator. Kita boleh membebankan kaedah proprietari kelas Contoh adalah seperti berikut:

#!/usr/bin/python3

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

Hasil pelaksanaan kod di atas adalah seperti berikut:

Vector(7,8)