面向对象最重要的概念就是类(Class)和实例(Instance)
类
类是抽象的模板,类:一个模板,抽象的, 封装数据以及数据对象的操作
定义类通过class关键字,class 后面紧接着是类名
实例:
实例数据:赋值给 self
实例方法:第一个参数是self
类数据:定义在类内部,通过类名获取、设置,如果通过实例添加,会创建一个实例,与类数据同名
类方法:用装饰器注解,@classmethod , 小括号里写 cls,用于获取类相关信息
静态方法:@staticmethod,不需要实例,节省实例内存,封装一些简略方法,一般是工具类
封装:
示例:
# 封装一个矩形类,数据 长、宽 方法 返回 周长 面积
class Rect:
def __init__(self, w, h):
# print(id(self))
self.width = w
self.height = h
def get_length(self):
return (self.width + self.height) * 2
def get_area(self):
return self.width * self.height
def set_data(self, w=None, h=None):
self.width = w if w is not None else self.width
self.height = h if h is not None else self.height
r1 = Rect(100, 200)
print(r1.width, r1.height)
# print(id(r1))
print(r1.get_length())
print(r1.get_area())
r1.set_data(h=1000)
print(r1.get_length())
print(r1.get_area())
继承:
示例:
class Animal:
def __init__(self,age):
self.age = age
self.lang = "chinese"
def __str__(self):
return "动物"
animal = Animal(5)
print(animal,animal.age)
class Dog(Animal):
# pass
def __init__(self, age,height):
# super().__init__(age)
self.age = age
self.height = height
def __str__(self):
return "狗"
dog = Dog(4,30)
print(dog,dog.age)
class Hashiqi(Dog):
def __str__(self):
return "哈士奇!"
def age_(self):
self.age = 10
self.lang = "汪星语"
hashiqi = Hashiqi(2,30)
hashiqi.age_()
print(hashiqi,hashiqi.age,dog.height,hashiqi.lang)
多继承:
示例:
class Father:
def __init__(self,money):
self.money=money
def get_money(self):
print(self.money+200)
class Mother:
def __init__(self,money,power):
self.money = money
self.power = power
def get_money(self):
print(self.money+100)
def get_power(self):
print("owner")
class Son(Father,Mother):
def __init__(self, money,power):
Father.__init__(self,money)
Mother.__init__(self,money,power)
s = Son(100,1)
s.get_money()
s.get_power()
s.get_money()
print(s,Son.__bases__)
多态:
多态两种实现
同一个类中的多态,可以通过python中的*args参数实现
父子类中的多态,子类重写父类方法
方法一:
class Util:
def do_task(self,):
pass
def do_task(self,a):
print(a)
def do_task(self,a,b):
print(a,b)
u = Util()
u.do_task(1,2)
class Util:
# def do_task(self,):
# pass
# def do_task(self,a):
# print(a)
# def do_task(self,a,b):
# print(a,b)
def do_task(self,*args):
print(args)
u = Util()
u.do_task()
u.do_task(1)
u.do_task(1,2)
方法二:
class Father:
def speak(self):
print("2333")
class Son(Father):
def speak(self):
print("3322")
f = Father()
f.speak()
s = Son()
s.speak()
访问限制
简要:
公有:默认 在类内用 self 访问 ,在类外通过实例;私有:__ ,以双下划线开头;保护 :_ ,以但下划线开头。
详解:
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线 __
,在Python中,实例的变量名如果以 __
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,
以一个下划线开头的实例变量名,比如_name
,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问 __name
是因为Python解释器对外把 __name
变量 改成了 _Student__name
,所以,仍然可以通过 _Student__name
来访问 __name
变量。