文章目录
-
- [一 类](#一 类)
- [二 封装](#二 封装)
-
- [1 公开/私有/隐藏属性](#1 公开/私有/隐藏属性)
-
- 1.1公开属性
- [1.2 私有属性](#1.2 私有属性)
- [1.3 隐藏属性](#1.3 隐藏属性)
- [2 公开/私有/隐藏方法](#2 公开/私有/隐藏方法)
- [三 继承](#三 继承)
- [四 多态](#四 多态)
- [五 静态方法和类方法](#五 静态方法和类方法)
一 类
1定义
python
class Human:#定义类
name="名字"
def eat(self):#self是自动生成的对象引用,名字可以改
print("我喜欢吃饭")
print(Human.hight)#读取属性
2实例化
python
man=Human()#实例化对象
print(man.name)
3类属性与实例属性
3.1 类属性
1 类属性是声明在类名下的属性,所有对象共享一个类属性
3.2 实例属性
增肌实例属性的方法有两种
1 写在构造方法里
python
class A:
def __init__(self,name,age):
self.name=name
self.age=age
2 通过对象直接添加
python
a.height = 170
3.3 误区
类属性只能用类名修改值,不能用类的对象赋值
python
class A:
claaAttribute = 1
@classmethod
def bark(cls, name):#和c#不同 没有静态参数这一说
print(f"{name}bark")
A.claaAttribute =2#正确,修改类属性
aobj = A()
aobj.claaAttribute =3#错误,对象只能读类属性不能改,这里实际上是添加了一个名为claaAttribute的实例属性
4 new函数
new函数是基类object提供的方法,他在构造函数前执行,返回值是对象的引用
python
class A:
def __init__(self):
print("构造方法执行")
def __new__(cls, *args, **kwargs):#这是重写一个new方法
print("new方法执行")
return super().__new__(cls)#因为返回值是对象引用,所以必须加return,否则拿不到引用init不会执行
a =A()
5构造函数
python
class Human:
def __init__(self,name,age,height):#注意每侧都有两个下划线
self.name = name
self.age= age
self.height= height
man1=Human("wuzi",18,180)
6析构函数
python
class Human:
def __def__(self):
print("析构执行")
man= Human()
del man #删除一个对象
二 封装
1 公开/私有/隐藏属性
1.1公开属性
属性默认是公开的,可以在任何地方被访问
python
class Human:
name ="wuzi"
1.2 私有属性
和c#的私有属性不同,py的私有属性可以被外部使用,子类可以继承,但是被另一个py文件通过 from xx import *导入时无法导入
更接近c#的protect
写法
加一个下划线
python
class Human:
_name ="wuzi"
man = Human()
print(man._age)#调用时要带着下划线
1.3 隐藏属性
更接近c#的私有属性,外部不可访问,子类不可继承,另一个Py文件使用 from xx import * 导入时无法导入
写法
直接在属性名前加两个下划线
隐藏的属性不会被继承
python
class Human:
name ="wuzi"
__age = 20#无法通过对象或类名访问到
如果非要访问隐藏的属性
方法1 python是通过修改变量名实现的隐藏,会被替换为_类名__变量名,直接找这个变量名即可
python
class Human:
name ="wuzi"
__age = 20
man = Human()
print(man._Human__age)
方法2 封装一个函数
python
class Human:
name ="wuzi"
__age = 20
def GetAge(self):
return self.__age
man = Human()
print(man.GetAge())
2 公开/私有/隐藏方法
同属性
三 继承
1单继承
python
class Human:
def eat(self):
print("eat")
def drink(self):
print("drink")
#单继承
class Girl(Human):#用()指出父类
pass
girl = Girl()
girl.eat()
2多继承
python
class A:
pass
class B():
pass
class C(A,B):
pass
如果多个父类里有重复的方法,会优先使用靠前的方法,此处用A类的方法(就近原则)
3 重写父类方法
py不需要标记虚方法,直接重写即可
python
class Father:
def money(self):
print("我有1块钱")
class Son(Father):
def money(self):
print("我有2块钱")
son = Son()
son.money()#我有2块钱
4 扩展父类方法
python
class Father:
def money(self):
print("父类有1块钱")
class Son(Father):
def money(self):
#这是三种不同的调用父类方法的写法
Father.money(self)#方法1
super().money()#方法2 super()实际上创建了父类的对象 推荐用这种
super(Son, self).money()#方法3 是方法2的完整写法
print("子类有2块钱")
son = Son()
son.money()#父类有1块钱 父类有1块钱 父类有1块钱 子类有2块钱
5 新式类
py3的所有类都是新式类,用户自己写的类一定会继承object
之所以叫新式类是因为py2里不显式继承object的话会什么都不继承
以下三种写法是一模一样的
python
class A:
pass
class B():
pass
class C(object):
pass
四 多态
和C#一样,只不过由于没有类型,不需要考虑声明父类实例化子类的问题,因为只能实例化子类
python
class A:
def bark(self):
print('bark')
class B(A):
def bark(self):
print('A_bark')
class C(A):
def bark(self):
print('B_bark')
def Test(object):
object.bark()#这里是硬写的,没有任何提示
b= B()
c= C()
Test(b)#A_bark
Test(c)#B_bark
五 静态方法和类方法
静态方法
1定义
使用@staticmethod装饰器装饰的方法就是静态方法
python
class A:
@staticmethod
def bark():
print('bark')
2特点
·没有self,cls参数限制
·静态方法调用不需要声明对象,直接用类名就可以
3调用
可以用类名直接调用,也可以用对象调用
python
class A:
@staticmethod
def bark(name):#和c#不同 没有静态参数这一说
print(f"{name}bark")
#类名调用
A.bark("Bob")#Bobbark
#对象调用
aobj = A()
aobj.bark("Charlie")#Charliebark
类方法
1定义
类方法是使用@classmethod修饰的方法
python
class A:
@classmethod
def bark(cls):#cls 是类,可以用它调类属性
pass
def Funa(self):#实例方法,无法直接通过类名调用
pass
2 特点
·可以直接用类名调用
· 可以使用类属性,也可以使用对象调用
python
class A:
claaAttribute = 1
@classmethod
def bark(cls, name):#cls 是类,可以用它调类属性
print(f"{name}bark{cls.claaAttribute}")
A.claaAttribute = 2
A.bark("Bob")#Bobbark2
实例方法 静态方法 类方法 的对比
实例方法:对象调用,可以访问实例属性,可以通过类名访问类属性
静态方法:类名或对象调用,可以通过类名访问,无法访问实例属性
类方法:类名或对象调用,可以通过类名访问,无法访问实例属性
python
class A:
claaAttribute = 1
def __init__(self, b):
self.b = b
@classmethod
def bark(cls, name):#cls 可以访问类属性 由于没有对象,不能访问实例属性
print(cls.claaAttribute)
print(A.claaAttribute)
@staticmethod
def FunStatic():#静态方法,可以访问类属性 由于没有对象,不能访问实例属性
print(A.claaAttribute)
def Funa(self):#实例方法,无法直接通过类名调用
print(A.claaAttribute)
print(self.b)
类方法和静态方法主要优势在于继承,类方法里的cls会自动变成子类的(子类赋值同名类属性不会影响父类),而静态方法只能静态写死