小知识:return可以结束函数的调用,后面的语句将不会执行。所有的函数都有返回值,return语句如果不写同样会隐式调用return None。return语句的结果就是返回值,作为函数的输出可以用变量接走,返回值可以是任意类型。
面向对象三大特性:封装,继承,多态。
属性是对象的描述,方法是对象的动作。
数据,函数,变量都是对象。
类是图纸,对象是依照图纸创造的事物。
定义类语法:
class 类名:
def 函数名(self 参数列表):
pass
创建对象:
对象名= 类名()
引用:对象.函数名
增加临时属性:对象.属性(不推荐使用,只在类的外部,而不在内部》》》顺序的不同会导致报错)
self的作用:哪一个对象引用的方法,self就是哪一个对象的引用。
_init_(初始化方法)定义一个类有什么属性的方法
创建对象时:分配空间,初始化方法
写法:def _init_(self):
self.name=""
def _init_(self,new_name)
self.name=new_name(把形参赋值给self)
__del__删除对象前调用一次。
__str__必须有返回一个字符串,可以看到自定义的内容,描述。要用print输出。
%s格式控制符。
定义属性时,不知道设置什么初始值,可以设置为None
def __init__(self,name):
self.name=name
self.gun=None
一个对象的属性可以是另外一个类创建的对象
is 是身份运算符 判断两个标识符是不是引用同一个对象
is 判断对象 ,==判断变量
私有属性 对象不对外公开的属性,私有方法亦然。
私有方法,在外界不能被直接访问,以两个下划线定义私有方法.属性。
子类对象访问不了父类的私有属性和方法。
子类内也无法调用父类的私有属性和方法
可以根据父类的公有方法,访问私有方法,和属性
class A:
def __init__(self):
self.num1=100
self.__num2=21
def __test(self):
print("%d__test__%d"%(self.num1,self.__num2))
def demo(self): #可以根据父类的公有方法,访问私有方法,和属性
print(self.__num2)
self.__test()
pass
class B(A):
def emo(self):
print(self.num1)
pass
#在外界无法使用对象的私有属性,方法
b=B()
#b.__test() #无法访问,'B' object has no attribute '__test'
#print(b.__num2)
b.emo()
b.demo()
#print(b)
python没有真正意义的私有,只有伪私有。以对象._类名__方法访问
class Women:
def __init__(self,name):
self.name=name
self.__age=18 #两个下划线变成私有属性
def __secret(self):
print("%s的年龄是%d"%(self.name,self.__age))
xf=Women("小芳")
#对象._类名__方法名
print(xf._Women__age)#这访问的是__init__方法
xf._Women__secret() #访问报错
子类继承父类的属性,方法。
语法 :class 子类(父类):
派生类=子类,基类=父类
爷类=>父类=>子类 传递
子类可以调用父类的属性和方法,也可以调用父类的父类的方法。
子类有了父类的属性和方法,有时可能无法满足子类的需求,就需要重写。
第一种,覆盖父类方法。在子类中,定义同名方法
class Dog(Anmail): #验证继承
def bark(self):
print("bark")
class xtq(Dog): #验证继承的传递性
def fly(self):
print("fly")
def bark(self):
#针对子类的需求,编写代码
print("虎啸龙吟")#重写了父类bark方法
第二种,扩展父类方法。
注意:super()是一个特殊类,可以创建对象。重写时,调用父类中的方法。
def bark(self):
#针对子类的需求,编写代码
print("虎啸龙吟")#重写了父类bark方法
#使用super(),调用原本父类的方法
super().bark()
#增加其他子类的代码
print("呜呼!!起飞")
父类方法的另一种调用方法:父类.方法(self),不推荐使用。
Dog.bark(self)
注意:如果调用子类调用方法,会出现递归调用——死循环
子类有多个父类,并有父类的属性和方法。
语法:
class A:
def test(self):
name="神烦"
print("test")
class B:
def demo(self):
print("demo")
class C(A,B): #多继承两个父类
def le(self):
print("A,B")
sf=C()
sf.demo()
sf.test()
sf.le()
注意:父类的属性和方法有同名的情况应该谨慎使用。如果有同名的情况,方法的继承的结果与继承顺序有关。
class A:
def test(self):
self.name="神烦"
print("a--test")
def demo(self):
print("a--demo")
class B:
def test(self):
print("b--test")
def demo(self):
print("b--demo")
class C(A,B): #多继承两个父类
def le(self):
print("A,B")
def test(self):
print("c--test")
def demo(self):
print("c--demo")
sf=C()
#(, , , )
sf.demo() #c--demo
sf.test() #c--test
sf.le()
python的内置属性,__mro__可以查看搜索顺序。主要用于多继承时判断方法,属性调用路径。
从左往右查找,找到方法就执行,否则继续查找。当到最后的基类,还未找到就报错。
object为所有对象提供基类,提供内置属性和方法,用dir查看。
新式类以object为基类,旧式类不以object为基类,如果不以object作为基类,会影响到方法的搜索顺序,没有指定父类的建议统一继承object。
未完待续!!!