Table of Contents
属性
Sample:
class Book:
name = "C Programming"
__publisher = "T University"
def show(self):
print(self.name, self.__publisher)
b = Book()
b.show() # b.__publisher and Book.__publisher are restricted
b.name = "Python" # Assign "Python" to name property
b.author = "God" # Add new property "author" to instance b
print(b.name, b.author) # b has author
print(Book.name) # Book does not have author.
Result:
C Programming T University
Python God
C Programming
Key points:
- 一般的属性都是公有的,如果想要定义成私有的,则要在属性前面加2个下划线“__”
- 有两种访问属性的方式 ,Book.name 或者b.name
- 实例有结合任何属性的功能:
对象实例.属性=...
如果该对象实例存在这个属性,这个属性的值就被改变;
如果不存在该属性就会自动为该对象实例创建这个属性。
对象初始化
-
构造方法(函数)
Sample:
class Book:
name = "C Programming"
def __init__(self, n):
self.name = n
b = Book("Python")
print(b.name)
Result:
Python
Key points:
- 构造方法__init__(self, ...)在生成对象时调用,可以用来进行一些初始化操作,不需要显示的去调用,系统默认去执行。如果用户自己没有重新定义构造方法,系统就自动执行默认的构造方法。
- 一个类中构造函数只能有一个(构造函数没有重载)。要想实现重载的功能,可以给构造函数的参数写默认值, e.g. def __init__(self, name="", publisher="TTT")
-
析构方法(函数)
Sample:
class Book:
name = "C Programming"
def __init__(self, n):
self.name = n
print("__init__",self)
def __del__(self):
print("__del__", self)
b = Book("Python")
print(b.name)
Result:
__init__ <__main__.Book object at 0x000001E9E034A0B8>
Python
__del__ <__main__.Book object at 0x000001E9E034A0B8>
Key points:
- 析构方法__del__(self)在释放对象时调用,可以在里面进行一些释放资源的操作,不需要显示调用。
类的方法
-
实例方法
Sample:
class Book:
name = "C Programming"
def show(self):
print(self.name)
b = Book()
b.show()
b.name = "C++"
Book.show(b)
Result:
C Programming
C++
Key points:
- 实例方法至少有一个参数,一般命名为“self”(也可以是其他名称)。
- 实例方法通过实例对象调用。例如, b.show()。
- 如果使用类名称调用需要认为传递实例参数,例如:Book.show(b)。
- 实例方法被调用时要向它的第一个参数传递实例对象。
-
类方法
Sample:
class Book:
name = "C Programming"
@classmethod
def show_name(cls):
print(cls.name)
b = Book()
b.name = "Python"
Book.show_name()
b.show_name()
Result:
C Programming
C Programming
Key points:
- 类方法使用@classmethod来修饰,而且第一个参数一般命名为cls(也可以命名为别的名称)。
- 类方法通常使用类的名称调用,例如:Book.show_name().
- 类方法也可以使用实例调用,例如:b.show_name()
- 类方法调用时会向它的第一个参数传递类的名称。
-
静态方法
Sample:
class Book:
name = "C Programming"
@staticmethod
def show():
print(Book.name)
b = Book()
b.name = "Python"
b.show()
Book.show()
Result:
C Programming
C Programming
Key points:
- 静态方法通过@staticmethod修饰。
- 通常采用类的名称或者实例来调用静态方法,例如:Book.show(), b.show()
- 在调用静态方法时不会向函数传递任何参数。
类的继承
-
继承类构造方法
Sample:
class Person:
name = "Sample name"
gender = "male"
age = 18
def __init__(self, n, g, a):
self.name = n
self.gender = g
self.age = a
def show(self):
print(self.name,self.gender,self.age, end=" ")
class Student(Person):
def __init__(self, n, g, a, m, d):
Person.__init__(self, n, g, a)
self.major = m
self.dept = d
def show(self):
Person.show(self)
print(self.major, self.dept)
s = Student("Holly", "female", 20, "Software", "CS")
s.show()
Result:
Holly female 20 Software CS
Key points:
- 在继承中基类的构造方法(__init__()方法)不会被自动调用,它需要在其派生类的构造方法中显示的调用下。不同于C#。
- 在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。不同于在类中调用普通方法时不需要带上self参数的情况。
- Python总是首先查找对应类型的方法,如果在派生类中找不到对应的方法,才去到基类中逐个查找。(先在当前类中查找调用的方法,找不到才去基类中找)
-
方法与属性的继承
Sample:
class Person:
className = "Person"
name = "Sample name"
gender = "male"
age = 18
def __init__(self, n, g, a):
self.name = n
self.gender = g
self.age = a
def show(self):
print(self.name,self.gender,self.age, end=" ")
def display(self):
print("Person display", self)
@classmethod
def class_class_name(cls):
print("class method: ", cls, cls.className)
@staticmethod
def static_class_name():
print("Static method: ", Person.className)
class Student(Person):
className = "Student"
def __init__(self, n, g, a, m, d):
Person.__init__(self, n, g, a)
self.major = m
self.dept = d
def show(self):
Person.show(self)
print(self.major, self.dept)
s = Student("Holly", "female", 20, "Software", "CS")
s.show()
s.display()
Student.class_class_name()
Student.static_class_name()
Result:
Holly female 20 Software CS
Person display <__main__.Student object at 0x0000017DD889A278>
class method: <class '__main__.Student'> Student
Static method: Person
Key points:
- 如果一个基类中有一个实例方法,在继承类中可以重新定义完全一样的实例方法,例如Person有show方法,在Student中也有一样的show方法,他们是不会混淆的,我们称Student类的show重写了Person的show。
- 当然一个基类的实例方法也可以不被重写,派生类会继承这个基类的实例方法。
- 派生类也可以增加自己的新实例方法。