- 编程界的两大阵营
| 面向过程 | 面向对象 | |
|---|---|---|
| 区别 | 事物比较简单,可以用线性的思维去解决 | 事物较复杂,使用简单的思维无法解决 |
| 共同点 | 都是解决实际问题的一种思维方式 | |
| 二者相辅相成,并不是对立的,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系,方便我们分析整个系统,具体到微观操作,仍然使用面向过程方式来处理 |
-
数据类型
- 不同的数据类型属于不同的类
- 使用内置函数type()查看数据类型
-
对象
- 100,99.520都是int类之下包含的相似的不同个例,这个个例专业术语称为实例或者对象
class Student:
native_pace='河南' #直接写在类里的变量,称为类属性
def __init__(self,name,age):
self.name=name
self.age=age #self.name称为实体属性,进行了一个赋值的操作,将局部变量的name的值赋给实体属性
#实例方法
def eat(self):
print('学生在吃饭...')
#静态方法
@staticmethod
def method():
print('我使用了staticmethod进行修饰,所以我是静态方法')
#类方法
@classmethod
def cm(cls):
print('我是类方法,因为我使用了classmethod进行修饰')
#在类之外定义的称为函数,在类之内定义的称为方法
def drink():
print('喝水')
对象的创建
-
对象的创建又称为类的实例化
-
语法:
实例名=类名()
-
意义:有了实例,就可以调用类中的内容
- 类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
- 类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
- 静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法
print(Student.native_place) #访问类属性 Student.cm() #调用类方法 Student.sm() #调用静态方法动态绑定属性和方法
- Python是动态语言,在创建对象以后,可以动态的绑定属性和方法
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def eat(self):
print(self.name+'在吃饭')
stu1=Student('张三',20)
stu2=Student('李四',30)
print(id(stu1))
print(id(stu2))
print('--------------为stu2动态绑定性别属性---------------------')
stu2.gender='女'
print(stu1.name,stu1.age) #张三 20
print(stu2.name,stu2.age,stu2.gender) #李四 30 女
面向对象三大特征
封装
- 面向对象的三大特征
- 封装:提高程序的安全性
- 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关系方法内部的具体实现细节,从而隔离了复杂度。
- 在Python中没有专门的的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问 ,前面使用两个’‘_’'。
- 继承:提高代码的复用性
- 多态:提高程序的可扩展性和可维护性。
- 封装:提高程序的安全性
class Student:
def __init__(self,name,age):
self.name=name
self.__age=age #年龄不希望在类的外部被使用,所以加了两个_
def show(self):
print(self.name,self.__age)
stu=Student('张三',20)
stu.show()
#在类的外部使用name和age
print(stu.name) #张三
#print(stu.__age) 不希望被使用,但是可以使用
print(dir(stu)) #dir()函数是一个库函数,用于获取对象的所有属性和方法的列表
print(stu._Student__age) #在类的外部可以通过 _Student__age 进行访问
继承
-
语法格式:
class 子类类名(父类1,父类2):
pass
-
如果有个类没有继承任何类,则默认继承object
-
Python支持多继承
-
定义子类时,必须在其构造函数中调用父类的构造函数
#super()是直接用类名调用父类的一个方法
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 #调用自己的
class Teacher(Person):
def __init__(self,name,age,teachofyear):
super().__init__(name,age) #调用父类的
self.teachofyear=teachofyear #调用自己的
stu=Student('张三',20,'1001')
teacher=Teacher('李四',34,10)
stu.info() #张三 20
teacher.info() #李四 34
class A(object):
pass
class B(object):
pass
class C(A,B): #多继承
pass
方法重写
- 如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写。
- 子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法
#因为只输出了姓名,年龄,学号和教龄并没有输出,所以进行方法重写
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 #调用自己的
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 #调用自己的
def info(self): #方法重写
super().info()
print(self.teachofyear)
stu=Student('张三',20,'1001')
teacher=Teacher('李四',34,10)
stu.info() #张三 20 1001
teacher.info() #李四 34 10
object类
- object类是所有类的父类,因此所有类都有object类的属性和方法
- 内置函数dir()可以查看指定对象所有属性
- object有一个_str_()方法,用于返回一个对于’对象的描述’,对应于内置函数str()经常用于print()方法,帮助我们查看对象的信息,所以我们经常会对_str_进行重写。
-
简单地说,多态就是’具有多种形态’,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。
-
静态语言与动态语言关于多态的区别:
- 静态语言(Java)实现多态的三个必要条件
- 继承
- 方法重写
- 父类引用指向子类对象
- 静态语言(Java)实现多态的三个必要条件
-
动态语言(Python)的多态崇尚"鸭子类型" 当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象时什么类型,到底是不是鸭子,只关心对象的行为。
class Animal(object):
def eat(self):
print('动物会吃')
class Dog(Animal):
def eat(self):
print('狗吃骨头')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person(object):
def eat(self):
print('人吃五谷杂粮')
#定义一个函数
def fun(obj):
obj.eat()
#开始调用函数
fun(Cat()) #Cat()是类,这里其实是一个实例化的过程,只是没有将其赋值。如果将c=Cat(),然后再传fun(c),与前面是等效的
fun(Dog())
fun(Animal())
print('--------------------------')
fun(Person()) #人吃五谷杂粮
特殊属性
class A(object):
pass
class B(object):
pass
class C(A,B):
def __init__(self,name,age):
self.name=name
self.age=age
class D(A):
pass
x=C('Jack',20) #是C类型的一个实例对象
print(x.__dict__) #{'name': 'Jack', 'age': 20} 实例对象的属性字典
print(C.__dict__)
print(x.__class__) # 输出了对象所属的类
print(C.__bases__) #C类的父类类型的元素
print(C.__base__) # class C(A,B)谁在前面输出谁
print(C.__mro__) #类的层次结构
print(A.__subclasses__()) #子类的列表
特殊方法
a=20
b=100
c=a+b #两个整数类型的对象的相加操作
d=a.__add__(b)
print(c)
print(d)
class Student():
def __init__(self,name):
self.name=name
def __add__(self, other):
return self.name+other.name
def __len__(self):
return len(self.name)
stu1=Student('张三')
stu2=Student('李四')
s=stu1+stu2 #实现了两个对象的加法运算,因为在Student类中编写了__add__() 特殊方法
print(s) #张三李四
s=stu1.__add__(stu2)
print(s)
print('---------------------------------------')
lst=[11,22,33,44]
print(len(lst)) #4 内置函数len()
print(lst.__len__()) #4
print(len(stu1)) #2 因为在Student类中编写了__len__() 特殊方法



