1.面向对象语法
声明一个类
class MyClass(FatherClass1,FatherClass2,...): #括号内为继承自的父类,可以多继承
def __init__(self,parameter...): #构造方法,属于魔法方法(名字前面有__)
pass #self==this指针,默认要写
def A(self,parameter...)
pass
Attributes... #这里的属性不同于c++,只能是类属性
声明一个对象实例
class = MyClass(parameter...) #默认第一个参数是对象引用
class.A(parameter...) #自动调用__init__魔法方法
这些和c++貌似大同小异罢了,故不表。
不同点在于
属性不绑定在类中,每个实例对象可以自己添加属性
class Person:
name='' #这是类属性
xiaoming = Person()
print(xiaoming.__dict__) #__dict__魔法方法,得到类的所有方法和属性或者实例的所有属性
print(Person.__dict__)
xiaoming.name = '小明'
print(xiaoming.__dict__)
xiaohua = Person()
{}
{‘module‘: ‘main‘, ‘name’: ”, ‘dict‘:
class Person:
name='没有' #这是类属性
def setName(self,str):
name = str
xiaoming = Person() #实例化两个对象小明,小华
xiaohua = Person()
xiaoming.name = '小明' #设置小明的名字
print('xiaoming name='+xiaoming.name)
print('xiaohua name='+xiaohua.name) #查看两个对象的name属性
xiaohua.setName('小华') #通过方法调用改变小华的name
print('xiaoming name='+xiaoming.name)
print('xiaohua name='+xiaohua.name) #查看两个对象的name属性
print('Person name='+Person.name) #查看类的name属性
xiaoming name=小明
xiaohua name=没有
xiaoming name=小明
xiaohua name=没有
Person name=没有
输出如上,发现猜想2有错误 ,类方法内的变量不是任何属性,作用域于仅仅在方法内。
猜想1也有问题:这里xiaohua.name操控的是Person.name类属性
猜想:
3. 对象名可以调用类属性,前提是没有对象属性同名覆盖了类属性。
class Person:
name='没有' #这是类属性
def setName(self,str):
name = str
xiaoming = Person() #实例化两个对象小明,小华
xiaohua = Person()
print(xiaoming.name)
xiaoming.name = '小明'
print(xiaoming.name)
print(xiaohua.name)
没有
小明
没有
发现猜想正确。
猜想:
4. 通过对象引用是改变不了类属性的。只有通过类名才可以。
5. 对象引用操控的属性是会改变的,是对象属性或者类属性。
class Person:
name='没有' #这是类属性
def setName(self,str):
name = str
xiaoming = Person() #实例化两个对象小明,小华
xiaohua = Person()
print(xiaohua.name)
xiaohua.name='小华'
print(xiaohua.name)
print(Person.name)
Person.name='小朋友'
print(xiaohua.name)
print(Person.name)
没有
小华
没有
小华
小朋友
猜想符合实际。
过程中发现下面这种特殊情况
class Person:
name='没有' #这是类属性
def setName(self,str):
name = str
xiaoming = Person() #实例化两个对象小明,小华
xiaohua = Person()
print(xiaohua.name)
print(xiaoming.name)
xiaohua.name+='2号'
print(xiaohua.name)
print(xiaoming.name)
没有
没有
没有小华
没有
查阅资料得到解释,类属性相当于c++的static属性,类对象共有,当用对象引用名字改变类属性时候,会产生新的对象属性覆盖类属性,所以不可以通过引用名改变类属性。但是类名就可以了。这也解释方法内直接操控不了类属性的情况。
猜想:
6. 通过self引用可以操控类属性,原理和在方法之外操控一样,所以不能改变类属性,否则就是声明一个新的同名对象属性。
class Person:
name='没有' #这是类属性
def setName(self,str):
self.name += str
xiaoming = Person() #实例化两个对象小明,小华
xiaohua = Person()
print(xiaohua.name)
print(xiaoming.name)
xiaohua.setName('小华')
Person.name+='小狗'
print(xiaohua.name)
print(xiaoming.name)
没有
没有
没有小华
没有小狗
发现猜想符合实际情况。
通过实验可以发现python的对象机制与c++有很大的不同,更加的杂乱。主要在于:
- 声明任何变量可以不声明,包括属性。
- 同一类对象都拥有自己的独特属性。只需要在使用过程中声明就可以使用。
- 类属性可以被类名和对象引用名操控,但是被同名对象属性覆盖的时候就不能由对象引用操控了。
- 类方法内的直接使用变量统统不属于其他作用域,特指类属性和对象属性。除非使用引用,例如self,这一点和c++有很大的不同。也反映了python的方法和属性的捆绑性不强大。感觉就很鸡肋。只是简单的整合了一下属性和方法。
- 属性名字可以覆盖掉方法名字。
- 对象在类被删除之后依然存在(类可以被删除这一点很奇怪)。