- 面向过程:简单问题 线性思维解决 具体到微观操作
- 面向对象:复杂问题 宏观把握事物之间的联系 方便分析整个系统
一、object类
所有的类默认继承Objecct类
(1)特殊方法
①dir(对象) :返回该对象具有的所有属性,从Object类中继承
②__str__()方法:用于返回一个对象的描述 常用于print方法,帮助查看对象的信息,可以对__str__()进行重写
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return 'my name is {0} , {1} years old'.format(self.name,self.age)
stu =Student("zhangsan",20)
print(dir(stu))
print(stu) #默认调用__str__方法 可以重写这个方法 返回对对象的描述
print(type(stu))
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
my name is zhangsan , 20 years old #重写前 默认的对象描述为<__main__.Student object at 0x000001B654818400>
<class '__main__.Student'>
③__add__():实现了两个对象的加法运算
class Student:
def __init__(self,name):
self.name = name
def __add__(self, other):
return self.name+other.name
stu1=Student("zhangsan")
stu2=Student("lisi")
s=stu1+stu2
print(s) #zhangsanlisi
s=stu1.__add__(stu2)
print(s) #zhangsanlisi
④__len__():相当于len(),对没有len()的对象重写__len__()
class Student:
def __init__(self,name):
self.name = name
def __len__(self):
return len(self.name)
stu1=Student("zhangsan")
print(stu1.__len__()) #8
⑤__new__()和__init__()
new在前创建对象,init对对象的属性进行赋值
class Person(object):
def __new__(cls, *args, **kwargs):
print("__new__被调用执行了,cls的id值{0}".format(id(cls)))
obj = super().__new__(cls)
print("创建的对象的id为:{0}".format(id(obj)))
return obj
def __init__(self,name,age):
print('__init__被调用了,self的id值为:{0}'.format(id(self)))
self.name = name
self.age = age
print("object对象的id为:{0}".format(id(object)))
print("Person对象的id为:{0}".format(id(Person)))
p1 = Person("zhangsan",20)
print("p1这个实例对象的id为:{0}".format(id(p1)))
object对象的id为:140734945672016
Person对象的id为:2046457094576
__new__被调用执行了,cls的id值2046457094576
创建的对象的id为:2046488192048
__init__被调用了,self的id值为:2046488192048
p1这个实例对象的id为:2046488192048
(2)特殊属性
①__dict__
实例对象.dict:实例对象的属性字典
类.dict:类的属性和方法字典
②__class__ :输出了对象所属的类
③__bases__:类的父类类型元素
④ base :基类 类的最前面的父类类型元素
⑤__mro__:类的层次结构
⑥__subclasses()__:类的子类列表
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name,age):
self.name = name
self.age = age
x=C("zhangsan",20)
print(x.__dict__) #{'name': 'zhangsan', 'age': 20}
print(C.__dict__) #{'__module__': '__main__', '__init__': <function C.__init__ at 0x000002C37F32E280>, '__doc__': None}
print(x.__class__) #<class '__main__.C'>
print(C.__bases__) #(<class '__main__.A'>, <class '__main__.B'>)
print(C.__base__) #<class '__main__.A'>
print(C.__mro__) #(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(A.__subclasses__()) #[<class '__main__.C'>, <class '__main__.D'>]
二、 类与对象
1.类的组成:
- 类属性:直接写在类里的变量,类内共享;类和对象均可以直接访问
- 实例属性:init赋值
def __init__(self,age,name):
self.age = age
self.name = name
- 实例方法:类内函数
def eat(self):
print("实例方法")
- 静态方法:@staticmethod修饰 使用类名直接访问的方法
@staticmethod
def method():
print("静态方法")
- 类方法:@classmethod修饰 使用类名直接访问的方法
@classmethod
def cm(cls):
print("类方法")
2.调用
stu1=Student("20","zhangsan")
stu1.eat()
Student.eat(stu1)
3.动态绑定
stu1.gender='女' #为stu1对象单独绑定属性
def drink():
print("heshui")
stu1.drink=drink #为stu1对象单独绑定方法
4.面向对象的三大特征
- 封装:安全性
python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外被访问,前边使用两个“_”
class Student:
def __init__(self,name,age):
self.name = name
self.__age = age #age不希望在类的外部被使用
def show(self):
print(self.name,self.__age) #age在类的内部可以被访问
stu = Student("zhangsan",20)
stu.show() #zhangsan 20
print(stu.name) #zhangsan
print(stu.__age) #没有这个属性可访问
print(dir(stu)) #显示stu所有可访问的属性 没有__age 但是有Student__age
print(stu.Student__age) #20 在类的外部可以通过Student__age进行访问
- 继承:代码复用性
python支持多继承;
若一个类没有继承任何类,默认继承Object;
定义子类时,必须在其构造函数中调用父类的构造函数
super()调用父类方法
override方法重写
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(self.name,self.age)
class Student(Person):
def __init__(self,name,age,stu_no):
super().__init__(name,age)
self.stu_no = stu_no
#override方法重写
def info(self):
super().info() #调用父类的方法
print(self.stu_no) #加入子类的扩展实现
class Teacher(Person):
def __init__(self,name,age,teachofyear)
super().__init__(name,age)
self.teachofyear = teachofyear
#override方法重写
def info(self):
super().info() #调用父类的方法
print(self.teachofyear) #加入子类的扩展实现
stu = Student("zhangsan",20,"1001")
teacher = Teacher("lisi",35,10)
stu.info() #重写前zhangsan 20 重写后 zhangsan 20 1001
teacher.info() #重写前lisi 35 重写后 zhangsan 35 10
#多继承 C同时继承了A和B
class A(object):
pass
class B(object):
pass
class C(A,B):
pass
- 多态:可扩展性和可维护性
不知道一个变量引用的对象是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据引用对象的类型,动态决定调用那个对象中的方法
(1)静态语言(Java)实现多态:必要条件①继承②方法重写③父类引用指向子类对象
(2)动态语言(Python)实现多态:“鸭子类型”,不关注对象是什么类型,只关心对象的行为
class Animal(object):
def eat(self):
print("动物会吃")
class Dog(Animal):
def eat(self):
print("狗吃骨头...")
class Cat(Animal):
def eat(self):
print("猫吃鱼...")
class Person:
def eat(self):
print("人吃五谷杂粮")
def fun(obj):
obj.eat()
fun(Cat()) #猫吃鱼...
fun(Dog()) #狗吃骨头...
fun(Animal()) #动物会吃
fun(Person()) #人吃五谷杂粮